xilinx 暑期学校学习笔记(三)HLS优化语法与资源

文章目录

  • 优化语法
    • **硬件资源指定语法**
    • **数组划分语法**
    • 流水化
    • STREAM
    • 函数内联
    • 循环
      • **循环边界**
      • 循环展开
  • 资源内容
    • **硬件资源**
    • **数值精度**
    • 模块接口
  • 优化案例
    • 未优化
    • 数组展开及循环展开
    • 数组展开及PIPELINE优化
    • 不同循环顺序的PIPELINE优化
    • 效果对比

优化语法


硬件资源指定语法

指定向FPGA硬件资源映射时的资源类型#

#pragma HLS RESOURCE variable =core =
Examples :
a = b + c;
# pragma HLS RESOURCE variable =a core =AddSub_DSP
intA[1024];
# pragma HLS RESOURCE variable =A core =RAM_T2P_BRAM

数组划分语法

#pragma HLS array _partition variable =factor =dim =
Type :complete ,cyclic ,block 
dim=1,23(dim=0)

xilinx 暑期学校学习笔记(三)HLS优化语法与资源_第1张图片
不同TYPE:
complete: 完全打散为N个数
Block: 打散为几个块
cycle: factor 取模的方式进行划分,如奇偶性


流水化

任务级流水化

#pragma HLS dataflow

管线优化

#pragma HLS PIPELINE

任务级流水化粒度更大,作用于不同的子函数,后面的代码只能包含函数调用和中间变量声明。

pipeline作用于循环的不同iteration


STREAM

数据类型: hls::stream
以高性能FIFO替代高资源占用的double-buffered RAM
指令:#pragma HLS stream variable =depth =dim=

  • 数据类型为Istream ,使用流操作符操作
  • 在函数参数配置时传引用“&”
  • 必须有一个producer 和一个consumer

函数内联

#pragma HLS INLINE(off)

循环

循环边界

一般循环次数为定值,否则综合后无法获得性能估计(Latency=?)

#pragma HLS loop_tripcount min =  max =  avg =

循环展开

手动展开或使用指令

#pragma HLS UNROLL(factor = )
E.g., #pragma HLS UNROLL factor=2

过分了可能综合时间过长和失败


资源内容

硬件资源

可以存储于为片上的存储单元/Buffer/Scratchpad Memory
设计利用数据局部性提高重复访问数据的访问效率

  • flip-flop(FF)
    • 单个时钟周期内可并行访问多个地址
    • 单个时钟周期内可完成读、写操作
    • 容量有限:典型值大约100Kbytes
  • Block RAM ( BRAM)
    • 高容量:典型值在Mbytes 级别
    • 访问性能受限:端口有限
  • 权衡:带宽vs.容量

数值精度

头文件: ap_int.h,ap_fixed.h
支持任意精度、任意位宽的有/无符号数据类型:

  • Unsigned int :ap_uint
  • Signed int :ap_int
  • Unsigned fixed : ap_ufixed
  • Signed fixed :ap _fixed

精度处理

  • 加法: ap_uint A = ap_uint B + ap_uint C ,where x = max (y,z) + 1
  • 乘法: ap_uint A = ap_uint B * ap_uint C ,where x = y+z

其实说人话就是加法的精度取决于原来误差较大的,乘法则是原来的相乘


模块接口

在综合过程中定义生成的硬件接口

  • 函数级(函数调用传参)的接口实现方式、控制协议
  • ip级(顶层函数参数)的接口实现方式、控制协议

常用有

  • ap_fifo:生成标准FIFO接口,常做模块间数据通路
  • m_axi:生成AXI4总线的Master接口,常做IP外部数据访问接口
  • s_axilite:生成AXI4-lite的Slave接口,常做控制IP调用的控制接口

优化案例

源码如下

void test()
{
	float In[CHin][Rin][Cin];
	float Out[CHout][R][C];
	float W[CHout][CHin][K][K];

	Output_Channel:
	for(int cho=0; cho<CHout; cho++)
	{
		Input_Channel:
		for(int chi=0; chi<CHin; chi++)
		{
			Row:
			for(int r=0; r<R; r++)
			{
				Column:
				for(int c=0; c<C; c++)
				{
					Kernel_Row:
					for(int kr=0; kr<K; kr++)
					{
						Kernel_Column:
						for(int kc=0; kc<K; kc++)
						{
							Out[cho][r][c] += In[chi][r+kr][c+kc] * W[cho][chi][kr][kc];
						}
					}
				}
			}
		}
	}

	return;
}

未优化

xilinx 暑期学校学习笔记(三)HLS优化语法与资源_第2张图片

数组展开及循环展开

void test()
{
	float In[CHin][Rin][Cin];
#pragma HLS array_partition variable=In complete dim=1
	float Out[CHout][R][C];
#pragma HLS array_partition variable=Out complete dim=1
	float W[CHout][CHin][K][K];
#pragma HLS array_partition variable=W complete dim=1
#pragma HLS array_partition variable=W complete dim=2
	
	Row:
	for(int r=0; r<R; r++)				
	{
		Column:
		for(int c=0; c<C; c++)	
		{
			Kernel_Row:
			for(int kr=0; kr<K; kr++)					
			{
				Kernel_Column:
				for(int kc=0; kc<K; kc++)				
				{
					Output_Channel:
					for(int cho=0; cho<CHout; cho++)
					{
#pragma HLS UNROLL
						Input_Channel:
						for(int chi=0; chi<CHin; chi++)						
						{
#pragma HLS UNROLL
							Out[cho][r][c] += In[chi][r+kr][c+kc] * W[cho][chi][kr][kc];
						}
					}
				}
			}
		}
	}

	return;
}

xilinx 暑期学校学习笔记(三)HLS优化语法与资源_第3张图片

数组展开及PIPELINE优化

void test()
{
	float In[CHin][Rin][Cin];
#pragma HLS array_partition variable=In complete dim=1
	float Out[CHout][R][C];
#pragma HLS array_partition variable=Out complete dim=1
	float W[CHout][CHin][K][K];
#pragma HLS array_partition variable=W complete dim=1
#pragma HLS array_partition variable=W complete dim=2
	
	Row:
	for(int r=0; r<R; r++)				
	{
		Column:
		for(int c=0; c<C; c++)	
		{
			Kernel_Row:
			for(int kr=0; kr<K; kr++)					
			{
				Kernel_Column:
				for(int kc=0; kc<K; kc++)				
				{
#pragma HLS PIPELINE
					Output_Channel:
					for(int cho=0; cho<CHout; cho++)
					{
						Input_Channel:
						for(int chi=0; chi<CHin; chi++)						
						{
							Out[cho][r][c] += In[chi][r+kr][c+kc] * W[cho][chi][kr][kc];
						}
					}
				}
			}
		}
	}

	return;
}

xilinx 暑期学校学习笔记(三)HLS优化语法与资源_第4张图片

不同循环顺序的PIPELINE优化

void test()
{
	float In[CHin][Rin][Cin];
#pragma HLS array_partition variable=In complete dim=1
	float Out[CHout][R][C];
#pragma HLS array_partition variable=Out complete dim=1
	float W[CHout][CHin][K][K];
#pragma HLS array_partition variable=W complete dim=1
#pragma HLS array_partition variable=W complete dim=2

	Kernel_Row:
	for(int kr=0; kr<K; kr++)					
	{
		Kernel_Column:
		for(int kc=0; kc<K; kc++)				
		{
			Row:
			for(int r=0; r<R; r++)				
			{
				Column:
				for(int c=0; c<C; c++)	
				{		
#pragma HLS PIPELINE
					Output_Channel:
					for(int cho=0; cho<CHout; cho++)
					{
						Input_Channel:
						for(int chi=0; chi<CHin; chi++)						
						{
							Out[cho][r][c] += In[chi][r+kr][c+kc] * W[cho][chi][kr][kc];
						}
					}
				}
			}
		}
	}

	return;
}

xilinx 暑期学校学习笔记(三)HLS优化语法与资源_第5张图片

效果对比

xilinx 暑期学校学习笔记(三)HLS优化语法与资源_第6张图片

你可能感兴趣的:(xilinx暑期学校)