CUDA 同期について質問があります。特に、if ステートメントでの同期について明確にする必要があります。つまり、ブロック内のスレッドの一部がヒットする if ステートメントのスコープに __syncthreads() を配置すると、どうなるでしょうか? 一部のスレッドは、同期点に到達しない他のスレッドを「永遠に」待機し続けると考えました。そこで、検査するサンプル コードをいくつか作成して実行しました。
__global__ void kernel(float* vett, int n)
{
int index = blockIdx.x*blockDim.x + threadIdx.x;
int gridSize = blockDim.x*gridDim.x;
while( index < n )
{
vett[index] = 2;
if(threadIdx.x < 10)
{
vett[index] = 100;
__syncthreads();
}
__syncthreads();
index += gridSize;
}
}
驚くべきことに、出力がかなり「正常」であることがわかりました (64 要素、ブロックサイズ 32)。
100 100 100 100 100 100 100 100 100 100 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
100 100 100 100 100 100 100 100 100 100 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
そこで、次のようにコードを少し変更しました。
__global__ void kernel(float* vett, int n)
{
int index = blockIdx.x*blockDim.x + threadIdx.x;
int gridSize = blockDim.x*gridDim.x;
while( index < n )
{
vett[index] = 2;
if(threadIdx.x < 10)
{
vett[index] = 100;
__syncthreads();
}
__syncthreads();
vett[index] = 3;
__syncthreads();
index += gridSize;
}
}
出力は次のとおりです。
3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
繰り返しますが、私は間違っていました。ベクトルの要素を変更した後、if ステートメント内のスレッドは待機状態のままであり、if スコープから出ることはないと考えていました。それで...何が起こったのか明確にしていただけますか?同期ポイントの後に取得するスレッドは、バリアで待機しているスレッドのブロックを解除しますか? 私の状況を再現する必要がある場合は、CUDA Toolkit 5.0 RC と SDK 4.2 を使用しました。よろしくお願いします。