方案一
- 方案一 源码
1 |
|
- 方案一 kernel 设置

- 方案一 综合结果


- 方案一 HLS log 文件

- 方案一 Performance图





方案二(修改gmem位宽为64bit)
- 方案二 kernel 设置

- 为何为64bit?
首先,源码中对外层loop_1进行pipeline,因此对于内层的loop_2自动进行uroll展开。内层for循环的边界为J_CNT = 2因此将loop_2代码
展开为如下代码形式。因此需要对a和b进行两次读取,对a请求一次读入,对b请求一次读入。一拍只能对gmem请求一次,因为是并行执行因此a有两个数据a[i * J_CNT + 0]和a[i * J_CNT + 1]需要读入所以接口位宽为sizeof(int) * 2。
对于代码来说gmem位宽应该等于sizeof(int) * J_CNT
1 | // loop_2 uroll 展开过程 |
- 方案二 综合结果


- 方案二 HLS log文件

- 方案二 Performance图





方案二 II = 2 原因分析
- 修改源码,解决gmem ii = 2 问题(屏蔽掉b向arrayB赋值)
1 |
|
- 综合结果分析

- HLS log文件

- Performence图



- 为何源程序 II = 2?
该问题还要从loop_2 unroll说起
1 | // loop_2 uroll 展开过程 |
关键原因是一拍只能对gmem请求一次 因为是并行执行因此第一拍对gmem进行a的读请求,a有两个数据a[i * J_CNT + 0] 和a[i * J_CNT + 1]需要读入,同理下一拍对gmem进行b的请求,b有两个数据b[i * J_CNT + 0] 和b[i * J_CNT + 1]需要读入。
因此解决办法也不言而喻:一个gmem只能一次读请求,但是综合多个gmem便可以在一拍内分别进行请求!
方案三(解决 II = 2问题)
- 方案三 源码
1 |
|
- 方案三 设置

- 方案三 综合结果




- 方案三 HLS log文件

- 方案三 Performence图



总结
- 产生gmem carry dependency的两种解决办法:
- 进行 gmem位宽大小的调整 32bit – 512bit
- 多个 __global 参数采用多个gmem进行数据传输(max memory ports)
TODO 采用pipe传输(做一个memRead)
- 问题(当数据为非32bit的倍数-512bit)