我正在尝试为家庭作业实现 CUDA 中的绝对差异之和,但无法获得正确的结果。我得到一个 Blocksize,它代表我要比较的图像的正方形部分的 X 和 Y 大小(以像素为单位)。我还得到了两张 YUV 格式的图像。以下是我必须实现的程序部分:计算 SAD 的内核和线程网格/块大小的设置。提供了程序的其余部分,并且可以假定它们是正确的。
在这里,我获取当前线程的 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 作为总和。我究竟做错了什么?