运行 在许多 GPU 线程上使用相同的 for 循环,使用 OpenCL

Running the same for loop on many GPU threads, using OpenCL

我需要从许多其他不同的二维数组中减去一个二维数组 D。我已经线性化(扁平化)了所有数组:D 是一个 25 元素数组,imges 是一个一维数组,其中 4 个 25 元素数组被连接在一起。意思是:如果我想从 4 个 5x5 数组中减去 D,我只需将这些 5x5 数组中的每一个变成一个 25 元素数组,然后附加这 4 个数组。这就是 imgs 的意思,在本例中它将是一个包含 100 个元素的数组。我相信我在我的内核中正确地捕获了它,索引方式。

想到做减法的唯一方法是 运行 一个 for 循环,这样 D 中的每个元素都会从数组中减去相应的线程。我的想法是,这将按如下方式工作:

  1. 每个线程都会收到要减去的 D 数组,以及必须从中减去 D 的数组之一(在我的示例中,1/4 imges)

  2. 我将使用 for 循环遍历两个数组的元素,逐个元素进行减法

但是,它没有按预期工作:似乎只是选择了 D 的最后一个或第一个值,然后从其他数组的所有元素中减去。

我以为我对索引和线程在 GPU 上的工作方式很了解,但现在我不太确定,因为这一直在挑战我一段时间。内核在下面。

有没有比 for 循环更好的方法?非常感谢。

__kernel void reduce(__global float* D, __global float* imges, __global float* res)
{
    const int x = (int)get_global_id(0);
    const int y = (int)get_global_id(1);
    const int z = (int)get_global_id(2);

    int im_i = imges[x+25]; //Images are 5x5 meaning a 25-size array

   for(int j = 0; j < 25; j++){
       res[x+25] = im_i - D[j];
   }
}

编辑: 我不想并行化 for 循环本身,因为数组可能会变大,我不想 运行 陷入开销的麻烦。

如果我正确理解您的尝试,您的内核应该看起来更像这样:

__kernel void reduce(__global float* D, __global float* imges, __global float* res)
{
  const int x = (int)get_global_id(0);

  for(int j = 0; j < 25; j++){
    res[x*25 + j] = imges[x*25 + j] - D[j];
  }
}

此内核将从 imges 中每个工作项的 25 元素数组的第 j 个元素中减去 D 的第 j 个元素。