增加块大小会降低性能

时间:2011-02-19 04:35:46

标签: cuda


在我的cuda代码中,如果我增加blocksizeX,则blockizeY实际上花费更多的时间。[因此我在1x1运行它]我的执行时间的一大块(例如9秒中的7个)仅通过调用kernel .Infact我很惊讶,即使我注释掉整个内核的时间几乎是一样的。任何建议在哪里以及如何优化?

P.S。我已经用我的实际代码编辑了这篇文章。我正在对一个图像进行下采样,所以每4个相邻像素(例如,对于例如来自行1的1,2和来自行2的1,2)给出输出像素。我得到了有效的bw。 5GB / s与理论最大值86.4 GB / s相比。我使用的时间是调用内核与指令和调用空内核的区别。 我现在看起来很糟糕,但我无法弄清楚我做错了什么。

 __global__ void streamkernel(int *r_d,int *g_d,int *b_d,int height ,int width,int *f_r,int *f_g,int *f_b){


    int id=blockIdx.x * blockDim.x*blockDim.y+ threadIdx.y*blockDim.x+threadIdx.x+blockIdx.y*gridDim.x*blockDim.x*blockDim.y;
    int number=2*(id%(width/2))+(id/(width/2))*width*2;

     if (id<height*width/4)
    {

        f_r[id]=(r_d[number]+r_d[number+1];+r_d[number+width];+r_d[number+width+1];)/4;                              
        f_g[id]=(g_d[number]+g_d[number+1]+g_d[number+width]+g_d[number+width+1])/4;             
        f_b[id]=(g_d[number]+g_d[number+1]+g_d[number+width]+g_d[number+width+1];)/4;  
    }


  }

2 个答案:

答案 0 :(得分:2)

尝试在CUDA SDK示例中查找矩阵乘法示例,了解如何使用共享内存。

当前内核的问题在于它为每3个添加和1个分区执行4次全局内存读取和1次全局内存写入。每次全局内存访问大约需要400个周期。这意味着你花了绝大部分时间进行内存访问(GPU不好),而不是计算(GPU擅长什么)。

共享内存实际上允许您对此进行缓存以便分摊,在每个像素处获得大约1次读取和1次写入,以进行3次加法和1次除法。 CGMA比率(计算到全球内存访问率,GPU计算的圣杯)仍然没有那么好。

总的来说,我认为对于像这样的简单内核,考虑到通过PCI-E总线传输数据的开销,CPU实现可能会更快。

答案 1 :(得分:0)

您忘记了一个多处理器可以同时执行多达8个块的事实,然后就可以达到最大性能。但是,有许多因素会限制并行存在的块数(不完整列表):

  • 每个多处理器的最大共享内存量限制了每个块的#blocks *共享内存的块数>总共享内存。
  • 如果#blocks * #threads / block将是&gt;,则每个多处理器的最大线程数限制了块数。最大总数#threads。
  • ...

您应该尝试找到一个内核执行配置,该配置只能在一个多处理器上运行8个块。即使占用率= / = 1.0,这几乎总能产生最高性能!从这一点开始,您可以尝试迭代地进行更改,以减少每个MP执行块的数量,但因此可以增加内核的占用率,并查看性能是否会提高。

nvidia occupancy calculator(excel sheet)会有很大的帮助。