OpenCL:3D阵列处理-全局大小限制

OpenCL:3D阵列处理-全局大小限制,opencl,Opencl,我正在使用一个三维数组,它的维度xdim=49,ydim=1024,zdim=64。我的设备最大工作项大小仅为512/512/512。如果我申报 size\u t global\u work\u size={xdim,ydim,zdim}并启动一个3D内核 由于我的ydim>512,我得到了错误的结果。如果我的所有维度都低于512,我将得到预期的结果。请告诉我是否有替代方案?假设您提供的维度是数据的大小,您可以通过使每个GPU线程计算更多数据来减少全局工作大小。我的意思是,在你的例子中,每一个线

我正在使用一个三维数组,它的维度xdim=49,ydim=1024,zdim=64。我的设备最大工作项大小仅为512/512/512。如果我申报

size\u t global\u work\u size={xdim,ydim,zdim}
并启动一个3D内核


由于我的ydim>512,我得到了错误的结果。如果我的所有维度都低于512,我将得到预期的结果。请告诉我是否有替代方案?

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

假设您有一个要进行计算的数组,数组大小为2048。如果按照以下方式编写内核,则需要2048作为全局工作大小:

__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};
但是,如果将内核更改为以下内核,还可以降低全局工作大小:()


同样对于第二个内核,您的每个线程将执行更多的工作,从而提高利用率。

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

假设您有一个要进行计算的数组,数组大小为2048。如果按照以下方式编写内核,则需要2048作为全局工作大小:

__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};
但是,如果将内核更改为以下内核,还可以降低全局工作大小:()


同样对于第二个内核,每个线程将执行更多的工作,从而提高利用率。

CL\u设备\u MAX\u work\u ITEM\u大小仅限制工作组的大小,而不是全局工作项的大小(是的,这是一个可怕的常量名称)。您受到CL_DEVICE_MAX_WORK_GROUP_SIZE更严格的限制,这是工作组中允许的项目总数(由于乘法,您通常会比CL_DEVICE_MAX_WORK_ITEM_SIZE快很多)

因此,继续启动您的全局工作大小为49102464。它应该可以工作。如果不行,您使用的是
get\u local\u id
,而不是
get\u global\u id
,或者存在一些其他错误。我们定期启动具有4096 x 4096全局工作大小的2D内核

另见


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

CL\u设备\u最大工作\u项目大小仅限制工作组的大小,而不是全局工作项目大小(是的,这是一个可怕的常数名称)。CL\u设备\u最大工作\u项目大小是工作组中允许的项目总数,对您的限制要严格得多(由于乘法的缘故,你通常会比CL_设备_最大工作_项目_大小更快地达到这个值

因此,继续启动您的全局工作大小为49102464。它应该可以工作。如果不行,您使用的是
get\u local\u id
,而不是
get\u global\u id
,或者存在一些其他错误。我们定期启动具有4096 x 4096全局工作大小的2D内核

另见

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