我正在使用OpenCL Progamming Guide第14章中提供的代码来计算直方图。它适用于256个垃圾箱,但不幸的是我的应用程序需要65536个垃圾箱。这导致了一个问题,即如果我使用这种方法,本地数组会变得太大。
local uint tmp_histogram[256 * 256];
因此,程序未构建(CL_BUILD_PROGRAM_FAILURE)。
您有什么想法可以解决这个问题吗?我想过使用多个内核来计算不同分档的值(即分割直方图,这样我首先计算分箱0-255的值,然后是256-511等的值)。但是,在这种情况下,我必须在递增之前检查一个值是否在该范围内,这意味着我将需要条件...
答案 0 :(得分:2)
使用全局内存可以解决问题,但不会导致内核速度非常快。我建议创建多个工作组,并使用每个组来计算一系列值。
#define RANGE_SIZE 8192
kernel void histo(__global uint data,__constant int dataSize){
int wid = get_local_id(0);
int wSize = get_local_size(0);
int gid = get_group_id(0);
int numGroups = get_num_groups(0);
int rangeStart = gid * RANGE_SIZE / numGroups;
int rangeEnd = (gid+1) * RANGE_SIZE / numGroups;
local uint tmp_histogram[RANGE_SIZE];
uint value;
for(int i=wid; i< dataSize; i+= wSize){
value = data[i];
if(value >= rangeStart && value < rangeEnd){
atomic_inc(tmp_histogram[value - rangeStart]);
}
}
//barrier...
//use the local data here
}
假设有32kb本地内存可用。如果你减少RANGE_SIZE,它不一定是2的幂,但是你需要确保用足够的工作组调用内核来达到最高64k的所有值。
答案 1 :(得分:1)
将直方图移动到全局存储。 如果您的应用程序适合此大小,则可以使用unsigned short。 最后你可以运行你的代码两次。第一次为低32000值,第二次为上半部分。