2012-11-27 93 views
0

创建线程的网格我写了针对OpenCL内核,我初始化一个三维阵列中的所有元素 - >我* I * I + J *∫*∫。我现在在创建一个线程网格来执行元素初始化(并发)时遇到了问题。我知道我现在使用的代码只使用3个线程,我该如何扩展?OpenCL中

请帮忙。我是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

它看起来像这样的代码通过甲在作为__global浮子*,然后redeclares它作为一个int数组,这是固有的私人。那是故意的吗? – boiler96

+0

嗨,除了隐藏锅炉96突出显示的'A'变量,为什么你说你只使用3个线程?你的工作组大小有3个维度(X,Y和Z),所以我怀疑你在调用代码中创建了多于3个线程(工作项目)。你想要什么尺寸的最终输出数组 - 2000x100x4或这些尺寸的倍数? –

+0

@ boiler96我认为这是我犯的一个错误,它应该是一个数组。你能帮助解决这个问题吗? –

回答

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; 
        } 
        } 
    } 
    
+1

只是一个相关的问题。如果“A”不是定义的矩阵,那么编译器如何知道每个维度的大小?我想知道A [i * 100 * 4 + j * 4 + k]是否是访问矩阵的正确方法。 – DarkZeros

+1

前两个项目符号是对这个问题的一个很好的回答,但我不同意你的最后一个项目符号。最好尽可能简单地编写代码,让工作组大小不定,然后让OpenCL SDK处理准备优化的代码。除非您正在考虑使用特定的硬件,并且已经将此代码标识为低效,否则我认为不需要像这样修改它。 – Oak

+0

@DarkZeros,+1好点,我已经添加了一个演员来迎合这个答案。另一种方法是按照您的建议使用一维数组,或许将尺寸作为参数传递给内核。 –