【问题标题】:Is there a guideline about register and local memory in cuda programing?cuda编程中是否有关于寄存器和本地内存的指南?
【发布时间】:2022-11-23 09:43:04
【问题描述】:

寄存器的数量在 gpu 中是有限的,例如A100。每个线程不能使用超过 255 个寄存器。

但在我的测试中,即使不超过 255,编译器也会使用本地内存而不是寄存器。关于如何将我的数据保存在寄存器中以及何时将其保存在本地内存中,是否有更详细的指南?

我尝试在我的内核中定义一个本地数组。看起来数组 len 会影响编译器的操作。

template<int len>
global void test(){
// ...
float arr[len];
// ...
}

【问题讨论】:

  • 为防止将本地内存用于数组,请改用共享内存或在循环之前使用“#pragma unpack”或手动展开循环或使用 Boost 预处理器取消循环代码。也许你可以重新设计你的算法,这样它就不需要本地数组,例如每个线程处理一个数组元素,而不是一个线程循环处理一个数组。
  • @Sebastian 是#pragma unroll,不是“解包”。如果循环的长度在编译时可见,则 CUDA 编译器已经非常积极地展开,所以通常它不再有任何区别。
  • @Sebastian 是的,你是对的。其实我可以使用共享内存。但是我想使用寄存器来提高内核的性能(寄存器比共享内存快)。
  • @paleonix 你是对的,unroll,对不起。我体验过当前编译器的代码,它不会自动展开,所以值得一试。也许阿尔文,你可以更详细一点,如何访问数组以提供更具体的建议,如何防止使用本地内存。

标签: cuda gpu-local-memory


【解决方案1】:

如果编译时常量索引未访问本地数组,则本地数组将放置在本地内存中。

这在编程指南第 5.3.2 段本地内存中有描述。 https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#device-memory-accesses

本地内存访问仅发生在变量内存空间说明符中提到的某些自动变量。编译器可能放置在本地内存中的自动变量是:

  • 无法确定其索引为常量的数组,
  • 会占用过多寄存器空间的大型结构或数组,
  • 如果内核使用的寄存器多于可用的寄存器(这也称为寄存器溢出),则为任何变量。

【讨论】:

  • 非常感谢。这就是我需要的。作为第二项描述,我测试了 arr[32],它会在寄存器中,arr[33] 会在本地内存中。 guildeline甚至只说“消耗太多寄存器空间”,没有给出详细数字。通过寄存器替换共享内存来优化内核似乎不是一个好主意,因为很难控制编译器的动作。
  • @Alvin 通常 32 个寄存器不应该太多。我成功地处理了总和 > 100 个 4 字节元素的本地数组而没有溢出。你设置的是哪个架构? A100 8.0 还是保持默认?使用 arr[33] 的非常短的内核也会发生这种情况吗?您是否指定了 maxrregcount 或 __launch_bounds?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-11-01
  • 2011-11-06
  • 2023-04-03
  • 2021-11-16
  • 1970-01-01
  • 2012-01-21
  • 1970-01-01
相关资源
最近更新 更多