仅对英特尔可见 — GUID: ddd1582588012187
Ixiasoft
仅对英特尔可见 — GUID: ddd1582588012187
Ixiasoft
6.9. 循环融合(Loop Fusion)
循环融合是一种编译器转换,其中两个相邻的循环在同一索引范围内合并成单个循环。这种转换通常用于减少循环开销并提高运行时性能。
Unfused Loops | Fused Loop |
---|---|
for (j = 0; j < 300; j++) a[j] = a[j] + 3; for (k = 0; k < 300; k++) b[k] = b[k] + 4; |
for (f = 0; f < 300; f++) { a[f] = a[f] + 3; b[f] = b[f] + 4; } |
Unfused Loops | Fused Loop |
---|---|
for (j = 0; j < 300; j++) a[j] = a[j] + 3; for (k = 0; k < 300; k++) b[k] = b[k] + 4; |
for (jk = 0; jk < 600; jk++) { if (jk < 300) { int j = jk; a[j] = a[j] + 3; } else { int k = jk - 300; b[k] = b[k] + 4; } } |
循环控制结构意味着很大的开销。通过融合两个循环,循环所需要的控制结构的数量就从两个减少到一个,从而减少了此开销。减少该控制结构数量的主要目的是为您的设计节省FPGA的面积的同时,仍然保持(理想情况下增加)组件吞吐量。
融合外部循环会引入并行出现过的并发性。将两个相邻的循环(Lj和Lk)主体合并起来形成单个循环(Lf),其中的循环主体包含Lj和Lk主体。该组合循环主体可实现Lj和Lk的给定迭代串行化以并行执行的操作。实际上,这两个循环现在是作为单循环以锁步(lockstep)方式执行,从而改善了延迟情况。
如果融合了内部循环,而外部循环迭代的流水线执行已经实现了该并行性。该情况下,循环融合的并行效果就会减弱。
融合条件
- 两个循环必须相邻。
也就是说,您不能有一个带有副作用的声明Si,使得Lj之后先执行Si,然后才执行Lk。
- 每个循环必须有一个single-entry point(单一入口点)和一个single exit point(单一出口点)。
例如,不考虑融合包含break声明的循环。
- 循环必须没有负距离(negative-distance)依赖项。
也就是说,对于Lj先于Lk被定义的Lj和Lk中,循环Lk的迭代m不依赖于循环Lj的迭代m+n(其中n>0)中计算的值。
自动循环融合(Loop Fusion)
如果您组件的编译器分析确定融合循环是有益的,则 Intel® HLS Compiler自动相邻融合具有相同行程计数的循环。
- 两个循环的其中之一由ivdep pragma注释,但不能两个都是。
- 两个循环其中之一(但不能两者皆是)包含无停顿逻辑。
High-Level Design Report中的Loop Analysis Report显示循环何时被融合。
- nofusion指令
使用该指令注释循环以请求编译器不融合被批注的循环。
-
覆盖编译器有益性分析并融合相邻循环以确保其安全。
使用loop_fuse指令告知编译器考虑融合具有不同行程计数的相邻循环。