FPGA HLS Matrix_MUL 矩阵乘法的计算与优化

这篇具有很好参考价值的文章主要介绍了FPGA HLS Matrix_MUL 矩阵乘法的计算与优化。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

新建Vivado工程

设置clock,10表示一个周期10ns,带宽100M

vivado工具比较保守,计算需要的延迟是14,实际优化可以在10,设置大一点,优化的计算更多,一般约束设置大一点在30-50

FPGA HLS Matrix_MUL 矩阵乘法的计算与优化

选择开发板 xc7z020clg400-1

FPGA HLS Matrix_MUL 矩阵乘法的计算与优化

Source:描述功能模块的cpp和h代码

Test Bench:测试代码的main.cpp

FPGA HLS Matrix_MUL 矩阵乘法的计算与优化

C Code

matrix_mul.h

#ifndef __MATRIX_MUL__
#define __MATRIX_MUL__

#include "ap_fixed.h"

void matrix_mul(ap_int<8> A[4][4], ap_int<8> B[4][4], ap_int<16> C[4][4]);

#endif
  • #ifndef __xxxx__ #define __xxxx__ #endif 用于放置重复引入头文件
  • ap_fixed.h :arbitrary precision data types 用于自定义精度整形(FPGA的浮点数运算很慢,在后面的模型推理的时候 整形数运算比较快)
  • 两个8位数相乘,结果最大可以是16位

.h文件包含了一个矩阵乘法的函数声明

matrix_mul.cpp

#include "matrix_mul.h"

void matrix_mul(ap_int<8> A[4][4], ap_int<8> B[4][4], ap_int<16> C[4][4])
{
	for(int i = 0; i < 4; ++ i){
		for(int j = 0; j < 4; ++ j){
			C[i][j] = 0;
			for(int k = 0; k < 4; ++ k){
				C[i][j] += A[i][k]*B[k][j];
			}
		}
	}
}

i行k列乘k行j列

FPGA HLS Matrix_MUL 矩阵乘法的计算与优化

main.cpp

#include "matrix_mul.h"
#include <iostream>

int main()
{
	ap_int<8> A[4][4], B[4][4];
	ap_int<16> C[4][4];

	// initial A&B
	for(int i = 0; i < 4; ++ i)
		for(int j = 0; j < 4; ++ j)
			A[i][j] = B[i][j] = i*4 + j;

	// inference
	matrix_mul(A, B, C);

	// print C matrix
	for(int i = 0; i < 4; ++ i){
		for(int j = 0; j < 4; ++ j){
			std::cout << "C["<<i<<"] = " << C[i][j] << "\t";
		}
		std::cout << std::endl;
	}
	return 0;
}

C Simulation

当有许多模块的时候需要指定顶层函数,设置顶层模块(top function):

FPGA HLS Matrix_MUL 矩阵乘法的计算与优化

C仿真主要用于编译C代码与HLS无关,测试功能是否与预期一致。使用C++完成testbench,同样地,C语言可以编译为对应的激励,驱动上一步骤完成的电路模块

_csim.log 文件显示仿真结果

INFO: [SIM 2] *************** CSIM start ***************
INFO: [SIM 4] CSIM will launch GCC as the compiler.
   Compiling ../../../main.cpp in debug mode
   Compiling ../../../matrix_mul.cpp in debug mode
   Generating csim.exe
C[0] = 56	C[0] = 62	C[0] = 68	C[0] = 74	
C[1] = 152	C[1] = 174	C[1] = 196	C[1] = 218	
C[2] = 248	C[2] = 286	C[2] = 324	C[2] = 362	
C[3] = 344	C[3] = 398	C[3] = 452	C[3] = 506	
INFO: [SIM 1] CSim done with 0 errors.
INFO: [SIM 3] *************** CSIM finish ***************

C Synthesis

C++代码综合成RTL逻辑,生成综合报告,包括时序,延时,资源占用,端口信息等。

FPGA HLS Matrix_MUL 矩阵乘法的计算与优化

  • Loop Latency:完成所有循环需要的时钟周期

  • Iteration Latency:循环里面,迭代一次需要的周期

  • Initiation Interval(II):两次迭代之间的时钟间隔

  • Trip Count:循环次数

FPGA HLS Matrix_MUL 矩阵乘法的计算与优化


工程的资源占用情况(工程使用的资源数目&FPGA的总可用资源):

FPGA HLS Matrix_MUL 矩阵乘法的计算与优化


端口信息,ABC数组默认存在存储器ap_memory中,以下ap_clk、ap_rst、ap_start、ap_done、ap_idle、ap_ready都是控制信号

FPGA HLS Matrix_MUL 矩阵乘法的计算与优化

端口分析

  1. 控制端口用于控制和显示该模块的工作状态。各个端口的功功能如下,默认情况下会生成下面四个控制端口。
    • ap_start(in):为高时,该模块开始处理数据。
    • ap_done(out):为高时,表示模块处理数据完成。
    • ap_idle(out):表明模块是否处于空闲态。高电平有效。为高时,该处于空闲态。
    • ap_ready(out):为高时,表示模块可以接受新的数据。
  2. 数据端口用于传递模块的输入输出参数。
    参数d_o,d_i 为数组类型,故默认状态下回生成内存接口。内存接口 (数组类型参数)数据来自外部的memory,通过地址信号读取相应的数据,输入到该模块中。输入数组从外部内存中读源数据,输出数组从向外部内存写入结果数据。各个端口的定义如下。
    • address:地址信号
    • ce0:片选信号
    • we0:写使能信号
    • d0 :数据信号

并行优化

A和B的四个数同时相乘,让原先一行乘一列需要8个周期完成,变成一个周期完成

两种实现方法:

  • unroll,手动展开循环
  • pipline,系统自动推断展开
    • partiotion,切分数组
    • reshape,改变存储长度

unroll

FPGA HLS Matrix_MUL 矩阵乘法的计算与优化

source文件自动添加优化代码:#pragma HLS UNROLL

#include "matrix_mul.h"

void matrix_mul(ap_int<8> A[4][4], ap_int<8> B[4][4], ap_int<16> C[4][4])
{
	for(int i = 0; i < 4; ++ i){
		for(int j = 0; j < 4; ++ j){
			C[i][j] = 0;
			for(int k = 0; k < 4; ++ k){
				#pragma HLS UNROLL
				C[i][j] += A[i][k]*B[k][j];
			}
		}
	}
}

运行C综合的结果:((1+2)*4+2)*4+1 =57

FPGA HLS Matrix_MUL 矩阵乘法的计算与优化

pipeline

选择第二个for循环,设置pipeline的迭代间隔等于1

FPGA HLS Matrix_MUL 矩阵乘法的计算与优化

自动添加优化语句:#pragma HLS PIPELINE II=1

#include "matrix_mul.h"

void matrix_mul(ap_int<8> A[4][4], ap_int<8> B[4][4], ap_int<16> C[4][4])
{
	for(int i = 0; i < 4; ++ i){
		for(int j = 0; j < 4; ++ j){
			#pragma HLS PIPELINE II=1
			C[i][j] = 0;
			for(int k = 0; k < 4; ++ k){
				C[i][j] += A[i][k]*B[k][j];
			}
		}
	}
}

C综合结果:

FPGA HLS Matrix_MUL 矩阵乘法的计算与优化

计算一共需要34个周期,这已经比以前的169个周期快了不少了,但是我们希望16个周期就能计算完。

没有达到预期的目标是因为没有指定数组A和B的端口类型,默认为双端口。读取数据时一次只能读取2个,所以16次计算,每次读取4个数据,一共16*4个数据需要花费16*4/2=32个周期

端口只有ce0和ce1:

FPGA HLS Matrix_MUL 矩阵乘法的计算与优化

所以需要同时取出四个数据,可以通过ArrayPartition和ArrayReshape实现

Array_Partition

数组分割:A竖着切割(按照维度2),分成4份分别存储在4个存储器里面;B横着切割(按照维度1)分别存储在4个存储器里面;

计算时同时各取出4个进行运算:

注意维度:高是维度1,宽是维度2

FPGA HLS Matrix_MUL 矩阵乘法的计算与优化

FPGA HLS Matrix_MUL 矩阵乘法的计算与优化

#include "matrix_mul.h"

void matrix_mul(ap_int<8> A[4][4], ap_int<8> B[4][4], ap_int<16> C[4][4])
{
    // partiton 优化语句
	#pragma HLS ARRAY_PARTITION variable=B complete dim=1
	#pragma HLS ARRAY_PARTITION variable=A complete dim=2
	for(int i = 0; i < 4; ++ i){
		for(int j = 0; j < 4; ++ j){
			#pragma HLS PIPELINE II=1
			C[i][j] = 0;
			for(int k = 0; k < 4; ++ k){
				C[i][j] += A[i][k]*B[k][j];
			}
		}
	}
}

C综合结果:

1*16+2 = 18

FPGA HLS Matrix_MUL 矩阵乘法的计算与优化

数组A和B都有四个端口同时读数据了:

FPGA HLS Matrix_MUL 矩阵乘法的计算与优化

Array_Reshape

重定义数组在存储器中的排列方式。原来默认一个地址行放一个数据,宽度只占8位。

A每次计算取一行,所以按照维度 2的方向放置数据:

FPGA HLS Matrix_MUL 矩阵乘法的计算与优化

#include "matrix_mul.h"

void matrix_mul(ap_int<8> A[4][4], ap_int<8> B[4][4], ap_int<16> C[4][4])
{
	#pragma HLS ARRAY_RESHAPE variable=B complete dim=1
	#pragma HLS ARRAY_RESHAPE variable=A complete dim=2
	for(int i = 0; i < 4; ++ i){
		for(int j = 0; j < 4; ++ j){
			#pragma HLS PIPELINE II=1
			C[i][j] = 0;
			for(int k = 0; k < 4; ++ k){
				C[i][j] += A[i][k]*B[k][j];
			}
		}
	}
}

C综合结果:

FPGA HLS Matrix_MUL 矩阵乘法的计算与优化

FPGA HLS Matrix_MUL 矩阵乘法的计算与优化

latency约束

这里Latency指的是每次迭代的花费的周期数

设置计算消耗的周期数设置为5

FPGA HLS Matrix_MUL 矩阵乘法的计算与优化

FPGA HLS Matrix_MUL 矩阵乘法的计算与优化

#include "matrix_mul.h"

void matrix_mul(ap_int<8> A[4][4], ap_int<8> B[4][4], ap_int<16> C[4][4])
{
	#pragma HLS ARRAY_RESHAPE variable=B complete dim=1
	#pragma HLS ARRAY_RESHAPE variable=A complete dim=2
	for(int i = 0; i < 4; ++ i){
		for(int j = 0; j < 4; ++ j){
			#pragma HLS LATENCY min=5 max=5
			#pragma HLS PIPELINE II=1
			C[i][j] = 0;
			for(int k = 0; k < 4; ++ k){
				C[i][j] += A[i][k]*B[k][j];
			}
		}
	}
}

所以最后使用的周期数一共是:16×( Initiation Interval -1 ) + Latency = (16-1)×1+5 = 20

FPGA HLS Matrix_MUL 矩阵乘法的计算与优化

原来不加latency时,延时是1,所以是(16-1)*1+1=16文章来源地址https://www.toymoban.com/news/detail-487064.html

到了这里,关于FPGA HLS Matrix_MUL 矩阵乘法的计算与优化的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • FPGA HLS 卷积单元 数据类型&hls优化&约束设置

    自定义精度整形: 自定义定点数 为了替换float,double类型的数,加快运算,节约资源 根据输入的数据,找到卷积层的数据范围 特征的内存排布方式 权重的内存排布方式 卷积的大小不固定,需要根据在内存中的排布方式算出地址 新建conv_core项目 conv_core.h conv_core.cpp main.cpp

    2024年02月03日
    浏览(49)
  • x86汇编_MUL/IMUL乘法指令_笔记52

    32位模式下整数乘法可以实现32、16或8位的操作,64位下还可以使用64位操作数。MUL执行无符号乘法,IMUL执行有符号乘法。 MUL指令:无符号数乘法 32 位模式下,MUL(无符号数乘法)指令有三种类型: 执行 8 位操作数与 AL 寄存器的乘法; 执行 16 位操作数与 AX 寄存器的乘法;

    2024年02月07日
    浏览(38)
  • 矩阵乘法优化:4x4矩阵块优化方法

    MMult_4x4_3.h 一次计算C中的4x4小块 0.24gflops 2.1% 1 MMult_4x4_4.h 一次计算C中的4x4小块 0.24gflops 2.1% 1 MMult_4x4_5.h 一次计算C中的4x4小块,将16个循环合并一个 0.25gflops 2.2% 1 MMult_4x4_6.h 一次计算C中的4x4小块(我们在寄存器中累加C的元素,并对a的元素使用寄存器) 1.75gflops 16.0% 1 MMult_4x4_7.h 在

    2024年02月15日
    浏览(49)
  • 基于脉动阵列的矩阵乘法加速(FPGA)

    ​ 原本准备做FADDEV求逆矩阵算法的FPGA实现,其中有一个概念挺吸引人,就是:脉动阵列。 ​ 先来讲讲脉动阵列的概念,脉动阵列其实是一种处理单元的结构。数据同步流过,能够减小降低重复访问,调高处理效率和资源消耗。 ​ 其实这是个比较旧的概念了,1982就有学者提

    2024年02月01日
    浏览(82)
  • FPGA | Verilog 实现矩阵乘法(附源码)

    使用 for语句实现,后续继续做并行优化… 最近需要用 verilog写一个矩阵乘法的简单模块,本来想着网上随便搜一个复制粘贴一下,却发现居然找不到有源码的(好多还上传到了CSDN资源),罢了罢了,照着Github的自己写一个吧。 我写的是 3 * 3 的、数值位宽为 [3:0] (0-15)的矩

    2024年02月11日
    浏览(35)
  • 矩阵乘法优化:1x4矩阵块的各种优化方法

    文件名 优化方法 gFLOPs 峰值占比 线程数 MMult1.h 无任何优化 0.24gflops 2.1% 1 MMult2.h 一次计算4个元素 0.24gflops 2.1% 1 MMult_1x4_3.h 一次计算4个元素 0.24gflops 2.1% 1 MMult_1x4_4.h 一次计算4个元素 0.24gflops 2.1% 1 MMult_1x4_5.h 一次计算4个元素(将4个循环合并为1个) 0.25gflops 2.2% 1 MMult_1x4_7.h 一次计

    2024年02月15日
    浏览(47)
  • 矩阵乘法与优化

    0 1 1 1 这是一个矩阵,那么我要让它乘以一个这样的矩阵 1 0 0 1 那么它的结果就是 0 1 1 1 如果乘以它自身,那么它的结果就是 1 1 1 2 那么矩阵乘法的公式就应该是 (此图为网图,侵权可以私信我) 可以发现,矩阵乘法的 右 单位元应该是 1 0 0 0 1 0 0 0 1 后面的以此类推 因为对于当

    2024年02月08日
    浏览(38)
  • 混合输入矩阵乘法的性能优化

    作者 |  Manish Gupta OneFlow编译 翻译|宛子琳、杨婷 AI驱动的技术正逐渐融入人们日常生活的各个角落,有望提高人们获取知识的能力,并提升整体生产效率。语言大模型(LLM)正是这些应用的核心。LLM对内存的需求很高,通常需要专用的硬件加速器,以高效地提供数百亿亿次

    2024年03月11日
    浏览(59)
  • 矩阵乘法优化:GEMM中如何将大矩阵切割成小矩阵

     论文自然还是 Anatomy of High-Performance Matrix Multiplication。 如何拆分 一个矩阵乘法有 6 种拆分方式,其中对 row-major 效率最高的是: 第一次拆分 先做第一次拆分,取 A 的 kc 列(PanelA)和 B 的 kc 行(PanelB),得到待累加的一部分结果; 第二次拆分 第二次拆分,把 PanelB 按 nc 大

    2024年04月27日
    浏览(36)
  • 矩阵计算复杂度(简洁版)(Computational complexity of matrix)

    This blog mainly focuses on the complexity of matrix calculation. I will introduce this topic in three parts: main results, analysis, and proof, code. Let ,  and invertible matrix . Then we have following computational complexity : (1)  ; (2)  ; (3) ; The usual computation for integer multiplication has a complexity of . This means that there is

    2023年04月13日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包