HLS开发学习-11- for 循环优化(一)

简介: HLS开发学习-11- for 循环优化(一)

写在前面


本文是本系列专题的第十一篇,参考高亚军老师的视频教程以及课程的ppt,主要介绍了vivado HLS对for 循环优化。

for循环优化


这里是一个很简单的for循环的函数,描述了一个运算功能。软件的分析思想和硬件电路的分析思想是不太一样的,这里的硬件运算流程是,先进行数据b、c的读取做运算,然后读取数组元素的数据做运算,然后执行写入到目标数组中,一次for循环的延迟是3个时钟周期,这里for循环的次数为3,所以循环执行的延迟为9,对于硬件电路来说,执行判断是否继续执行for循环不是立马执行的,所以要需要耗费一个时钟周期进行执行,所以函数的延迟为11。

image.png

虽然这里有最后的数据,但是HLS检查循环条件是必要的。这意味着需要额外的周期。(也就是上面的11个延迟周期的来源)

image.png

流水线优化


对于for循环的优化,我们比较常用的就是使用pipeline 的指令进行for循环的展开,提高for循环中的并行度,把整体算法循环的延迟给降下来。下图可以看出在使用指令进行并行展开的前后,算法的循环的延迟对比。

image.png

同样可以在波形中进行查看函数的延迟,

image.png

for循环展开


对于for循环可以进行展开,在默认状态下for循环是折叠的,在电路中对应的就应该为,对于for循环的每次循环都是使用的同一套电路,采用分时复用的方式,而对于展开的foe循环来说,有点像复制的功能,或者类似FPGA的模块重复调用。

image.png

for循环部分展开


也可以对for循环进行部分展开,假如把for循环复制3份,对于下图的电路即可等效拆分为三组电路结构,两个状态公用一份电路。

image.png

在HLS设置就是把展开的指令的factor填写需要复制的数量。

image.png

i的数据类型


对于I的数据类型,通常是不影响最后的优化结果的,因为HLS在综合时看的是变量i的最大值,这里的i最大值为6,工具就会给他分配位宽为4的寄存器,所以这里的i也可以使用ap_int< 4 >进行变量的定义。

image.png

for循环优化小结


  1. 要比较清楚的知道函数的循环延迟。
  2. 可以使用流水操作的指令进行for循环的优化。
  3. 可以使用展开指令提高函数的并行度。
  4. 部分展开可以在资源和并行度中求得一个权衡。
  5. 迭代变量的类型是不影响最后的综合结果的。

for循环合并


迭代量一致


在这个例子的函数中,两个for循环分别实现了加法电路和减法电路,在实际硬件设计中,我们希望两份电路进行一个选择判断,从而实现输入数据同时送给加减法电路中,节约资源,可以并行执行。

image.png

但是对于HLS的综合工具,默认情况下进行分析,把加减法进行了顺序执行,没有进行并行优化。

image.png

这里引用了Merge合并的操作,绿色的方框表示for循环的合并区域,在directive中也可以看到,加减法操作的for循环在loop_region的范围内,实现了合并。

image.png

合并之后,循环延迟变为了8,整个函数的延迟变成了9,这里就是合并带来的好处。

image.png

合并可以在一定程度上帮助减少延迟。所有的循环在设计状态机中都意味着并创建至少一个状态-当有多个顺序循环时,它会创建额外的不必要的时钟周期,并阻止进一步的优化. 因此资源利用率会下降。

迭代量不一致


image.png

在合并时,循环迭代的边界不一样,函数合并操作会依据函数的最大边界进行设置合并。

迭代量一个为常数,一个为变量


image.png

在未进行合并时,变量的迭代次数是个范围。这个范围是依据迭代的变量的位宽进行设置的。

image.png

如果在该种情况下进行循环的合并,HLS将会报错,提醒不能进行合并。

迭代量都为变量


和上面迭代量一个为常数,一个为变量的情况一样,如果在该种情况下进行循环的合并,HLS将会报错,提醒不能进行合并。

image.png

两个都是变量的合并解决办法


可以通过修改代码的方式进行合并相同次数的循环,然后把额外的循环进行单独编写。

image.png

循环合并原则


  1. 如果循环量都是常数,按最大值进行合并。
  2. 如果循环量都是变量,那么要求循环有相同的变量边界范围。
  3. 如果一个是变量,一个是常量,则不能进行循环的合并。

for循环合并小结


  • 区域是指用两个大括号括起来的任何区域。
  • 合并循环减少了RTL中所需的时钟周期的数量(在循环体实现之间转换),并允许并行实现循环(如果可能的话)。
  • 不是所有的循环都可以合并。有些规则应该遵守。

for循环优化-dataflow


引入示例,这里定义这三个变量为任务A、B、C。

image.png

该函数的数据通路为下图:

image.png

任务B的变量取决于任务A。任务C的变量取决于任务B。此时,应该如何进行减少延迟实现算法的优化呢?之前的for循环的合并和流水操作是不能实现优化操作的。

这里可以使用dataflow的方式进行循环的优化。

image.png

这种方式有点像流水操作,但又不太相同,这里使用dataflow的优化数据交互直接使用了RAM、FIFO、寄存器。实现数据的吞吐交互,此时,循环不在像之前一样是纯串行执行的方式,而是存在了一定的并行。dataflow优化允许任务的执行重叠,增加了设计的总体吞吐量,减少了延迟。

image.png

在应用dataflow操作后的性能对比如上图所示。对于channel使用的实现方式是RAM、还是FIFO的方式。这里可以在config_dataflow进行配置更改。

一个循环任务被其他两个循环任务调用不能直接使用dataflow


对于一个循环任务被其他两个循环任务调用不能使用dataflow,这里的loop1产生的输出引用到loop2中进行使用,同时也在loop3中进行使用。这样的例子就不能进行dataflow的优化,但是这里可以进行流水操作和循环合并。

image.png

解决一个循环任务被其他两个循环任务调用不能直接使用dataflow方法


为了使用dataflow,可以使用一个for循环进行变量的复制,确保for循环的变量只在一个for循环中被使用。

image.png

然后在进行使用dataflow就可以进行优化我们的设计了。

image.png

bypass task


在这个示例中,temp1经过了loop2生成了temp3,而temp2是直接进入loop3进行使用的,这种情况也不能直接使用dataflow的操作,也不能使用pipeline和merge。

image.png

这里的解决办法就是在loop2,只对temp2进行复制,然后输出给loop3,这样就可使用dataflow的优化设计。

image.png

配置dataflow 存储通道


Vivado HLS将任务之间的通道实现为乒乓缓冲区或FIFO缓冲区,这取决于数据交互的访问模式。

  • 对于标量、指针和引用参数以及函数返回,Vivado HLS将通道实现为FIFO。
  • 如果Vivado HLS确定数据是按顺序访问的,Vivado HLS将内存通道实现为深度1的FIFO通道。
  • 如果Vivado HLS无法确定数据是按顺序访问的还是以任意方式访问的,Vivado HLS将内存通道实现为乒乓缓冲区。就像两个BRAM,每个块ram由消费者数组或生产者数组的最大大小定义。

使用config_dataflow配置

  • 该配置为设计中的所有通道设置默认通道。
  • 减少信道中使用的内存大小,可以使用FIFO。
  • 使用fifo_depth选项显式设置FIFO中元素的深度或数量。当设置FIFO的深度时,建议您使用带有默认深度的FIFO,确认设计通过C/RTL协同仿真,然后减小FIFO的大小,确认C/RTL协同仿真仍然完成,没有问题。如果RTL联合模拟失败,FIFO的大小可能太小,以防止失速。

for循环优化-dataflow小结


  • DATAFLOW允许“for循环”并行运行,因此它可以帮助减少延迟并提高吞吐量。
  • 当DATAFLOW应用于’for循环’时存在一些限制。
  • 通道是可配置的,它可以是乒乓RAM或FIFO。


目录
相关文章
|
缓存 调度
HLS开发学习-12- for 循环优化(二)
HLS开发学习-12- for 循环优化(二)
267 0
HLS开发学习-12- for 循环优化(二)
|
异构计算
HLS开发学习-13- 数组优化
HLS开发学习-13- 数组优化
337 0
HLS开发学习-13- 数组优化
|
缓存 数据处理 索引
HLS实践 - 06 - 优化设计(二)
HLS实践 - 06 - 优化设计
169 0
HLS实践 - 06 - 优化设计(二)
|
存储 人工智能 监控
HLS实践 - 06 - 优化设计(一)
HLS实践 - 06 - 优化设计
223 0
HLS实践 - 06 - 优化设计(一)
HLS开发学习-14- Vivado HLS 函数层面的优化
HLS开发学习-14- Vivado HLS 函数层面的优化
229 0
HLS开发学习-14- Vivado HLS 函数层面的优化
HLS开发学习-15- HLS优化指令汇总
HLS开发学习-15- HLS优化指令汇总
284 0
HLS开发学习-15- HLS优化指令汇总
HLS实践 - 03 - 接口优化设计(一)
HLS实践 - 03 - 接口优化设计
257 0
HLS实践 - 03 - 接口优化设计(一)
HLS实践 - 03 - 接口优化设计(二)
HLS实践 - 03 - 接口优化设计
300 0
HLS实践 - 03 - 接口优化设计(二)
|
存储
HLS实践 - 02 - 简单优化FIR设计
HLS实践 - 02 - 简单优化FIR设计
175 0
HLS实践 - 02 - 简单优化FIR设计
|
算法 C语言 C++
HLS开发学习-03-VIVADO HLS设计流程
HLS开发学习-03-VIVADO HLS设计流程
270 0
HLS开发学习-03-VIVADO HLS设计流程