0

3D 配列のすべての要素を -> i*i*i + j*j*j に初期化する OpenCL 用のカーネルを作成しました。現在、要素の初期化を行うためのスレッドのグリッドを作成する際に問題が発生しています (同時に)。私が今持っているコードは 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 のグローバル (1 次元) 作業サイズとカーネル内のループからより良いパフォーマンスが得られる可能性があります。

    __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 に答える