具有许多 bin 的 OpenCL 直方图
OpenCL histogram with many bins
我正在使用 OpenCL 编程指南第 14 章中提供的代码来计算直方图。它适用于 256 个箱子,但不幸的是我的应用程序需要 65536 个箱子。这会导致问题,如果我使用这种方法,本地数组会变得太大。
local uint tmp_histogram[256 * 256];
因此,程序未构建 (CL_BUILD_PROGRAM_FAILURE)。
您知道如何解决这个问题吗?我考虑过使用多个内核来计算不同 bin 的值(即拆分直方图,以便我首先计算 bin 0-255 的值,然后计算 256-511 等)。但是,在这种情况下,我必须在递增之前检查值是否在该范围内,这意味着我将需要条件...
将您的直方图移至全局存储。
如果您的应用程序适合这种大小,另一种解决方案可能是使用 unsigned short。
最后你可以 运行 你的代码两次。第一次为较低的 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
}
假设有 32kb 的本地内存可用。如果你减少 RANGE_SIZE,它不必是 2 的幂,但你确实需要确保你调用内核有足够的工作组来命中所有高达 64k 的值。
我正在使用 OpenCL 编程指南第 14 章中提供的代码来计算直方图。它适用于 256 个箱子,但不幸的是我的应用程序需要 65536 个箱子。这会导致问题,如果我使用这种方法,本地数组会变得太大。
local uint tmp_histogram[256 * 256];
因此,程序未构建 (CL_BUILD_PROGRAM_FAILURE)。
您知道如何解决这个问题吗?我考虑过使用多个内核来计算不同 bin 的值(即拆分直方图,以便我首先计算 bin 0-255 的值,然后计算 256-511 等)。但是,在这种情况下,我必须在递增之前检查值是否在该范围内,这意味着我将需要条件...
将您的直方图移至全局存储。 如果您的应用程序适合这种大小,另一种解决方案可能是使用 unsigned short。 最后你可以 运行 你的代码两次。第一次为较低的 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
}
假设有 32kb 的本地内存可用。如果你减少 RANGE_SIZE,它不必是 2 的幂,但你确实需要确保你调用内核有足够的工作组来命中所有高达 64k 的值。