线程块与Streaming Multiprocessor(SM)寄存器数量的关联及计算疑问
关于GTX 1650寄存器计数的疑问解答
验证代码
你用于获取GPU寄存器信息的代码格式如下:
#include <stdio.h> #include <cuda_runtime.h> int main() { int deviceCount; cudaGetDeviceCount(&deviceCount); if (deviceCount == 0) { printf("No CUDA capable devices found!\n"); return 1; } cudaDeviceProp prop; cudaGetDeviceProperties(&prop, 0); printf("Device Name: %s\n", prop.name); printf("Regs Per Block: %d\n", prop.regsPerBlock); printf("Regs Per Multiprocessor: %d\n", prop.regsPerMultiprocessor); return 0; }
疑问1:为何regsPerBlock与regsPerMultiprocessor数值相同?
这是Turing架构(GTX 1650为SM 7.5)的硬件设计特性:
regsPerMultiprocessor代表每个SM的总寄存器容量,GTX 1650的每个SM确实拥有65536个32位寄存器。regsPerBlock是单个线程块能申请的最大寄存器数量,硬件允许一个线程块占用整个SM的所有寄存器。
你的假设存在偏差:SM可以同时运行多个线程块的前提是这些块的总寄存器占用不超过SM的总容量。如果某个线程块使用了全部65536个寄存器,该SM在这个块执行期间只能运行这一个块;但如果块的寄存器占用远低于上限(比如每个块只用几千个寄存器),SM就能同时调度多个块并行执行,充分利用硬件资源。
疑问2:不使用regsPerMultiprocessor参数时,如何计算SM寄存器数量?两者有何关联?
计算SM寄存器数量的替代方法:
- 架构规格推导:先获取GPU的计算能力(GTX 1650为7.5,对应Turing架构),查阅NVIDIA官方文档可知,Turing架构SM的固定寄存器容量为65536个。
- nvidia-smi计算:
- 执行以下命令获取GPU总寄存器数:
nvidia-smi --query-gpu=total_registers --format=csv,noheader - 执行以下命令获取SM数量:
nvidia-smi --query-gpu=multiprocessor_count --format=csv,noheader - 将总寄存器数除以SM数量,结果即为单个SM的寄存器容量。
- 执行以下命令获取GPU总寄存器数:
- CUDA属性查询:使用
cuDeviceGetAttribute函数,传入CU_DEVICE_ATTRIBUTE_REGISTERS_PER_MULTIPROCESSOR参数,本质是读取同一底层硬件数据,属于更细粒度的查询方式。
参数关联:
regsPerBlock是单个线程块的寄存器占用上限,它的取值不会超过regsPerMultiprocessor(线程块不可能占用比整个SM更多的寄存器)。- 对于Turing及后续多数现代架构,两者数值相等,意味着硬件允许线程块独占SM的全部寄存器;部分老架构可能限制
regsPerBlock低于SM总容量,但这种情况已较少见。
内容的提问来源于stack exchange,提问作者MaxiMaxi
相关产品推荐
相关产品推荐

