具有多个存储箱的OpenCL直方图

具有多个存储箱的OpenCL直方图,opencl,gpu,histogram,Opencl,Gpu,Histogram,我使用OpenCL编程指南第14章中的代码来计算直方图。它适用于256个存储箱,但不幸的是,我需要65536个存储箱用于我的应用程序。这导致了一个问题,如果我使用这种方法,本地数组会变得太大 local uint tmp_histogram[256 * 256]; 因此,程序未生成(CL_BUILD_program_FAILURE) 你对如何解决这个问题有什么想法吗?我考虑使用多个内核来计算不同存储单元的值(即分割直方图,以便首先计算存储单元0-255的值,然后计算存储单元256-511的值,

我使用OpenCL编程指南第14章中的代码来计算直方图。它适用于256个存储箱,但不幸的是,我需要65536个存储箱用于我的应用程序。这导致了一个问题,如果我使用这种方法,本地数组会变得太大

local uint tmp_histogram[256 * 256];
因此,程序未生成(CL_BUILD_program_FAILURE)


你对如何解决这个问题有什么想法吗?我考虑使用多个内核来计算不同存储单元的值(即分割直方图,以便首先计算存储单元0-255的值,然后计算存储单元256-511的值,等等)。但是,在这种情况下,我必须在递增之前检查值是否在该范围内,这意味着我需要条件…

将直方图移动到全局存储。 如果您的应用程序适合此大小,进一步的解决方案可能是使用unsignedshort。
最后,您可以运行代码两次。第一次用于较低的32000值,第二次用于上半部分

将直方图移动到全局存储。 如果您的应用程序适合此大小,进一步的解决方案可能是使用unsignedshort。
最后,您可以运行代码两次。第一次用于较低的32000值,第二次用于上半部分

将直方图移动到全局存储。 如果您的应用程序适合此大小,进一步的解决方案可能是使用unsignedshort。
最后,您可以运行代码两次。第一次用于较低的32000值,第二次用于上半部分

将直方图移动到全局存储。 如果您的应用程序适合此大小,进一步的解决方案可能是使用unsignedshort。
最后,您可以运行代码两次。第一次用于较低的32000值,第二次用于上半部分

使用全局内存可以解决这个问题,但不会产生非常快的内核。我建议创建多个工作组,并使用每个组仅计算一系列值

#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
}
定义范围大小8192
内核无效历史(uuu全局uint数据,uuu常量int数据大小){
int wid=获取本地id(0);
int wSize=获取本地大小(0);
int gid=get_group_id(0);
int numGroups=get_num_组(0);
int rangeStart=gid*范围大小/numGroups;
int rangeEnd=(gid+1)*范围大小/numGroups;
局部uint tmp_直方图[范围大小];
单位价值;
for(int i=wid;i=rangeStart&&value

假设32kb的本地内存可用。如果减小范围大小,它不必是2的幂,但需要确保调用内核时有足够的工作组,以达到64k以下的所有值。

使用全局内存可以解决问题,但不会产生非常快的内核。我建议创建多个工作组,并使用每个组仅计算一系列值

#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
}
定义范围大小8192
内核无效历史(uuu全局uint数据,uuu常量int数据大小){
int wid=获取本地id(0);
int wSize=获取本地大小(0);
int gid=get_group_id(0);
int numGroups=get_num_组(0);
int rangeStart=gid*范围大小/numGroups;
int rangeEnd=(gid+1)*范围大小/numGroups;
局部uint tmp_直方图[范围大小];
单位价值;
for(int i=wid;i=rangeStart&&value

假设32kb的本地内存可用。如果减小范围大小,它不必是2的幂,但需要确保调用内核时有足够的工作组,以达到64k以下的所有值。

使用全局内存可以解决问题,但不会产生非常快的内核。我建议创建多个工作组,并使用每个组仅计算一系列值

#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
}
定义范围大小8192
内核无效历史(uuu全局uint数据,uuu常量int数据大小){
int wid=获取本地id(0);
int wSize=获取本地大小(0);
int gid=get_group_id(0);
int numGroups=get_num_组(0);
int rangeStart=gid*范围大小/numGroups;
int rangeEnd=(gid+1)*范围大小/numGroups;
局部uint tmp_直方图[范围大小];
单位价值;
for(int i=wid;i=rangeStart&&value

假设32kb的本地内存可用。如果减小范围大小,它不必是2的幂,但需要确保调用内核时有足够的工作组,以达到64k以下的所有值。

使用全局内存可以解决问题,但不会产生非常快的内核。我建议创建多个工作组,并使用每个组仅计算一系列值

#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
}
定义范围大小8192
内核无效历史(uuu全局uint数据,uuu常量int数据大小){
int wid=获取本地id(0);
int wSize=获取本地大小(0);
int gid=get_group_id(0);
int numGroups=get_num_组(0);
int rangeStart=gid*范围大小/numGroups;
int rangeEnd=(gid+1)*范围大小/numGroups;
局部uint tmp_直方图[范围大小];
单位价值;
for(int i=wid;i=rangeStart&&value

假设32kb的本地内存可用。如果您减小范围大小,它不必是2的幂,但您需要确保调用内核时有足够的工作组来达到64k以下的所有值。

我同意这种方法。小尼