1

我的程序的分析结果表明最大理论达到的占用率为 50%,限制器是寄存器。关于最小化 CUDA 代码中的寄存器数量的一般说明是什么?我看到分析结果显示寄存器的数量远远多于我的代码(每个线程)中的 32 位和 16 位变量的数量?可能是什么原因?

另外,将“maxregcount”设置为 32(32 * 2048(每个 SMX 的最大线程数)= 65536(每个 SMX 的最大寄存器数),解决了占用限制问题,但我没有得到太多的加速。“maxregcount”是否尝试优化代码比较多,这样使用寄存器就不会浪费了?还是干脆选择L1缓存或者本地内存进行寄存器溢出?

4

2 回答 2

3

根据此处给出的 nvidia 介绍。如果源超出寄存器限制Local Memory,则使用。值得花时间研究此演示文稿,因为它描述了提高性能的各种选项。正如 Vasily Volkov 在演示文稿中所说,入住率不是唯一的指标之一。

还要注意,

32(32 * 2048(每个 SMX 的最大线程数)= 65536(每个 SMX 的最大寄存器数)我觉得有点不对劲。

32 * 1024(每个块的寄存器)= 32768 < 65536(每个块的寄存器)。您仍然可以将每个线程的寄存器数量增加到 64 个。

于 2013-11-13T04:37:36.257 回答
3

maxrregcount 确实会导致编译器重新排列其对寄存器的使用,但它总是试图保持低寄存器计数。如果它不能保持在您施加的限制之下,它只会将其溢出到 L1、L2 和 DRAM。当您必须去 DRAM 获取溢出的局部变量时,它可能会挤出您的显式内存提取和/或导致您的内核成为“延迟绑定”——也就是说,计算在等待数据时被搁置回来。

在无限寄存器和 32 个寄存器之间选择一些东西可能会更好。由于上述原因,一些溢出和不完美的占用率通常比 100% 占用率的大量溢出要好。

作为旁注,您可以通过使用launch_bounds来限制特定内核(而不是整个文件)的 regs ,您可以在编程指南中阅读。

于 2013-11-13T15:49:00.273 回答