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

OpenCL: 3D array processing - Globale size limit

我正在使用维度 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,我得到了预期的结果。如果有替代方案,请告诉我?

假设您提供的维度是数据的大小,您可以通过让每个 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};

还有第二个内核,你的每个线程都会执行更多的工作,从而提高利用率。

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 大小数组的指针,并让运行时选择一些东西(如果您的全局维度很容易被小数字整除,它会有所帮助)。