具有许多箱的OpenCL直方图

时间:2015-01-14 15:58:41

标签: opencl gpu histogram

我正在使用OpenCL Progamming Guide第14章中提供的代码来计算直方图。它适用于256个垃圾箱,但不幸的是我的应用程序需要65536个垃圾箱。这导致了一个问题,即如果我使用这种方法,本地数组会变得太大。

local uint tmp_histogram[256 * 256];

因此,程序未构建(CL_BUILD_PROGRAM_FAILURE)。

您有什么想法可以解决这个问题吗?我想过使用多个内核来计算不同分档的值(即分割直方图,这样我首先计算分箱0-255的值,然后是256-511等的值)。但是,在这种情况下,我必须在递增之前检查一个值是否在该范围内,这意味着我将需要条件...

2 个答案:

答案 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值,第二次为上半部分。