GPU内部每个线程的寄存器数量是如何决定的?我想看看GPU是否每个SM有65536个寄存器,可以在线程之间分配,这些寄存器是否都分配给SM上运行的活动线程块?现在,我有一个CUDA程序,每个线程块有1024个线程,每个块有65536个可用寄存器。我的困惑是,分析器说每个线程只能得到40个寄存器。另一个观察结果是每个线程实际上在其汇编代码中使用了正好64个寄存器,这意味着如果分配了这个数量的线程,性能可能会更好。为什么它没有得到64个寄存器?谁做这个决定?是在编译时根据计算能力还是运行时决定的,等等?
编辑:下面是示例代码及其汇编。我查看代码末尾的%f64来总结上面的观点。https://godbolt.org/z/eMzW8dY19
1条答案
按热度按时间jckbn6z71#
GPU内部如何决定每个线程的寄存器数量?
实际(非PTX虚拟)寄存器分配是在代码上运行
ptxas
工具(nvcc
编译器驱动程序工具链的一部分)时确定的,或者是作为驱动程序API加载程序或NVRTC机制一部分的等效工具。ptxas是将PTX转换为SASS(机器码)的工具。SASS是实际运行在GPU上的东西,PTX不是。PTX必须首先转换为SASS。
PTX和PTX中的虚拟寄存器系统对理解这些概念没有帮助。PTX中可以定义的虚拟寄存器的数量基本上没有限制,PTX中定义的虚拟寄存器的数量根本没有告诉你实际寄存器将如何在GPU硬件中使用。PTX对这类研究没有帮助。
寄存器分配在这里完全是静态确定的。当你的
nvcc
编译命令指定了一个有效的SASS目标时,你可以通过传递-Xptxas=-v
编译开关到nvcc
来得到一些证据。没有运行时的可变性(忽略通过CUDA JIT PTX-〉SASS转换机制产生的“可变性”;这里关注的项目是SASS而不是PTX。2一旦定义了SASS,就没有运行时可变性了。这些寄存器是否都被分配给在SM上运行的活动线程块?
分配的寄存器数量将由每个线程的寄存器、某些粒度/舍入效果以及每个线程块的线程数量确定(即,这些的乘积)。在线程块被“存放”在SM上的点处,寄存器的这个数量将从SM中可用的总数中“分出”,CUDA工作分配器(CWD或CUDA块调度器)。CWD不会存款块,直到有足够数量的寄存器可供分配。
寄存器的整个补码(如65536或任何SM容量)不会自动或始终分配给单个线程块。这将取决于该线程块的实际需求。如果CWD决定在该SM上存款另一个线程块,则可以在将来使用剩余/未分配的寄存器。CUDA SM能够同时支持多个线程块,除非未分配寄存器的数量足以满足预期线程块的需要,否则CWD不会在该SM上存款新线程块。
我的困惑是,分析器说每个线程只得到40个寄存器。另一个观察结果是,每个线程实际上在其汇编代码中使用了正好64个寄存器,
探查器报告的数字是正确的(并且它包括粒度/舍入效果,
-Xptxas=-v
输出中可能包括也可能不包括这些效果)。您的困惑在于您试图通过PTX了解正在发生的情况。不要这样做。它与本讨论无关。