我正在尝试在家庭作业中实施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的总和。我做错了什么?
答案 0 :(得分:1)
您确实应该显示所有代码并识别您正在运行的GPU。至少调用内核并为GPU使用分配数据的部分。
可能你的内核根本没有运行,因为你的内核
threadsInBlock
参数总共超过512个线程。您表明在Blocksize
= 92及以上时,事情无效。我们来算一算:
92/4 = 23 threads in X and Y dimensions
23 * 23 = 529 total threads requested per threadblock
529超过512这是cc 1.x设备的限制,因此我猜你在cc 1.x设备上运行,因此你的内核启动失败,所以你的内核没有运行,并且所以你得不到计算结果(即0)。请注意,在91和4 = X和Y维度的22个线程中,您要求{4}}总共484个线程。
如果您正在进行适当的cuda错误检查,错误报告会将注意力集中在由于启动参数不正确而导致cuda内核启动失败。
答案 1 :(得分: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