個々のスレッド インデックス (x、y、z 座標) は、次のようにカーネル内で計算できます。
int x = blockIdx.x * blockDim.x + threadIdx.x;
int y = blockIdx.y * blockDim.y + threadIdx.y;
int z = blockIdx.z * blockDim.z + threadIdx.z;
ブロックあたりのスレッド数は GPU によって制限されることに注意してください。したがって、作成したブロック サイズは無効です。
dim3 threads_query(32,32,32)
ブロックあたり 32768 スレッドに相当し、現在の CUDA デバイスではサポートされていません。現在、コンピューティング機能 2.0 以上の GPU ではブロックあたり最大 1024 スレッドがサポートされていますが、古い GPU では最大 512 スレッドがサポートされています。ブロック サイズを小さくする必要があります。そうしないと、カーネルが起動しません。もう 1 つ注目すべき点は、Compute 2.0 以降の CUDA GPU でのみサポートされる 3D グリッドを作成していることです。
アップデート
3D データの寸法がxDim
、yDim
およびzDim
であるとすると、スレッド ブロックの一般的なグリッドは次のように形成できます。
dim3 threads_query(8,8,8);
dim3 blocks_query;
blocks_query.x = (xDim + threads_query.x - 1)/threads_query.x;
blocks_query.y = (yDim + threads_query.y - 1)/threads_query.y;
blocks_query.z = (zDim + threads_query.z - 1)/threads_query.z;
上記のアプローチでは、合計データ サイズ以上のスレッドの合計数が作成されます。余分なスレッドにより、無効なメモリ アクセスが発生する可能性があります。そのため、カーネル内で境界チェックを実行します。これを行うには、とをカーネル引数として渡しxDim
、カーネル内に次の行を追加します。yDim
zDim
if(x>=xDim || y>=yDim || z>=zDim) return;