for循环优化基本概念从下面的例子中来解释for循环中的基本概念:
图 4.1 for循环基本概念
由于n等于3,因此每次循环可以分成4个步骤来完成:
c0:读取数据b和c;
c1:获取数据xin 0处地址;
c2:读取对应地址上的数据;
c3:计算yo[0]的值。
后面的计算都是三个时钟周期计算出一个值,因此对一次循环来说,loop iteration latency为3,loop iteration interval也是3,loop latency是9,再加上前面读b和c的值的一个周期,整个函数的latency是10,函数间的initial interval是11.
pipeline对for循环常用的优化是pipeline,pipeline的原理如下图4.2所示。
图 4.2 pipeline优化原理
在优化结束后,loop iteration latency为3,loop iteration interval变成1,loop latency为5.
如果对函数做pipeline,那么会自动把函数下面的for循环都做unrolling处理;如果对外层的for循环做pipeline,那么会自动对内层的for循环做unrolling处理。
unrolling默认情况下for循环是折叠的,就是电路被时分复用。当展开后,资源增加。如下图所示将for循环展开成3倍的情况,资源也扩大了3倍。
图 4.3 展开成3倍
也可以部分展开,循环次数为6,但展开成3倍,程序如下所示:
展开后,程序被分成3部分,资源也复制了3份。
图 4.4 unroll的设置
merge当几个for循环执行的内容很相似时,如下面的程序所示:
两个for循环分别对两个数据做加法和减法,在hls综合后,会先进行第一个for循环的计算,完成后再进行第二个for循环的计算。这样综合出的latency为18,interval为19。
图 4.5 综合后延迟
在hls中提供了merge的选项,合并的是for所作用的region,合并后综合后的延迟如下图4.6所示。
图 4.6 merge后的延迟
上面的例子中两个循环的边界相同,如果两个循环的边界不同,则以最大的作为合并后的边界;如果一个边界是变量,另一个是常量,则不能合并;如果两个循环边界都是变量,依然不能合并。
还可以将for循环封装成一个函数,并在上一层中例化两次,并对函数采用allocation来使函数并行执行,在allocation中有limit选项,可以指定实例化的次数,该数据与程序中实际的数值应该是一样的。
数据流在下面的例子中,task b依赖于task a,task c依赖于task b,如图4.7所示。
而且可以分析出,该结构不适合之前所讲的pipeline和merge方式进行处理,在可以使用dataflow的方式。
从图中可以看出,在使用dataflow后,loop b无需等待a执行完成后才开始执行,而且各个loop之间也村在间隔。且延迟和资源都明显减少。
dataflow使用的限制:
1.一个输出在多个loop模块中使用
2.被bypass的模块
3.带反馈的模块
4.带条件的模块
5.可变循环边界的模块
6.多个退出条件的模块
下面分别对上面的限制条件进行说明。
1.din在loop1中输出的temp1同时赋给loop2和loop3使用,这时是不能使用dataflow的,如图4.10所示。
通过对代码进行适当的修改,将其结构进行变形,增加一个loop_copy模块,将其输出一个送个loop2,另一个输出送给loop3,但其实这两个输出的结果是相同的。就可以使用dataflow来完成该函数。
且使用了dateflow后,工程所占用的资源和延迟都相应减少。
被bypass的模块如下图4.12所示的例子中,temp1在loop2中使用,但temp2没有经过loop2,直接在loop3中使用,这种情况下也是不能使用dataflow的。
同样的,可以对代码进行优化以达到可以使用dataflow的目的,如下图4.13所示。在loop2中,增加一个输出端口,使其输出给loop3,这样就可以使用dataflow了。
在dataflow的循环之间的存储模块,对于scalar、pointer和reference或者函数的返回值,hls会综合为fifo;对于数组,结果可能是乒乓ram或者fifo:如果hls可以判断数据是流模式,就会综合为fifo,且深度为1,若不能判断,就会综合为乒乓ram。我们也可以指定为fifo或者乒乓ram,但在指定为fifo时,如果指定的深度不合适,综合时就会出现错误。
嵌套for循环三种嵌套循环:
对于perfect loop,对外边的loop做流水比对内循环做流水更加节省时间。
对于imperfect loop,我们总希望可以转换为perfect loop或者semi-perfect loop。如下的imperfect loop,如果对内层product做流水,综合结果如右侧的图所示。
如果对第二层即col的loop做流水,则会提示信息,col下的循环会被展开。
从图中的warning可以看出,a被综合为一个双端口的ram,但第14行和第20行对a的操作有一个重叠的区域,意味着吞吐率受限。
如果对最外部的循环做流水,会把下面所有的循环都展开,延迟会减少,但资源会增加。
如果对整个函数做流水,那么函数下面的所有循环都会展开,能获得最好的latency,但资源也是最多的。
我们可以对代码就行优化,具体代码具体优化。
rewind我们在使用了pipeline后,循环之间仍然会有间隔,但使用rewind功能,可以消除该间隔,如下图所示。
图 4.16 rewind功能
但当函数中有多个循环时,rewind不能使用。
自动添加流水在config_compile中,可以设置自动添加流水操作,如果循环次数小于我们设定的pipeline loops时,hls就会自动为for循环添加流水。
在使用config_compile后,如果不想对某些for循环做流水,就可以在pipeline下面的选项中选中disable loop pipeline。
变量边界的解决方法当循环边界为变量时,通常可以采用下面的方式进行处理。
使用tripcount directive;对于边界变量的定义使用ap_int;在c代码中使用assert宏。tripcount directive不会对综合有任何的影响,它只会对报告的显示有影响。
使用ap_int和assert方法后,综合后的资源会有明显的减少。采用assert的方式的资源和延迟是最少的。
inline是针对函数,flatten是针对嵌套的循环。
空客已正式向达美航空交付了第12架A220飞机
修改PLC定时器设定值的方法
如何写一个会讲笑话的Python程序
MPEG1、MPEG2图像压缩
交流伺服系统的分类及应用场合
HLS for循环优化
分子组装理论基础的探究
Trinamic技术在太空增材制造法中的应用
当贝投影D3X和米家青春版2哪个好?谁才是年轻人的第一款投影仪
感应式交流验电笔的原理及制作
被传陷入资金困境的东贝营运问题集中爆发
第三代宽禁带半导体碳化硅功率器件的应用
无人机真实任务!英皇家空军指出应让更多玩家参与现实作战
iphone8什么时候上市?iphone8最新消息:iphone8即将上市,iPhone 8出现新的泄密,两大改变,恐怕就这样了
存储瓶颈日趋严重 数据存储核心专利国内企业缺席
浅谈汽车连接器接触失效的原因
动力锂电池和普通锂电池的区别
Allegro霍尔效应传感器解决方案满足所有行业应用要求
子网掩码怎么计算
英创信息技术ESMARC工控主板专用电磁屏蔽罩说明