我想在radeon HD 7970 Tahiti XT上使用OpenCL(来自此AMD link)执行关于两阶段减少的运行时基准测试。
最初,我使用了第一个版本的代码,其中我没有使用第一个循环,它执行从大小为N
的输入数组到大小为NworkItems
的输出数组的减少。这是内核代码的第一个循环:
int global_index = get_global_id(0);
float accumulator = 0;
// Loop sequentially over chunks of input vector
while (global_index < length) {
float element = buffer[global_index];
accumulator += element;
global_index += get_global_size(0);
}
因此,对于第一个版本,我已将运行时测量为输入数组大小(等于线程总数)和不同大小的工作组的函数。结果如下:
现在,我想做一个基准测试,我在上面使用这个初始循环。但我不知道我必须改变哪些参数。
来自this link,有人说AMD推荐工作组大小为64的倍数(NVIDIA为32)。
此外,从this other link的上一条评论开始,建议将工作组大小设置为:WorkGroup size = (Number of total threads) / (Compute Units)
。
在我的GPU卡上,我有32个计算单元。
所以我想知道哪些参数会有所变化,以便比较第二个版本中的运行时(第一个减少循环)。例如,我可能会为比率(N size of input array) / (total NworkItems)
和WorkGroup size
的固定值采用不同的值(请参阅上面的表达式),
或者相反,即我应该改变WorkGroup size
的值并确定比率(N size of input array) / (total NworkItems)
?
欢迎任何想法,谢谢
答案 0 :(得分:2)
您应该对本地数据求和,而不是分散数据,以帮助进行内存传输(合并数据访问)。所以请改用它:
int chunk_size = length/get_global_size(0)+(length%get_global_size(0) > 0); //Will give how many items each work item needs to process
int global_index = get_group_id(0)*get_local_size(0)*chunk_size + get_local_id(0); //Start at this address for this work item
float accumulator = 0;
for(int i=0; i<chunk_size; i++)
// Loop sequentially over chunks of input vector
if (global_index < length) {
float element = buffer[global_index];
accumulator += element;
global_index += get_local_size(0);
}
}
此外,您应该使用2的幂大小来帮助缓存。