占用率降低 - 性能更佳

时间:2013-04-10 18:28:29

标签: performance cuda

以下一直困扰着我。

使用两个不同的设备运行相同的内核,一个具有计算能力1.3,另一个具有计算能力2.0,我在1.3中获得了更好的性能,每个块的更多线程(高占用率),但在2.0中相反。 2.0的性能峰值似乎是每块16个线程,占用率为17%。任何比此更低或更高的性能都会有最差的性能。

因为这很可能是因为它本身就是内核本身的本质所在。

__global__ void
kernel_CalculateRFCH (int xstart, int ystart, int xsize,
          int ysize, int imxsize, int imysize, int *test, int *dev_binIm, int *per_block_results)
{
  int x2, y2, bin, bin2;
  __shared__ int s_pixels[blockDim.x*blockDim.y];  //this wouldn't compile in reailty

  int tx = threadIdx.x;
  int ty = threadIdx.y;
  int tidy = threadIdx.y + blockIdx.y * blockDim.y;
  int tidx = threadIdx.x + blockIdx.x * blockDim.x;

  if (xstart + xsize > imxsize)
    xsize = imxsize - xstart;
  if (ystart + ysize > imysize)
    ysize = imysize - ystart;

  s_pixels[tx * blockDim.y + ty] = 0;

  if (tidy >= ystart && tidy < ysize + ystart && tidx >= xstart && tidx < xsize + xstart)
{
      bin = dev_binIm[tidx + tidy * imxsize];

      if (bin >= 0)
    {
      x2 = tidx;
      y2 = tidy;

         while (y2 < ystart + ysize)
          {
          if (x2 >= xstart + xsize || x2 - tidx > 10)
             {
                  x2 = xstart;
                  y2++;
                  if (tidx - x2 > 10)
                   x2 = tidx - 10;
                  if (y2 - tidy > 10)
                   {
                      y2 = ystart + ysize;
                      break;
                   }
                   if (y2 >= ystart + ysize)
                      break;
              }

          bin2 = dev_binIm[x2 + y2 * imxsize];

           if (bin2 >= 0)
              {
               test[(tidx + tidy * imxsize) * 221 + s_pixels[tx * blockDim.y + ty]] = bin + bin2 * 80;
               s_pixels[tx * blockDim.y + ty]++;
              }
          x2++;
        }           
     }          

  } 

  for (int offset = (blockDim.x * blockDim.y) / 2; offset > 0; offset >>= 1)
    {
     if ((tx * blockDim.y + ty) < offset)
       {
         s_pixels[tx * blockDim.y + ty] += s_pixels[tx * blockDim.y + ty + offset];
       }
      __syncthreads ();
     }

   if (tx * blockDim.y + ty == 0)
     {
        per_block_results[blockIdx.x * gridDim.y + blockIdx.y] = s_pixels[0];

     }

}

我使用2-D线程。

ptxas info:为'sm_10'编译入口函数'_Z20kernel_CalculateRFCHiiiiiiPiS_' ptxas info:使用16个寄存器,128个字节的smem,8个字节的cmem [1]

每个设备都会显示16个寄存器。

为什么会发生这种情况的任何想法都会非常有启发性。

1 个答案:

答案 0 :(得分:1)

除了上面的一般性评论之外,你的内核是一个非常特殊的情况,因为大多数线程根本不做任何工作。为什么不立即将xstartystart添加到tidxtidy并选择较小的网格?在较小的块尺寸下,您的更好表现可能只是将感兴趣区域分成块的假象。

这也解释了为什么您看到计算能力1.x设备与CC 2.0+设备之间存在巨大差异。从CC 2.0开始,Nvidia GPU在处理内核方面变得更好,运行时块之间的运行时间差异很大 在计算能力1.x上,只有当所有当前运行的块都已完成时,才会安排新的块浪潮,而在任何旧块完成后立即启动新块上的CC 2.0。