cuda寄存器压力

标签 cuda

我有一个内核进行线性最小二乘拟合。事实证明,线程使用了太多寄存器,因此占用率很低。这是内核,

__global__
void strainAxialKernel(
    float* d_dis,
    float* d_str
){
    int i = threadIdx.x;
    float a = 0;
    float c = 0;
    float e = 0;
    float f = 0;
    int shift = (int)((float)(i*NEIGHBOURS)/(float)WINDOW_PER_LINE);
    int j;
    __shared__ float dis[WINDOW_PER_LINE];
    __shared__ float str[WINDOW_PER_LINE];

    // fetch data from global memory
    dis[i] = d_dis[blockIdx.x*WINDOW_PER_LINE+i];
    __syncthreads();

    // least square fit
    for (j=-shift; j<NEIGHBOURS-shift; j++)                                     
    {                                                                           
        a += j;                                                                 
        c += j*j;                                                               
        e += dis[i+j];                                                          
        f += (float(j))*dis[i+j];                                               
    }                                                                       
    str[i] = AMP*(a*e-NEIGHBOURS*f)/(a*a-NEIGHBOURS*c)/(float)BLOCK_SPACING;    

    // compensate attenuation
    if (COMPEN_EXP>0 && COMPEN_BASE>0)                                          
    {                                                                           
        str[i]                                                                  
        = (float)(str[i]*pow((float)i/(float)COMPEN_BASE+1.0f,COMPEN_EXP));     
    }   

    // write back to global memory
    if (!SIGN_PRESERVE && str[i]<0)                                             
    {                                                                           
        d_str[blockIdx.x*WINDOW_PER_LINE+i] = -str[i];                          
    }                                                                           
    else                                                                        
    {                                                                           
        d_str[blockIdx.x*WINDOW_PER_LINE+i] = str[i];                           
    }
}

我有 32x404 block ,每个 block 中有 96 个线程。在 GTS 250 上,SM 应能够处理 8 个 block 。然而,视觉分析器显示每个线程有 11 个寄存器,因此占用率为 0.625(每个 SM 5 个 block )。 BTW,每个 block 使用的共享内存是792 B,所以寄存器是问题所在。 演出并不是世界末日。我只是好奇是否有办法可以解决这个问题。谢谢。

最佳答案

快速但有限的寄存器/共享内存与缓慢但大的全局内存之间始终需要进行权衡。没有办法“绕过”这种权衡。如果您通过使用全局内存来减少寄存器的使用,您应该会获得更高的占用率,但内存访问速度会更慢。

也就是说,这里有一些使用更少寄存器的想法:

  1. 移位可以预先计算并存储在常量内存中吗?那么每个线程只需要查找shift[i]即可。
  2. a 和 c 必须是 float 吗?
  3. 或者,a 和 c 可以从循环中删除并计算一次吗?从而完全删除?

a 被计算为一个简单的算术序列,因此减少它......(类似这样)

a = ((NEIGHBORS-shift) - (-shift) + 1) * ((NEIGHBORS-shift) + (-shift)) / 2

a = (NEIGHBORS + 1) * ((NEIGHBORS - 2*shift)) / 2

因此,请执行以下操作(您可能可以进一步减少这些表达式):

str[i] = AMP*((NEIGHBORS + 1) * ((NEIGHBORS - 2*shift)) / 2*e-NEIGHBOURS*f)
str[i] /= ((NEIGHBORS + 1) * ((NEIGHBORS - 2*shift)) / 2*(NEIGHBORS + 1) * ((NEIGHBORS - 2*shift)) / 2-NEIGHBOURS*c)
str[i] /= (float)BLOCK_SPACING;

关于cuda寄存器压力,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4200230/

相关文章:

c++ - 我可以从不是由 nvcc 编译的 C++ 代码调用 CUDA 运行时函数吗?

cuda - 如何使用 Nvidia 多进程服务 (MPS) 运行多个非 MPI CUDA 应用程序?

在 CUDA 内核中执行后选择选定的元素

cuda - 安装 Cuda NVIDIA 图形驱动程序失败

c++ - 为什么 cudaMalloc() 不工作?

windows - 使用 LLVM/Clang 在 Win10 上使用 OpenMP 的 Cuda

memory - 了解内存传输性能 (CUDA)

algorithm - 使用 CUDA 并行冒泡排序

opencv - 如果我在我的内核函数中调用 OpenCV GPU 模块中的函数,它会工作并且更快吗?

c - 了解 CUDA 内核执行