我有一个算法,在GPU上执行两阶段并行缩减以找到字符串中最小的元素。我知道如何让它更快地工作,但我不知道它是什么。有关如何调整此内核以加快我的程序的任何想法?没有必要实际改变算法,可能还有其他技巧。欢迎所有的想法。
谢谢!
__kernel
void reduce(__global float* buffer,
__local float* scratch,
__const int length,
__global float* result) {
int global_index = get_global_id(0);
float accumulator = INFINITY
while (global_index < length) {
float element = buffer[global_index];
accumulator = (accumulator < element) ? accumulator : element;
global_index += get_global_size(0);
}
int local_index = get_local_id(0);
scratch[local_index] = accumulator;
barrier(CLK_LOCAL_MEM_FENCE);
for(int offset = get_local_size(0) / 2;
offset > 0;
offset = offset / 2) {
if (local_index < offset) {
float other = scratch[local_index + offset];
float mine = scratch[local_index];
scratch[local_index] = (mine < other) ? mine : other;
}
barrier(CLK_LOCAL_MEM_FENCE);
}
if (local_index == 0) {
result[get_group_id(0)] = scratch[0];
}
}
答案 0 :(得分:0)
accumulator = (accumulator < element) ? accumulator : element;
使用fmin函数 - 它正是您所需要的,它可能会导致更快的代码(调用内置指令,如果可用,而不是昂贵的分支)
global_index += get_global_size(0);
您的典型get_global_size(0)
是什么?
虽然您的访问模式不是很糟糕(它是合并的,但是32-warp的128字节块) - 最好尽可能顺序访问内存。例如,顺序访问可以帮助memory prefetching(注意,OpenCL
代码可以在任何设备上执行,包括CPU。)
考虑以下方案:每个线程将处理范围
[ get_global_id(0)*delta , (get_global_id(0)+1)*delta )
这将导致完全顺序访问。