OpenCL:3D数组处理 - 全局大小限制

时间:2017-08-22 03:19:24

标签: opencl

我正在使用尺寸xdim = 49,ydim = 1024和zdim = 64的3D数组。我的DEVICE_MAX_WORK_ITEM_SIZES只有512/512/512。如果我宣布我的

size_t global_work_size = {xdim, ydim, zdim};并启动3D内核

自从我的ydim>我收到错误的结果512.如果我的所有尺寸都低于512,我就会得到预期的结果。如果有替代方法,请告诉我吗?

2 个答案:

答案 0 :(得分:1)

假设您提供的维度是数据的大小,您可以通过使每个GPU线程计算更多数据来减少全局工作量。我的意思是,你的案例中的每个线程都会进行一次计算,如果你改变你的内核,让我们说y维度中的2个计算,那么你可以将你发射的线程数减少一半。 global_work_size决定您正在执行的每个方向上的线程数。让我举个例子:

假设您有一个想要进行计算的数组,并且您拥有的数组大小为2048.如果您按以下方式编写内核,则需要2048作为global_work_size:

__kernel void calc (__global int *A, __global int *B)
{
  int i = get_global_id(0);
  B[i] = A[i] * 5;
}

本案例中的全球工作规模为:

size_t global_work_size = {2048, 1, 1};

但是,如果将内核更改为以下内核,也可以降低全局工作量:()

__kernel void new_calc (__global int *A, __global int *B)
{
  int i = get_global_id(0);
  for (int ind = 0; ind < 8; ind++)
    B[i*8 + ind] = A[i*8 + ind] * 5;
} 

然后这样,你可以使用全局大小:

size_t global_work_size = {256, 1, 1};

同样使用第二个内核,每个线程都会执行更多工作,从而提高利用率。

答案 1 :(得分:1)

CL_DEVICE_MAX_WORK_ITEM_SIZES仅限制工作组的大小,而不是全局工作项大小(是的,它是常量的可怕名称)。 CL_DEVICE_MAX_WORK_GROUP_SIZE受到更严格的限制,这是工作组中允许的项目总数(由于乘法,您通常比CL_DEVICE_MAX_WORK_ITEM_SIZES要快得多。

所以继续推出你的全球工作规模49,1024,64。它应该有效。如果不是,则您使用get_local_id代替get_global_id或者有其他错误。我们定期推出具有4096 x 4096全局工作大小的2D内核。

另见Questions about global and local work size

如果您不使用共享本地内存,则无需担心本地工作组的大小。实际上,您可以传递NULL而不是指向local_work_size大小数组的指针,并让运行时选择一些东西(如果您的全局维度可以被小数字整除,则会有所帮助。)