ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

深度解读 DeviceQuery:理解你的 GPU 硬件属性

2026/8/30 14:53:40 拓冰建站 浏览量
深度解读 DeviceQuery:理解你的 GPU 硬件属性 0. 序读本文前最好先有基本的 CUDA 编程基础对 GPU 的计算能力、内存、cache、warp、block、gride 等概念有所了解。Sample 代码可以从 vitamin-cuda: devideQuery 获取欢迎关注我的 vitamain-cuda 项目主要是手撕算子系列和教程.1. Device Query 输出以本人的RTX 5060显卡为例。cdsamples/deviceQuerybashrun.sh1.1 输出::1available devices CUDA Driver Version / Runtime Version13.1/12.9CUDA Capability Major/Minor version number:12.0Total amount of global memory:8151MBytes(8546484224bytes)(026)Multiprocessors,(128)CUDA Cores/MP:3328CUDA Cores GPU Max Clock rate:1455MHz(1.46GHz)Memory Clock rate:12001MHz Memory Bus Width:128-bit L2 Cache Size:33554432bytes Maximum Texture Dimension Size(x,y,z)1D(131072),2D(131072,65536),3D(16384,16384,16384)Maximum Layered 1D Texture Size,(num)layers1D(32768),2048layers Maximum Layered 2D Texture Size,(num)layers2D(32768,32768),2048layers Total amount of constant memory:65536bytes Total amount of shared memory per block:49152bytes Total shared memory per multiprocessor:102400bytes Total number of registers available per block:65536Warp size:32Maximum number of threads per multiprocessor:1536Maximum number of threads per block:1024Max dimension size of a thread block(x,y,z):(1024,1024,64)Max dimension size of a grid size(x,y,z):(2147483647,65535,65535)Maximum memory pitch:2147483647bytes Texture alignment:512bytes Concurrent copy and kernel execution: Yes with1copy engine(s)Runtimelimit on kernels: Yes Integrated GPU sharing Host Memory: No Supporthostpage-locked memory mapping: Yes Alignment requirementforSurfaces: Yes Device has ECC support: Disabled Device supports Unified Addressing(UVA): Yes Device supports Managed Memory: Yes Device supports Compute Preemption: Yes Supports Cooperative Kernel Launch: Yes Supports MultiDevice Co-op Kernel Launch: No Device PCI Domain ID / Bus ID / location ID:0/1/0Compute Mode:Default(multiplehostthreads can use ::CUDASetDevice()with device simultaneously)2. 详细解读这是一张 RTX 5060虽然参数都在上面列着但对于开发者来说更重要的是理解这些数字背后的性能瓶颈和优化方向。2.1 基本架构CUDA 驱动版本 / 运行时版本13.1 / 12.9CUDA 算力兼容版本号 (Compute Capability)12.0 (Blackwell 架构架构决定了支持的指令集。通常高版本架构意味着更好的低精度计算性能Blackwell 架构原生支持 FP4, FP8, BF16, INT8 等低精度计算非常适合大模型推理量化。2.2 核心算力和并发能力流处理器 (SM) 数量26 个每个流处理器的 CUDA 核心数128 个即每个 SM 真实并行的线程数为 128总 CUDA 核心数3328 个 (26 * 128)这意味着硬件层面同时真实执行的线程数最多 3328 个编程建议虽然物理核心只有 3k 多但我们由 GPU 的设计哲学掩盖延迟决定了我们必须发射远超这个数量的线程。Grid 设置Kernel 的线程组 (Block) 数量最好是 SM 数 (26) 的整数倍且最好有几百个以上的 Block这样调度器才能充分轮转 Block 以隐藏延迟。每个 SM 最多驻留线程数1536每个 block 最大线程数1024Occupancy 占用率 计算如果设为 1024 线程/Block一个 SM 只能跑 1 个 Block1024 1536但跑 2 个就超了。利用率 1024/1536 ≈ 66%如果设为 512 线程/Block一个 SM 可以跑 3 个 Block。利用率 1536/1536 100%甜点位 (Sweet Spot)通常 128 或 256 是比较通用的 Block Size容易凑出高利用率。这个大小能比较平衡地分配寄存器/共享内存资源。当然在极致优化时需要具体分析Occupancy Calculator 算一下整卡活跃线程上限1536 * 26 39,936 个2.3 时钟频率GPU 最大频率1455 MHz (1.46 GHz)约 0.5ns 执行一个最简单的指令 如 FADD)。对比 CPU我的 Ultra 9 285H 主频高达 2.9GHz。单看频率再加上 CPU 的分支预测和乱序执行能力等等GPU 跑串行逻辑就是“垃圾中的战斗机”。设计哲学GPU 讲究**“三个臭皮匠顶个诸葛亮”**。它不追求单线程极速而是追求几万个线程 (39,936 个 同时推进。编程建议绝对不要在 Kernel 里写复杂的串行逻辑或深层 if/else 嵌套。显存频率12001 MHz这个频率是等效频率实际频率计算比较复杂涉及 Command Clock, Write Clock, Double Data Rate 等我们开发时只需关注它计算出的带宽吞吐。Latency vs Throughput这个频率高不代表延迟低单次显存读取的延迟可能高达几百个 GPU 时钟周期所以 CUDA 程序往往都是 Memory Bound尤其这张卡优化的核心永远是掩盖这些延迟。2.4 内存子系统性能瓶颈之源总显存大小8GB显存位宽128 bits位宽很小了等效频率也不高作为对比参考A100 5120 bits12840可以计算出显存带宽 120012*128/8 384000MB /s ≈ 384G/s我们的 kernel 大概率是带宽瓶颈而如果 kernel 在处理大规模数据里带宽吞吐达不到这个量级说明还有提升空间更何况还有 L2 cache 提速现状128-bit 位宽非常窄这意味这块卡的 Kernel 极大概率是带宽瓶颈。合并访问 (Coalescing)虽然物理显存有 Burst Size但从 CUDA 核心视角看Global Memory 访问的最小粒度是 32 字节 (Sector)。正面案例32 个线程正好读取连续的 128 字节 如 float)合并为 4 个 Sector 事务。反面案例如果只读 1 个字节或者跨步读取总线依然要搬运整个 32 字节 Sector导致带宽浪费。编程建议必须保障相邻线程读写地址的连续性即程序的空间局部性尽量使用向量化读写 (float4) 来减少指令发射量提高指令并行度。L2 缓存大小32MB重要性L2 Cache 也是以 32B Sector 为管理单位通常 Cache Line 为 128B。空间局部性L2 是全卡共享的且速度比显存快得多。编程时应利用**“空间局部性 (Spatial Locality)”**让同一个 Warp 的线程读取相邻数据最大化 L2 命中率。对于 5060 这类显存位宽小的卡32MB 的大 L2 是救命稻草。总的常量内存65536 bytes (64KB)常量内存是只读的所有线程共享用于存储常量数据比如权重等。常量内存的访问速度比全局内存快因为常量内存有专门的缓存。2.5 资源限制和 Occupancy占用率每个 SM 最大共享内存 (Shared Memory)100 KB每个 Block 共享内存限制48 KB坑点如果你一个 Block 申请了 48KB Shared Mem那么一个 SM 最多只能跑 2 个 Block (48*2 100)这可能导致 SM 没跑满降低 Occupancy。每个 Block 寄存器文件 (Register File)65536 个除了共享内存限制每个线程可以使用的寄存器数量也是有限的如果一个线程使用了过多的寄存器会导致 活跃线程数/block 数减少影响 occupancy寄存器溢出 (Register Spill)除了 Shared Memory寄存器也是稀缺资源。如果单线程使用的寄存器过多会导致 SM 能并行的 Block 数量减少严重后果如果寄存器彻底不够用编译器会把变量“溢出”到 Local Memory。注意Local Memory 物理上是显存速度极慢会严重拖垮流水线Bank Conflict共享内存被划分为 32 个 Bank。这已经讲烂了总而言之就是一个 warp 线程访问共享内存时多个线程不能同时访问同一个 bank 的不同地址数据否则会变成串行的多次访问共享内存的 bank id 归属是每 4 字节 (32bits) 顺序归属的即连续的 0…310…31 这样建议最简单的方法是让相邻线程访问相邻地址 (tid 对应 data[tid])这样天然无冲突。当然有时为了复杂的任务分发而进行下标变换会进行交错访问那就要很小心地避免冲突了2.6 调度和物理限制warp size32warp 是 gpu 调度的最小单位每个 warp 包含 32 个线程这些线程必须同时执行相同的指令这是 gpu 并行计算的基础指定的线程组 block 大小为比如 256 个他们是每 32 个一组一组的被调度到 SM 上运行Warp Divergence这个也要讲烂了因为是 SIMT model如果有 if/else 分支那么两个分支都串行执行只是在对应阶段会屏蔽条件外的线程。block 的最大 shape (x,y,z): (1024, 1024, 64)是的block 的纬度是有大小限制的毕竟上面也写了每个 block 最多 1024 个线程多维只是为了在特别情况下索引数据方便多维读取和理解grid 的最大 shape (x,y,z): (2147483647, 65535, 65535)一般来说可以放心无脑地用单个数字作为 grid爆 int 除外除非数据特别适合多维索引那么可以改用多维 grid最大内存 pitch2147483647 bytes定义二维显存时单行内存最大 stride 不能爆 int纹理内存地址对齐512 bytes纹理内存地址必须对齐到 512 字节这是为了提高纹理内存的访问效率Async Copy支持 Copy Engine 和 Compute Engine 并行双流水线这是实现计算与传输重叠 (Overlap) 的硬件基础。剩下的就没什么好说的了3. 最终建议小结Block Size: 常用 128 或 256且 Grid Size 至少要是 SM 数26的几倍甚至几十倍。访存访存铁律延迟隐藏不要怕线程多利用海量线程切换来掩盖内存延迟。资源管理盯着 Shared Memory 和 Register 用量防止 Occupancy 暴跌或寄存器溢出到显存。以上是自己对 GPU 架构和 CUDA 编程的一些理解希望对大家有所帮助。欢迎批评指正欢迎关注我的 vitamain-cuda 项目主要是手撕算子系列和教程vitamin-cuda本文首发于个人博客欢迎关注深度解读 DeviceQuery理解你的 GPU 硬件属性