循环并行化 - 2021.2 Chinese

Vitis 高层次综合用户指南 (UG1399)

Document ID
UG1399
Release Date
2021-12-15
Version
2021.2 Chinese

Vitis HLS 会尽早调度逻辑和函数,以减少时延,同时使估算的时钟周期保持在用户指定的周期之下。为此,它会将尽可能多的逻辑运算和函数调度为并行运行。但它并不会将循环也调度为并行执行。

如果对以下代码示例进行综合,则先调度 SUM_X 循环,然后调度 SUM_Y 循环,即使 SUM_Y 循环无需等待 SUM_X 循环完成后再开始运算,也仍调度为在 SUM_X 之后运行。


#include "loop_sequential.h"

void loop_sequential(din_t A[N], din_t B[N], dout_t X[N], dout_t Y[N], 
 dsel_t xlimit, dsel_t ylimit) {  

 dout_t X_accum=0;
 dout_t Y_accum=0;
 int i,j;

 SUM_X:for (i=0;i<xlimit; i++) {
 X_accum += A[i];
 X[i] = X_accum;
}

 SUM_Y:for (i=0;i<ylimit; i++) {
 Y_accum += B[i];
 Y[i] = Y_accum;
 }
} 

由于循环边界(xlimitylimit)不同,因此无法合并。通过将循环置于不同函数内(如以下代码示例所示),即可实现相同功能,并且可并行调度这 2 个循环(在函数内部)。


#include "loop_functions.h"

void sub_func(din_t I[N], dout_t O[N], dsel_t limit) {
 int i;
 dout_t accum=0;
  
 SUM:for (i=0;i<limit; i++) {
 accum += I[i];
 O[i] = accum;
 }

}

void loop_functions(din_t A[N], din_t B[N], dout_t X[N], dout_t Y[N], 
 dsel_t xlimit, dsel_t ylimit) {

 sub_func(A,X,xlimit);
 sub_func(B,Y,ylimit);
}

如果对前述示例进行综合,则时延为顺序循环示例的一半,因为现在这些循环(作为函数)可并行执行。

dataflow 最优化同样可在顺序循环示例中使用。此处演示了在函数中捕获循环以发挥其并行性的原理,在此处示例中无法使用 dataflow 最优化。例如,在较大的示例中,对位于顶层的所有循环和函数应用 dataflow 最优化,存储器置于每个顶层循环和函数之间。