cuda - 为什么 CUDA 对线程使用的寄存器数量进行四舍五入?

标签 cuda nvidia

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

根据GTX480的规范,设备每个SM有32768个寄存器,所以可能有25 regs x 256 threads per block x 6 blocks per SM block 并发运行。

但是,Compute Visual Profiler 和 Cuda Occupancy Calculator 报告每个 SM 只有 4 个 block 处于事件状态。我想知道为什么只有 4 个 block 处于事件状态,而不是我预期的 5 个。

我发现的原因是CUDA将使用的寄存器数量四舍五入为26,在这种情况下,事件 block 的数量为4。

为什么 CUDA 对寄存器的数量进行四舍五入?因为每个线程有 25 个寄存器和每个 block 有 256 个线程,所以每个 SM 可能有多达 5 个 block ,这显然是一个优势。

环境设置:

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

最佳答案

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

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

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

关于cuda - 为什么 CUDA 对线程使用的寄存器数量进行四舍五入?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13046193/

相关文章:

c++ - 如何比较 CUDA C++ 中的 char 数组?

c - Nvidia CUDA - 通过指针传递结构

tensorflow - 在 Tensorflow 中测量 GPU 内存使用情况的最佳方法是什么

compilation - 为Linux编译CUDA SDK V4.1.28?

CUDA 神经网络仿真

c - 我如何计算 block 号

Matlab GPU计算

c++ - 我可以在 CUDA 设备上为包含 float 数组的对象分配内存吗?

sorting - 推力:sort_by_key 与 zip_iterator 性能

c++ - CUDA 内核自动调用内核完成 vector 加法。为什么?