常数*能否限制增加cuda寄存器的使用?

常数*能否限制增加cuda寄存器的使用?,cuda,cpu-registers,restrict-qualifier,Cuda,Cpu Registers,Restrict Qualifier,因为我的指针都指向非重叠内存,所以我竭尽全力将传递给内核(及其内联函数)的指针替换为受限的,并尽可能使它们保持常量。然而,这增加了一些内核的寄存器使用,而减少了其他内核的寄存器使用。这对我来说没什么意义 有人知道为什么会这样吗?是的,它会增加寄存器的使用 请参阅用于限制的代码: 这里的效果是减少了内存访问次数和计算次数。这是由“缓存”加载和公共子表达式导致的寄存器压力增加来平衡的 由于寄存器压力在许多CUDA代码中是一个关键问题,由于占用率降低,使用受限指针可能会对CUDA代码的性能产生负面影响

因为我的指针都指向非重叠内存,所以我竭尽全力将传递给内核(及其内联函数)的指针替换为受限的,并尽可能使它们保持常量。然而,这增加了一些内核的寄存器使用,而减少了其他内核的寄存器使用。这对我来说没什么意义


有人知道为什么会这样吗?

是的,它会增加寄存器的使用

请参阅用于限制的代码:

这里的效果是减少了内存访问次数和计算次数。这是由“缓存”加载和公共子表达式导致的寄存器压力增加来平衡的

由于寄存器压力在许多CUDA代码中是一个关键问题,由于占用率降低,使用受限指针可能会对CUDA代码的性能产生负面影响

const\uuuuu restrict\uuuuu
至少有两个原因是有益的:

  • 在支持它的体系结构上,它可以使编译器发现对的使用,这可能是一种性能增强功能

  • 如上面链接的编程指南部分所述,它可以使编译器进行其他优化(例如,减少指令和内存访问),如果相应的寄存器压力没有成为问题,也可以提高性能

  • 减少指令和内存访问导致寄存器压力增加可能是不直观的。让我们考虑在上面的编程指南链接中给出的例子:

    void foo(const float* a, const float* b, float* c) { 
      c[0] = a[0] * b[0]; 
      c[1] = a[0] * b[0]; 
      c[2] = a[0] * b[0] * a[1]; 
      c[3] = a[0] * a[1]; 
      c[4] = a[0] * b[0]; 
      c[5] = b[0]; ... }
    
    如果我们在上面的例子中考虑了指针别名,那么编译器就不能进行很多优化,编译器本质上只能按照编写的代码执行代码。第一行代码:

      c[0] = a[0] * b[0]; 
    
      c[1] = a[0] * b[0]; 
    
    将需要3个寄存器。下一行代码:

      c[0] = a[0] * b[0]; 
    
      c[1] = a[0] * b[0]; 
    
    还需要3个寄存器,因为所有内容都是按写入方式生成的,所以它们可以是相同的3个寄存器,可以重复使用。在本示例的其余部分,可能会发生类似的寄存器重用,从而导致寄存器的总体使用率/压力较低


    但是如果我们允许编译器重新排序,那么我们必须为预先加载的每个值分配寄存器,并保留到该值失效为止。这种重新排序可能会增加寄存器的使用/压力,但最终可能导致更快的代码(或者,如果寄存器压力成为性能限制,则可能导致较慢的代码)。

    感谢您详细的回答。我想我应该在我的问题上更明确一些。事实上,它可以提高寄存器的使用率,您可以很好地解释这一点。但它又如何减少寄存器的使用呢?任何影响代码生成的因素都可以增加或减少寄存器的使用。