仅对英特尔可见 — GUID: tac1582215172557
Ixiasoft
仅对英特尔可见 — GUID: tac1582215172557
Ixiasoft
6.9.1. 循环融合控制(loop_fuse预处理指令)
使用loop_fuse指令告知编译器尝试融合两个相邻的循环而不影响任一循环的功能,同时覆盖编译器对融合循环的有益性分析。
融合相邻循环有助于减少组件中的循环控制开销量,从而有助于减少所使用的FPGA面积,并且可以通过将两个循环作为一个(融合)循环来执行从而提高性能。
#pragma loop_fuse [depth(N)] [independent] { ... }
#pragma loop_fuse // can also be // #pragma loop_fuse depth(1) { L1: for(...) {} L2: for(...) { L3: for(...) {} L4: for(...) { L5: for(...) {} L6: for(...) {} } } } 默认情况下(或depth(1)),最初仅考虑将循环L1和L2进行融合。 |
|
#pragma loop_fuse depth(2) { L1: for(...) {} L2: for(...) { L3: for(...) {} L4: for(...) { L5: for(...) {} L6: for(...) {} } } }以及depth(2),首先考虑以下循环对进行融合:
|
#pragma loop_fuse depth(3) { L1: for(...) {} L2: for(...) { L3: for(...) {} L4: for(...) { L5: for(...) {} L6: for(...) {} } } }对于depth(3),首先考虑以下循环对进行融合:
|
当循环满足条件时,编译器会自动考虑合并具有相同行程计数的相邻循环。您还可以使用loop_fuse指令告知编译器考虑融合具有不同行程计数的相邻循环。
由于将loop_fuse指令应用于代码块,编译器在确定可以安全合并循环时始终尝试合并块中的相邻循环(具有相同或不同行程计数)。如果两个循环满足循环融合(Loop Fusion)的Fusion Criteria部分中描述的合并标准,则认为它们可以安全合并。
未融合的循环 | 融合环 |
---|---|
#pragma loop_fuse { for (int i = 0; i < N; i++) { // Loop Body 1 } for (int j = 0; j < M; j++) { // Loop Body 2 } } |
for (int f = 0; f < max(M,N); f++) { if (f < N) { // Loop Body 1 } if (f < M) { // Loop Body 2 } } |
#pragma loop_fuse { L1 for(...) {} L2 for(...) { L3 for(...) {} } L4 for(...) {} }
使用independent选项来覆盖依赖项安全检查。如果您指定了independent选项,则表示您向编译器保证由loop_fuse指令指示的循环融合对是安全。换言之,融合循环中没有负距离依赖关系。如果它不安全,您的组件中可能会遇到功能错误。
loop_fuse代码块中的功能调用
如果功能调用发生在带有以loop_fuse指令批注的代码块中 并且并且内联的功能调用包含循环,则生成的循环可以作为循环融合的选择对象。
嵌套式depth(N)子句
当您嵌套loop_fuse指令时,可能会创建重叠的可选对象循环集。
#pragma loop_fuse depth(2) independent { L1: for(...) {} L2: for(...) { #pragma loop_fuse depth(2) { L3: for(...) {} L4: for(...) { L5: for(...) {} L6: for(...) {} } } } }在此实例中,编译器考虑融合以下循环对:L1/L2、L3/L4和L5/L6。此外,编译器会覆盖以下循环对的编译器负距离依赖性分析:L1/L2、L3/L4。
<quartus_installdir>/hls/examples/tutorials/best_practices/loop_fusion