我为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;
}
}
}
}
答案 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;
}
}
}