集成电路技术分享

 找回密码
 我要注册

QQ登录

只需一步,快速开始

搜索
查看: 1060|回复: 2

FPGA硬件函数优化方法

[复制链接]
fpga_feixiang 发表于 2020-8-30 21:28:21 | 显示全部楼层 |阅读模式
硬件函数由vivado_hla综合成PL端的硬件。编译器将自动的将C/C++代码编译到FPGA硬件实现中,并于所有编译器一样,使用所有编译器默认值。除了编译器默认的以外,vivado提供了大量的优化,通过使用集成好的函数来应用于C/C++代码。本章解释了可以应用的优化和对于应用这些的推荐方法。

两个流程用于硬件函数优化:

1).TOP-DOWN flow:在这个流程中,使用SDSCO环境,程序分解为自上而下处理的硬件函数,让系统编译器创造能够自动操作数据流模式的函数管道。每个硬件函数的微体系结构利用vivado_hls来优化。

2).Bottom-up flow/自底向上的流程:利用vivado设计套件提供的vivado_hls编译器,硬件函数隔离系统,单一的进行优化。硬件函数被优化后,可用于实现而不是使用默认的实现。最后单一优化后的硬件函数将被纳入SDSOC环境中(听着像先使用vivado套件设计优化某一硬件函数,然后生成IP核,放入SDSOC中)

自下而上的流程经常用于不同软件团队对软件和硬件进行优化的组织中,软件程序员可以利用他们在组织内部或者合作伙伴中利用现有的硬件实现。

以上两种工作流程都得到支持,在任何情况下都使用了相同的优化方法。这两个工作流程都能够产生相同的高性能系统。xilinx将根据视为个别团队或者组织所做的工作流程来决定,它并未没有建议使用哪种流程。两种工作也可以在一起使用。

1.一些基本概念:

在试图执行任何硬件功能优化之前,理解现有的代码和编译器所取得的性能是很重要的,并且了解性能是如何度量的。这是通过选择硬件实现和构建项目来是实现的。在项目构建后,报告将会在IDE的报告部分展示(hw_function中)这个报告将会详细介绍性能估计和资源使用估计。

性能评估的关键 是时间,间隔以及延时。

1)时间约束:主要体现在编译器估计的时钟频率和程序员设定的时钟频率,当估计的频率大于设定的频率时,硬件将不能在这个频率上工作。在项目设置中,使用通过使用数据流时钟频率选项来设置,可以减少估计时钟频率。此外,如果一个估计值的频率不超过设定频率的20%,那么也有可能实际是可以工作的。当生成比特流时,还可以进一步优化,并且任然可能满足频率要求。但是硬件函数不能给保证频率要求。

2)启动间隔:是函数接收新输入之前的时钟周期,通常是任何系统中最关键的性能指标。在理想的硬件函数中,硬件以每一个采样时钟周期处理数据。如果大数据传递到硬件的长度是N(数组长度为N),这意味着硬件函数在n个时钟周期处理N个数据样本,并且在所有N个样本被处理后都可以接受一个时钟周期的新数据。创建一个优化数据长度小于N的硬件函数是可以做到的,但是这需要更多的PL端资源,通常这样做是没什么好处的。硬件函数往往被理想化,因为它消耗和产生的数据的速度都比其他系统快。

3)循环初始化间隔:是在循环的下一次迭代开始处理数据之前所需要的时钟周期个数。当你深入分析性能瓶颈时,这个度量就会显得很重要。

4)延迟是函数计算所有输出值所需要的时钟周期数,这只是从应用数据到准备就绪时的滞后,对于大多数应用程序而言,这是很少关注的。尤其是当硬件函数的延迟远远超过软件或者系统功能(例如DMA)。然而,最为一个性能指标,你应该检查和确认对于一个应用程序而言,它是否有影响。

注意:循环迭代延迟是完成一个循环迭代所需要的时钟周期数,而循环延迟是执行循环所有迭代的周期数。

区域评估报告部分将会详细的说明在硬件实现中需要多少PL端资源,以及设备上有多少可用的资源。这里关键量度是利用率(%),对于任何资源,利用率不能超过100%,一个大于100%的数字意味着没有足够的资源来实现硬件函数,这就需要一个更大资源的FPGA设备。

这里应当对系统所需要的性能有所了解,以及硬件函数需要什么度量标准。通过了解当前设计性能和一组基准性能指标,就可以继续向硬件函数应用优化指令学习。

2.优化指标:

1)LOOP_TRIPCOUNT:仅用于评估报告,对实际硬件函数无影响

2)Pipeline for performance:创建一个高性能设计是将函数,循环和操作流水线化(在管道中处理),流水线工作开业导致最高级别的并发性和最高级别的性能,

pipeline的指令有:

PIPELINE:通过允许在一个循环或者函数中并发执行操作,从而减少启动时间间隔。

DATAFLOW:启用任务级流水线,允许函数胡循环同时执行,用于最小化时间间隔。

3)RESOURCE:指定用于实现变量(数组,算术操作)的硬件资源上的流水线

4)config Compile:使用自底向上的数据流时,允许循环根据迭代计数自动化流水线操作

在优化的阶段,你可以尽可能多的创建并发操作,可以将管道指令应用在函数和循环上.在包含函数和循环的层级上使用数据流指令,并使它们并行工作。资源指令可以用于有限提升最高层级的性能。

3.对于自底向上的设计中,一些可用的策略:

1)一些函数和循环包含子函数,如果子函数没有pipelined,那么这样的函数在pipelined时可能会显示出有限的改进。(没有pipeined的函数将会限制性能)

2)一些函数和循环包含子循环,当你使用管道pipeline指令时,该指令自动打开下面层次的所有循环。这会创造大量的逻辑,在下面的层次结构上管道pipeine循环可能更有意义。

基本的策略是通过pipeline任务(函数和循环)来优化处理。



4.硬件函数管道化策略:

获得高性能设计的关键优化指令是管道pipeline和数据流dataflow指令。

本节详细地讨论如何将这些指令应用于各种C语言体系。

从根本上说,有两种类型的C/C++代码:基于frame帧和基于样本。但是啊无论采用哪种编码方式,硬件函数都可以在两种情况下实现相同的性能。区别只在于如何优化应用指令。

(1)基于frame帧的C代码:

基于frame帧的编码风格的主要特点是:函数处理多个数据样本-一个数据帧-通常作为数组和指针提供,在每次事件中通过指针访问数据(事件是一个完整执行的C函数)。

这种编码方式中,数据通常通过一系列循环或者嵌套循环进行处理。

基于frame帧的C代码编程例子:

void foo(data_t in1[HEIGHT][WIDTH],data_t,in2[HEIGHT][WIDTH],data_t,out[HEIGHT][WIDTH])

loop1:

    loop2:

         loop3:

1)函数层级优化:如果管道指令应用于函数foo,在函数一下层级所有回路都必须展开,这是pipeline的要求。即管道内不能有顺序逻辑。这会导致创建height*width个元素浅拷贝的逻辑单元,这将导致一个臃肿的设计。

由于数据是按照顺序方式访问的,所以硬件功能接口上的数组可以实现可以为多种类型的硬件接口。

Block RAM interface

AXI4 interface

AXI4-lite interface

AXI4-Stream interface

FIFO interface

BRAM接口可以实现为双端口接口,也就是说每个时钟周期能够得到两个样本,其他接口类型只能得到一个样本量。如果一个大型的高度并行的硬件设计不能够并行处理所有数据,这就会导致资源的浪费???

2)loop1优化:在这个循环里配置pipeline,用于在每个始终周期处理一行。由于PS上运行的主机代码不可能处理很大的数据量,这将导致许多高度并行的硬件资源由于带宽限制不能够并行操作。

3)loop2:通过pipeline loop2创建的硬件函数在一个时钟周期中处理一个数据,只需要达到所需的数据吞吐量。

4)loop3:loop3可能包含先前像素的移位寄存器,在这里添加pipeline的话,会告诉编译器使用一个时钟周期来移位一个数据值,这将会导致数据迭代处理很慢。

故以上代码例子中,最理想的pipeline的位置是LOOP2,对于同一层次上有多个循环的例子,可以为每个循环确定放置pipeline指令的最佳位置,然后应用到该函数的数据流指令,以确保每个循环一并发的方式进行。

(3)优化结构提升性能:

eg.loop:for(i=3,i<N,i=i+4)

{     #pragma HLS PIPELINE

    sum+=men[i]+men[i-1]+men[i-2]+men[i-3];

}

return sum

对于以上结构的编码,编译器会给出警告:unable to schedule 'load' operatin ...on array 'men' due to limited memory ports

出现这样的警告是因为BRAM是双端口,但是pipeline希望并行处理四个数据的加法,这是没办法做到的。解决思路是使用ARRAY_PARITION指令指向men数组。该指令将数组划分为更小的数组,通过提供更多数据端口和允许更高性能的pipeline来改进数据结构。使用该指令后,men数组将会使用两个双端口的BRAM来缓存数据。

在尝试将循环和函数pipeline时,可能会遇到很多类似的问题,一下列出有助于减少数据结构瓶颈的指令。

ARRAY_PARTITION/数组分区:将大数组分割成多个较小的数组或者多个单数组,用于改善寄存器对数组的访问,进而消除BRAM的瓶颈。

DEPENDENCE/依赖:提供可以客服循环依赖的额外信息,允许循环Pipeline.
大鹏 发表于 2020-9-3 16:19:03 | 显示全部楼层
FPGA硬件函数优化方法
您需要登录后才可以回帖 登录 | 我要注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

QQ|小黑屋|手机版|Archiver|集成电路技术分享 ( 京ICP备20003123号-1 )

GMT+8, 2024-4-27 08:49 , Processed in 0.077739 second(s), 22 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表