const * __restrict__可以增加cuda寄存器的使用吗?

时间:2015-07-10 15:18:18

标签: cuda cpu-registers restrict-qualifier

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

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

1 个答案:

答案 0 :(得分:6)

是的,它可以增加注册用量。

参考__restrict__的{​​{3}}:

  

这里的效果是减少了内存访问次数并减少了计算次数。这是由于"缓存"引起的注册压力增加而平衡的。加载和公共子表达式。

     

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

const __restrict__可能有益于至少两个原因:

  1. 在支持它的体系结构上,它可以使编译器发现programming guide的用途,这可能是一种性能增强功能。

  2. 如上面的链接编程指南部分所示,它可以使编译器能够进行其他优化(例如,减少指令和存储器访问),如果相应的寄存器压力不能提高性能,也可以提高性能成为一个问题

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

    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]; 
    

    需要3个寄存器。下一行代码:

      c[1] = a[0] * b[0]; 
    

    还需要3个寄存器,因为所有内容都是按写入方式生成的,所以它们可以是相同的3个寄存器,可以重复使用。对于示例的其余部分,可能会发生类似的寄存器重用,导致整体寄存器使用/压力较低。

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