如何在CUDA中正确添加全局内存?

时间:2013-09-25 05:42:01

标签: cuda

我正在尝试在家庭作业中实施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的总和。我做错了什么?

2 个答案:

答案 0 :(得分:1)

您确实应该显示所有代码并识别您正在运行的GPU。至少调用内核并为GPU使用分配数据的部分。

  • 您是否正在对所有cuda API调用和内核调用进行适当的cuda error checking
  • 可能你的内核根本没有运行,因为你的内核 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