在OpenCL中创建线程网格

时间:2012-11-27 18:35:42

标签: concurrency opencl

我为OpenCL编写了一个内核,我将3D数组的所有元素初始化为 - >我* 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;
        }
    }
}
}

1 个答案:

答案 0 :(得分: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;
        }
      }
    }