【发布时间】:2016-02-28 19:26:07
【问题描述】:
我正在尝试在 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 作为总和。我做错了什么?
【问题讨论】:
-
“Blcoksize”和“block_size”有什么区别?命名看起来很混乱。一个是CUDA的thread-block大小,另一个是图像ROI的大小?
-
啊,对不起。这些是我们的教授在骨架实现中提供的名称。 Blocksize 是指我们在输入图像中求和的像素方块的 X/Y 大小。所以 Blocksize*Blocksize 是我们正在计算的盒子的大小。 block_size 指的是 CUDA 线程块的大小。
-
也许你应该给出完整的代码。我认为你必须检查你的块和线程配置。例如,对于 100x100 的图像,假设 Blocksize = 100,则 grid_sizeX = grid_sizeY = 50 和 block_sizeX = block_sizeY = 25,总线程数为 25*25*50*50 = 1562500(不等于 100x100)
标签: cuda