0

我为 OpenCL 编写了一个内核,将 3D 数组的所有元素初始化为 -> i*i*i + j*j*j。我现在在创建线程网格来初始化元素(同时)时遇到问题。我知道我现在的代码只使用了 3 个线程,我该如何扩展呢?

请帮忙。我是 OpenCL 的新手,所以任何建议或解释都可能很方便。谢谢!

这是代码:

_kernel void initialize (
int X;
int Y;
int Z;
_global float*A) {

// Get global position in X direction
int dirX = get_global_id(0);
// Get global position in Y direction
int dirY = get_global_id(1);
// Get global position in Z direction
int dirZ = get_global_id(2);

int A[2000][100][4];
int i,j,k;
for (i=0;i<2000;i++)
{
    for (j=0;j<100;j++)
    {
        for (k=0;k<4;k++)
        {
            A[dirX*X+i][dirY*Y+j][dirZ*Z+k] = i*i*i + j*j*j;
        }
    }
}
}
4

1 回答 1

0
  • 您创建缓冲区以将输出“A”存储在调用(主机)代码中。这作为指针传递给您的内核,这在您上面的函数定义中是正确的。但是,您不需要在内核函数中再次声明它,因此请删除int A[2000][100][4];.

  • 您可以大大简化代码。使用 3D 全局 ID 来指示每个工作项的数组中的 3D 索引,您可以按如下方式更改循环(假设对于给定的 i 和 j,沿 Z 的所有元素应该具有相同的值):

    __kernel void initialize (__global float* A) {
      // cast required so that kernel compiler knows the array dimensions
      __global float (*a)[2000][100][4] = A;
    
      // Get global position in X direction
      int i = get_global_id(0);
      // Get global position in Y direction
      int j = get_global_id(1);
      // Get global position in Z direction
      int k = get_global_id(2);
    
      (*a)[i][j][k] = i*i*i + j*j*j;
    }
    

然后,在您的调用代码中,您将创建全局工作大小为 2000x100x4 的内核。

  • 实际上,这是要安排的很多工作项,因此您可能会从 2000 的全局(一维)工作大小和内核内部的循环中获得更好的性能,例如:

    __kernel void initialize (__global float* A) {
      // cast required so that kernel compiler knows the array dimensions
      __global float (*a)[2000][100][4] = A;
    
      // Get global position in X direction
      int i = get_global_id(0);
    
      for (j=0;j<100;j++) {
        for (k=0;k<4;k++) {
          (*a)[i][j][k] = i*i*i + j*j*j;
        }
      }
    }
    
于 2012-11-27T20:23:58.363 回答