2

3D ブロックで構成される 3D グリッドがあります。カーネルが呼び出されるたびに、各座標の個々のスレッド インデックスを計算したいと考えています。私はこれらのパラメータを持っています:

dim3 blocks_query(32,32,32);
dim3 threads_query(32,32,32);
kernel<<< blocks_query,threads_query >>>();

カーネル内で、x、y、z 座標の個々の値を計算したいと考えています。たとえば、x=0、y=0、z=0、x=0、y=0、z=1、x=0、y です。 =0,z=2,....よろしくお願いします....

4

1 に答える 1

2

個々のスレッド インデックス (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 データの寸法がxDimyDimおよび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、カーネル内に次の行を追加します。yDimzDim

if(x>=xDim || y>=yDim || z>=zDim) return;
于 2013-07-19T17:04:47.750 に答える