在 CUDA 中使用寄存器内存

Ada*_*rsh 4 cuda

我有一些关于 cuda 寄存器内存的问题

1)有没有办法在cuda内核中释放寄存器?我在寄存器中有变量,一维和二维数组。(最大数组大小 48)

2)如果我使用设备函数,那么我在设备函数中使用的寄存器在执行后会发生什么?它们是否可用于调用内核执行或其他设备功能?

3) nvcc 如何优化寄存器使用?请分享内存密集型内核的重要wrt优化要点

PS:我有一个复杂的算法可以移植到 cuda,它需要大量的寄存器进行计算,我试图弄清楚是将中间数据存储在寄存器中并写入一个内核还是将其存储在全局内存中并在多个内核中中断算法.

Luc*_*aro 5

只有局部变量才有资格驻留在寄存器中(另请参阅在 CUDA 内核中声明变量)。您无法直接控制哪些变量(标量或静态数组)将驻留在寄存器中。编译器将做出自己的选择,在尊重寄存器备用的情况下争取性能。

可以使用maxrregcountnvcc 编译器的选项来限制寄存器的使用。

您还可以将大多数小的一维、二维数组放在共享内存中,或者,如果访问常量数据,则将此内容放入常量内存中(缓存非常接近注册为 L1 缓存内容)。

在 CUDA 中处理计算绑定内核时减少寄存器使用的另一种方法是分阶段处理数据,使用多个全局内核函数调用并将中间结果存储到全局内存中。每个内核将使用更少的寄存器,因此每个 SM 的更多活动线程将能够隐藏加载/存储数据移动。大多数情况下,这种技术与正确使用流和异步数据传输相结合是非常成功的。

关于设备函数的使用,我不确定,但我猜调用函数的寄存器内容将被移动/存储到本地内存(L1缓存左右),就像使用太多本地时发生寄存器溢出一样变量(请参阅CUDA 编程指南 -> 设备内存访问 -> 本地内存)。此操作将为被调用的设备函数释放一些寄存器。设备函数完成后,它们的局部变量不再存在,寄存器现在可以被调用函数再次使用,并填充以前保存的内容。

请记住,出于性能原因,在全局内核的同一源代码中定义的小型设备函数可能会被编译器内联:当发生这种情况时,生成的内核通常需要更多的寄存器。