常数*能否限制增加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个寄存器,可以重复使用。在本示例的其余部分,可能会发生类似的寄存器重用,从而导致寄存器的总体使用率/压力较低
但是如果我们允许编译器重新排序,那么我们必须为预先加载的每个值分配寄存器,并保留到该值失效为止。这种重新排序可能会增加寄存器的使用/压力,但最终可能导致更快的代码(或者,如果寄存器压力成为性能限制,则可能导致较慢的代码)。感谢您详细的回答。我想我应该在我的问题上更明确一些。事实上,它可以提高寄存器的使用率,您可以很好地解释这一点。但它又如何减少寄存器的使用呢?任何影响代码生成的因素都可以增加或减少寄存器的使用。