0

私はそのようなばかげた問題に行き詰まっていると思います。これは、atomicAdd の動作を確認するためのテスト カーネルです。

__global__
void pixelcount_kernel(unsigned int * d_count,
                      const size_t numElems)
{ 
int myId = threadIdx.x + blockDim.x * blockIdx.x;
//avoid out of boundary access
if(myId > (numElems-1))
{return;
}

unsigned int inc=1;
atomicAdd(d_count, inc);
//debug code
printf("d_count: %d \n", *d_count);   
}

これは、メモリ割り当て、初期化、およびカーネル呼び出しです。

unsigned int* d_count;
checkCudaErrors(cudaMalloc(&d_count, sizeof(unsigned int)));
checkCudaErrors(cudaMemset(d_count, 0, sizeof(unsigned int)));
pixelcount_kernel<<<gridSize, blockSize>>>( d_count, 10);

出力では、0 から numElems (この呼び出しでは 10) までの増分は見られませんが、これは次のとおりです。

d_count: 10 
d_count: 10 
d_count: 10 
d_count: 10 
d_count: 10 
d_count: 10 
d_count: 10 
d_count: 10 
d_count: 10 
d_count: 10

どうしたの?ありがとうジュゼッペ

4

1 に答える 1

3

この出力に問題はありません。d_countカーネル起動のさまざまなスレッドが並行して実行されるため、最初のスレッドが printf() に到達するまでにすべてのスレッドがインクリメントされていることは完全に正当です。

実際、少なくとも 10 のブロックサイズでコードを実行している場合、10 個のスレッドすべてが同じワープの一部であり、同じ命令を同時に実行することが確実です。

d_countインクリメントを表示したい場合(たとえば、参加している各スレッドに一意の ID を与えたい場合)、代わりに次のコードを使用します。

unsigned int my_d_count = atomicAdd(d_count, inc);
printf("d_count before atomic increment: %d \n", my_d_count); 
于 2013-06-04T09:16:39.097 に答える