0

宿題のためにCUDAで絶対差の合計を実装しようとしていますが、正しい結果が得られません。比較する画像の正方形部分の X および Y サイズ (ピクセル単位) を表す Blocksize が与えられます。また、YUV 形式の 2 つの画像も提供されます。以下は、実装する必要があるプログラムの一部です。SA​​D を計算するカーネルと、スレッドのグリッド/ブロックのサイズの設定です。プログラムの残りの部分は提供されており、正しいと見なすことができます。

ここでは、現在のスレッドの x および y インデックスを取得し、それらを使用して、現在のスレッドで扱っている画像配列のピクセルを取得しています。次に、絶対差を計算し、すべてのスレッドが計算を完了するのを待ちます。次に、現在のスレッドが画像内のブロック内にある場合、衝突を回避するためにatomicAddを使用して絶対差がグローバルメモリの合計に追加されます書き込み中。

__global__ void gpuCounterKernel(pixel* cuda_curBlock, pixel* cuda_refBlock, uint32* cuda_SAD,  uint32 cuda_Blocksize)                                                                                                                  
 {                                                                                                                                                                                                                                                                                                                                                               
     int idx = blockIdx.x * blockDim.x + threadIdx.x;                                                                                                                                                                                    
     int idy = blockIdx.y * blockDim.y + threadIdx.y;                                                                                                                                                                                    
     int id = idx * cuda_Blocksize + idy;                                                                                                                                                                               
     int AD = abs( cuda_curBlock[id] - cuda_refBlock[id] );                                                                                                     
     __syncthreads();                                                                                                                                                                                 
     if( idx < cuda_Blocksize && idy < cuda_Blocksize ) {                                                                                                                                                                           
         atomicAdd( cuda_SAD, AD );                                                                                                                                                                                              
     }                                                                                                                                                                                                                                   
 }

そして、これは私がカーネルのグリッドとブロックを設定する方法です:

int grid_sizeX   = Blocksize/2;                                                                                                                                                                                                
int grid_sizeY   = Blocksize/2;                                                                                                                                                                                                     
int block_sizeX  = Blocksize/4;                                                                                                                                                                                                     
int block_sizeY  = Blocksize/4;
dim3 blocksInGrid(grid_sizeX, grid_sizeY);                                                                                                                                                                                     
dim3 threadsInBlock(block_sizeX, block_sizeY);                                                                                                                                                                              

指定されたプログラムは、CPU の SAD も計算し、GPU からの結果をその結果と比較して、正確性をチェックします。イメージ内の有効なブロック サイズは 1 ~ 1000 です。上記の私の解決策は 10-91 から正しい結果を得ていますが、91 を超えるものは合計として 0 を返します。私は何を間違っていますか?

4

2 に答える 2

1

グリッドとブロック サイズの設定が奇妙に見えます。

通常、次のような画像ピクセルの設定を使用します。

int imageROISize=1000;
dim3 threadInBlock(16,16);
dim3 blocksInGrid((imageROISize+15)/16, (imageROISize+15)/16);

ワークロードを CUDA スレッドに分散する方法の詳細については、cuda プログラミング ガイドの次のセクションを参照してください。

http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#thread-hierarchy

于 2013-09-25T06:06:54.937 に答える