目錄
1. 簡介
2. 基礎 kernel
2.1 pass kernel
2.2?double_pass kernel
2.3?add_kernel
2.4 split kernel
3. 三種bypass
3.1 input_bypass
3.2 middle_bypass
3.3 output_bypass
4. 總結
1. 簡介
本文展示三個在數據流水線中常見的問題:
- 輸入參數繞過了第一個函數,導致數據流水線性能下降。
- 數據流內部的通道不是前饋的,繞過了任務,導致性能下降。
- 數據流通道輸出沒有正確處理,導致性能下降。
2. 基礎 kernel
首先引入四個通用 HLS kernel 函數作為后續演示的基礎:
2.1 pass kernel
void pass(int a[128], int tmp1[128]) {for (int i = 0; i < 128; i++) {tmp1[i] = a[i];}
}
參數1 -> 參數2
2.2?double_pass kernel
void double_pass(int b[128], int tmp2[128], int tmp1[128], int tmp4[128]) {for (int i = 0; i < 128; i++) {tmp2[i] = b[i];tmp4[i] = tmp1[i];}
}
參數1 -> 參數2
參數3 -> 參數4
2.3?add_kernel
void add_kernel(int tmp1[128], int tmp2[128], int tmp3[128]) {for (int i = 0; i < 128; i++) {tmp3[i] = tmp1[i] + tmp2[i];}
}
參數1 + 參數2 -> 參數3
2.4 split kernel
void split(int a[128], int tmp1[128], int tmp2[128]) {for (int i = 0; i < 128; i++) {tmp1[i] = a[i];tmp2[i] = a[i];}
}
參數1 -> 參數2
參數1 -> 參數3
?
3. 三種bypass
3.1 input_bypass
void dut(int a[128], int b[128], int tmp3[128]) {
#pragma HLS DATAFLOWint tmp1[128], tmp2[128], tmp4[128];pass(a, tmp1);double_pass(b, tmp2, tmp1, tmp4);add_kernel(tmp4, tmp2, tmp3);
}
優化后:
void dut(int a[128], int b[128], int tmp3[128]) {
#pragma HLS DATAFLOWint tmp1[128], tmp2[128], tmp4[128];int tmp5[128];pass(a, b, tmp1, tmp2);Double_pass(tmp2, tmp1, tmp4, tmp5);add_kernel(tmp4, tmp5, tmp3);
}
對比:?
a -> tmp1 -> tmp4+ --> tmp3b -> tmp2
a -> tmp1 -> tmp4+ --> tmp3
b -> tmp2 -> tmp5
3.2 middle_bypass
void dut(int a[128], int b[128], int tmp3[128]) {
#pragma HLS DATAFLOWint tmp1[128], tmp2[128], tmp4[128];double_pass(a, b, tmp1, tmp2);pass(tmp2, tmp4);bypass(tmp1, tmp4, tmp3);
}
優化后:
void dut(int a[128], int b[128], int tmp3[128]) {
#pragma HLS DATAFLOWint tmp1[128], tmp2[128], tmp4[128], tmp5[128];double_pass(a, b, tmp1, tmp2);pass(tmp2, tmp4, tmp1, tmp5);bypass(tmp5, tmp4, tmp3);
}
對比:
a -> tmp1 ------>+ --> tmp3
b -> tmp2 -> tmp4
a -> tmp1 -> tmp5+ --> tmp3
b -> tmp2 -> tmp4
3.3 output_bypass
void dut(int a[128], int b[128], int tmp2[128]) {
#pragma HLS DATAFLOWint tmp1[128], tmp3[128];split(a, tmp1, tmp2);pass(tmp1, b);
}
優化后:?
void dut(int a[128], int b[128], int tmp2[128]) {
#pragma HLS DATAFLOWint tmp1[128], tmp3[128];split(a, tmp1, tmp3);pass(tmp3, tmp2, tmp1, b);
}
?對比:
a -> tmp1 -> b
a -> tmp2
a -> tmp1 -> b
a -> tmp3 -> tmp2
4. 總結
本文展示了在數據流水線中常見的三個輸入參數繞過問題及其解決方案。通過引入四個基礎的HLS kernel函數:pass、double_pass、add_kernel和split,演示了input_bypass、middle_bypass和output_bypass三種問題的具體情形及優化后的解決方案。優化后的代碼通過重新排列數據流通道,使得數據流遵循前饋路徑,提高了性能。