最小化每个线程的寄存器+“maxregcount”效果

时间:2013-11-13 04:15:05

标签: cuda gpgpu nvidia

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

另外,设置" maxregcount"到32(32 * 2048(每个SMX的最大线程数)= 65536(每个SMX的最大寄存器数),解决了占用限制问题,但我没有太多的加速。是" maxregcount"尝试更多地优化代码,因此在使用寄存器时不会浪费?或者它只是选择L1缓存或本地存储器来进行寄存器溢出?

2 个答案:

答案 0 :(得分:3)

根据here给出的nvidia的介绍。如果源超过寄存器限制Local Memory。值得花时间研究这个演示文稿,因为它描述了提高性能的各种选项。正如瓦西里·沃尔科夫在this中所说,占用率是其中一个指标而不是唯一的指标。

另请注意,

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

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

答案 1 :(得分:3)

maxrregcount确实会导致编译器重新安排其对寄存器的使用,但它总是试图将寄存器计数保持在低位。如果它不能低于你强加的限制,它只会将它溢出到L1,L2和DRAM。当您必须转到DRAM来获取溢出的局部变量时,它可以挤出显式内存提取和/或导致内核变为“延迟限制” - 也就是说,在等待数据的同时计算被阻止回来。

你可能有更好的运气选择无限登记和32之间的东西。由于上面给出的原因,通常一些溢出和不完美的占用会导致大量溢出100%占用。

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