为啥CUDA会四舍五入线程使用的寄存器数量?

Posted

技术标签:

【中文标题】为啥CUDA会四舍五入线程使用的寄存器数量?【英文标题】:Why CUDA round up the number of registers used by thread?为什么CUDA会四舍五入线程使用的寄存器数量? 【发布时间】:2012-10-14 07:33:12 【问题描述】:

我正在分析一个内核,它在 GTX480 中每个线程使用 25 个寄存器和每个块 3568 字节的共享内存。内核配置为启动 16x16 线程,并且线程缓存首选项设置为共享。

根据 GTX480 的规格,该设备每个 SM 有 32768 个寄存器,因此可以同时运行 25 regs x 256 threads per block x 6 blocks per SM 块。

但是,Compute Visual Profiler 和 Cuda Occupancy Calculator 报告说,每个 SM 只有 4 个块处于活动状态。我想知道为什么只有 4 个块是活动的,而不是 5 个,正如我预期的那样。

我发现的原因是CUDA将使用的寄存器数量向上取整为26,在这种情况下,活动块的数量为4。

为什么 CUDA 会向上取整寄存器的数量?因为每个线程有 25 个寄存器,每个块有 256 个线程,所以每个 SM 最多可以有 5 个块,这显然是一个优势。

环境设置:

Device 0: "GeForce GTX 480"
CUDA Driver Version / Runtime Version          5.0 / 4.0
ptxas info: Compiling entry function '_Z13kernellS_PiS0_iiS0_' for 'sm_20'
ptxas info: Used 25 registers, 3568+0 bytes smem, 80 bytes cmem[0], 16 bytes cmem[2]
0 bytes stack frame, 0 bytes spill stores, 0 bytes spill loads
kernel config: 16x16 threads per block
kernel config: cudaFuncCachePreferShared

【问题讨论】:

我不是芯片设计人员之一,但我希望这可以节省芯片上的一些逻辑。 Nvidia 可能选择使用专用乘法器网络来寻址寄存器(而不是使用需要在内核启动时设置的偏移寄存器),在这种情况下,从乘法器中消除的每一位都可以节省相当多的逻辑和芯片空间。 tera 是对的,这就是硬件的工作原理。对于像这样的内核,您可能可以指定 -maxregcount=24,编译器将满足它所需的一切。 @ArchaeaSoftware 但这可能会将寄存器拆分到本地内存,或者至少这是我的预期。我已经用那个 regcount 编译了它,实际上只使用了 24 个寄存器,而且没有一个被拆分到本地内存。这是 nvcc 的神奇行为吗? 你会这么认为,但是 CUDA 的代码生成器知道溢出到本地内存真的很慢,所以如果你对寄存器计数施加限制,它将努力适应该限制而不会溢出。例如,它可能会去掉一个归纳变量并做一些额外的计算。 【参考方案1】:

您没有正确解释正在发生的事情。这里没有对每个线程的寄存器数量进行四舍五入,而是对 per warp 的寄存器数量进行了四舍五入。

您的 GPU 以每个 warp 为基础分配寄存器,寄存器“页面大小”为 64 个寄存器(请注意,我使用这个术语是松散的,我不知道精确的寄存器文件设计)。在您的情况下,warp 需要 25*32 = 800 个寄存器,必须四舍五入到最接近的“页面大小”64,每个 warp 有 832 个寄存器。每个块包含 8 个 warp(256 个线程),因此每个块需要 6656 个寄存器。这个内核的每个 SM 的最大块数是 32768 / 6656,向下舍入到最接近的整数,即。每个 SM 有 4 个区块,而不是您期望的 5 个。

所以非常简短的回答是寄存器文件分配粒度和页面大小决定了在这种情况下每个 SM 可以运行多少块。

【讨论】:

完全正确。占用计算器列出了寄存器分配单元大小(sm_20 为 64)和寄存器分配粒度(sm_20 为 per warp)。请注意,还有一个共享的内存分配单元大小。

以上是关于为啥CUDA会四舍五入线程使用的寄存器数量?的主要内容,如果未能解决你的问题,请参考以下文章

vue前端表格展示number类型太长数值四舍五入为啥

将string类型转换为decimal为啥会自动四舍五入

SQL中decimal和numeric为啥会自动四舍五入啊?我是想保留有小数的怎么办?

Java强制转换为啥没有四舍五入

ajax获取java后台的返回值,long的值为啥会四舍五入解决办法

json串向后台传递数值自动四舍五入的问题