增加实现的占用率不会线性地提高计算速度

时间:2013-12-02 22:21:13

标签: cuda gpu gpgpu computer-architecture kepler

我有一个CUDA程序,其中内核寄存器将最大理论实现占用率限制为%50。因此,我决定使用共享内存而不是寄存器来处理那些在块线程之间保持不变的变量,并且在整个内核运行期间几乎是只读的。我不能在这里提供源代码;我所做的事情在概念上是这样的:

我的初步计划:

__global__ void GPU_Kernel (...) {
    __shared__ int sharedData[N]; //N:maximum amount that doesn't limit maximum occupancy
    int r_1 = A; //except for this first initialization, these registers don't change anymore
    int r_2 = B;
    ...
    int r_m = Y;

    ...   //rest of kernel;
}

我将上述程序更改为:

__global__ void GPU_Kernel (...) {
    __shared__ int sharedData[N-m];
    __shared__ int r_1, r_2, ..., r_m;
    if ( threadIdx.x == 0 ) {
        r_1 = A;
        r_2 = B;
        ...
        r_m = Y; //last of them
    }
    __syncthreads();
    ...   //rest of kernel
}

现在块内的warp线程执行广播读取以访问新创建的共享内存变量。同时,线程不会使用太多寄存器来限制占用率。

第二个程序理论最大入住率等于%100。在实际运行中,第一个项目的平均入住率为〜%48,而第二个项目的入住率约为〜%80。但问题是净增速的提升在%5到%10左右,远低于我预期的考虑改善入住率。为什么这种相关性不是线性的?

考虑下面来自Nvidia白皮书的图片,我一直在想的是,当达到占用率为50%时,一半SMX(在较新的架构中)核心一次空闲,因为其他核心的过多请求资源停止他们不活跃。我的理解有缺陷吗?或者解释上述现象是不完整的?或者它是否添加__syncthreads();和共享内存访问费用?

enter image description here

1 个答案:

答案 0 :(得分:2)

  

为什么这种相关性不是线性的?

如果您已经有内存带宽限制或计算限制,并且这些边界中的任何一个接近设备的理论性能,那么改善占用率可能无济于事。提高占用率通常有助于这些因素对代码的性能有限(即,您没有达到或接近峰值内存带宽利用率或峰值计算)。由于您没有为您的程序提供任何代码或任何指标,因此没有人能够告诉您为什么它没有加快速度。分析工具可以帮助您找到性能的限制因素。

您可能对一对webinars感兴趣:

  

CUDA优化:由Paulius Micikevicius博士识别性能限制器

     

CUDA扭曲和占用注意事项+与Justin Luitjens博士一起生活,NVIDIA

特别是,请查看second webinar中的幻灯片10。