三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

HLS高层次综合设计技巧--任务有条件的执行阻碍dataflow最优化

HLS高层次综合设计技巧--任务有条件的执行阻碍dataflow最优化

一、dataflow最优化不会对有条件的任务执行最优化
void foo(int data_in1[N], int data_out[N], int sel) {
int temp1[N], temp2[N];
if (sel) {
Loop1: for(int i = 0; i < N; i++) {
temp1[i] = data_in[i] * 123;
temp2[i] = data_in[i];
}
} else {
Loop2: for(int j = 0; j < N; j++) {
temp1[j] = data_in[j] * 321;
temp2[j] = data_in[j];
}
}
Loop3: for(int k = 0; k < N; k++) {
data_out[k] = temp1[k] * temp2[k];
}
}

这个代码是没办法进行dataflow的,因为sel阻碍了dataflow最优化。
为什么呢?
dataflow中,生产者产生的东西给消费者用,这样一对一的方式,才能dataflow最优化。
也就是生产者生产的东西,消费者能立即消耗掉。
HLS综合工具需要在编译阶段就确认前后两个循环之间的数据流关系,HLS 工具必须明确知道生产者是谁以及消费者是谁,从而在它们之间建立固定的数据流通道(如 FIFO)。

二、sel引入后的情况
1.sel选择后,sel什么时候为高电平,什么时候是低电平,这个完全不确定,不通的sel拉高拉低,那么情况不一样;
2.基于这种情况,HLS综合工具压根没办法玩,那么怎么办呢?HLS综合工具会保守的退化为,将sel的分支的for循环全部执行完成,
之后再执行Loop3,从而,造成了dataflow的破坏。

三、剖析底层逻辑
1.数据源不确定性:DATAFLOW 优化的本质是将任务(循环/函数)像流水线一样并行执行,前一个任务产生数据,后一个任务立即消费。这要求在编译阶段(静态分析时),HLS 工具必须明确知道生产者是谁以及消费者是谁,从而在它们之间建立固定的数据流通道(如 FIFO)。
2.无法建立静态通道:由于 sel 是一个运行时变量,HLS 工具在编译时无法确定 Loop3 的数据究竟是来自 Loop1 还是 Loop2。
3.因为无法在生产者(Loop1 或 Loop2)与消费者(Loop3)之间建立一条固定的、点对点的数据流链路,HLS 只能采取保守策略,放弃并行化。程序必须串行执行:先判断 sel 的值,完整地执行完选中的分支循环(Loop1 或 Loop2),等待全部数据写入 temp1 和 temp2 后,才能开始执行 Loop3。


四、如何修改
void foo(int data_in[N], int data_out[N], int sel) {
int temp1[N], temp2[N];
Loop1: for(int i = 0; i < N; i++) {
if (sel) {
temp1[i] = data_in[i] * 123;
} else {
temp1[i] = data_in[i] * 321;
}
}
Loop2: for(int j = 0; j < N; j++) {
temp2[j] = data_in[j];
}
Loop3: for(int k = 0; k < N; k++) {
data_out[k] = temp1[k] * temp2[k];
}
}
这个代码解决了不能dataflow的问题。

← 返回列表