NVIDIA GPU 中的 SM、Warp 与 Occupancy

NVIDIA GPU 中的 SM、Warp 与 Occupancy

更新日期:2026-10-10

数据口径:表中 SM 数量均指具体产品对 CUDA 暴露的、实际启用的 SM 数量;多 GPU 模组按"每颗 GPU"统计,除非另有说明。

1. CUDA 的执行层次

NVIDIA GPU 的 CUDA 执行层次如下:

text 复制代码
GPU
└── 多个 SM(Streaming Multiprocessor)
    └── 一个或多个驻留的 Thread Block / CTA
        └── 多个 Warp
            └── 32 个 Thread

各层含义如下:

  • Thread:CUDA 的逻辑执行实例。每个线程具有自己的线程编号、寄存器状态、地址和分支状态。
  • Warp :NVIDIA GPU 的基本 SIMT 执行组,固定包含 32 个线程。
  • Thread Block / CTA:能够使用 Shared Memory 和组内同步进行协作的一组线程。一个 Block 在整个执行期间驻留在同一个 SM 上。
  • SM:负责创建、管理、调度和执行 Warp 的物理计算单元。一个 SM 内通常包含 Warp Scheduler、寄存器文件、Shared Memory/L1、Load/Store 单元、标量/浮点执行单元和 Tensor Core 等资源;具体组成随架构变化。
  • GPU:由多个 SM、L2 Cache、显存控制器和片上互连等单元构成。

2. Thread Block 与 Warp 的换算

一个 Warp 固定包含 32 个线程。一个 Thread Block 包含的 Warp 数量为:

text 复制代码
每个 Block 的 Warp 数
= ceil(每个 Block 的线程数 / 32)

示例:

每个 Block 的线程数 形成的 Warp 数 说明
128 4 每个 Warp 都有 32 个有效线程
256 8 每个 Warp 都有 32 个有效线程
300 10 前 9 个 Warp 完整,最后一个 Warp 只有 12 个有效线程
512 16 每个 Warp 都有 32 个有效线程
1024 32 CUDA Block 的常见线程数上限

线程数不是 32 的整数倍时,最后一个 Warp 仍按完整 Warp 分配执行资源,超出 Block 线程范围的 Lane 保持非活动状态。

3. SM 与 Warp 的关系

一个 SM 可以同时保存多个 Warp 的执行上下文,包括程序计数器、寄存器状态和其他调度状态。这些 Warp 称为驻留 Warp(Resident Warp)。

text 复制代码
一个 SM
├── Resident Warp 0
├── Resident Warp 1
├── Resident Warp 2
├── ...
└── Resident Warp N

驻留并不表示所有 Warp 在同一个时钟周期同时执行。Warp 可以处于以下状态:

  • Resident / Active:执行资源已经分配,Warp 已驻留在 SM 上。
  • Eligible / Ready:下一条指令的操作数和执行条件已经满足,可以被调度。
  • Issued:Warp Scheduler 在当前发射时机选择该 Warp,并向其活动线程发射指令。
  • Stalled:Warp 正在等待内存、数据依赖、Barrier、Fence 或其他资源。

Warp Scheduler 从就绪 Warp 中选择指令发射。当一个 Warp 等待高延迟操作时,SM 可以切换到其他就绪 Warp,从而隐藏访存或流水线延迟。

4. 不同计算能力下每个 SM 的最大驻留 Warp 数

每个 SM 的最大驻留 Warp 数由 Compute Capability 决定。

Compute Capability 典型架构/产品 Warp 大小 每个 SM 最大驻留 Warp 每个 SM 最大驻留线程
7.5 Turing:T4、RTX 20 系列 32 32 1024
8.0 Ampere 数据中心:A100、A30 32 64 2048
8.6 Ampere 消费级/工作站:RTX 30、A10 32 48 1536
8.7 Ampere 嵌入式:Jetson Orin 32 48 1536
8.9 Ada:RTX 40、L4、L40S 32 48 1536
9.0 Hopper:H100、H200 32 64 2048
10.0 数据中心 Blackwell:B200、GB200 32 64 2048
10.3 Blackwell Ultra:B300、GB300 32 64 2048
12.x RTX Blackwell:RTX 50 系列 32 48 1536

该上限是架构上限。具体 Kernel 的实际驻留 Warp 数通常更低,并由 Block 规模、寄存器和 Shared Memory 等资源共同决定。

5. NVIDIA 主流 GPU 的 SM 数量

下表列出常见产品的实际启用 SM 数,以及按架构上限计算的整颗 GPU 理论最大驻留 Warp 数。

text 复制代码
整颗 GPU 的理论最大驻留 Warp 数
= SM 数量 × 每个 SM 最大驻留 Warp 数
产品 架构 Compute Capability SM 数量 每个 SM 最大驻留 Warp 整颗 GPU 理论最大驻留 Warp 理论最大驻留线程状态
NVIDIA T4 Turing 7.5 40 32 1,280 40,960
GeForce RTX 2080 Ti Turing 7.5 68 32 2,176 69,632
NVIDIA A100 Ampere 数据中心 8.0 108 64 6,912 221,184
GeForce RTX 3070 Laptop GPU Ampere 8.6 40 48 1,920 61,440
GeForce RTX 3070 Ampere 8.6 46 48 2,208 70,656
GeForce RTX 3090 Ampere 8.6 82 48 3,936 125,952
GeForce RTX 3090 Ti Ampere 8.6 84 48 4,032 129,024
GeForce RTX 4090 Ada Lovelace 8.9 128 48 6,144 196,608
NVIDIA H100 PCIe Hopper 9.0 114 64 7,296 233,472
NVIDIA H100 SXM Hopper 9.0 132 64 8,448 270,336
NVIDIA B200 Blackwell 数据中心 10.0 148 64 9,472 303,104
NVIDIA B300 Blackwell Ultra 10.3 148 64 9,472 303,104
GeForce RTX 5090 Blackwell 消费级 12.0 170 48 8,160 261,120

"理论最大驻留线程状态"表示 GPU 最多能够在片上保存多少个逻辑线程的执行状态,不表示这些线程在同一周期全部执行。

5.1 产品版本差异

同一代 GPU 的不同产品可能启用不同数量的 SM:

text 复制代码
完整 GH100 裸片:144 SM
H100 SXM:       132 SM
H100 PCIe:      114 SM
text 复制代码
完整 GB202 裸片:192 SM
RTX 5090:       170 SM
text 复制代码
完整 AD102 裸片:144 SM
RTX 4090:       128 SM

因此,裸片设计中的最大 SM 数不能直接作为具体显卡的 SM 数。CUDA 调优应以运行时查询到的具体设备属性为准。

6. Occupancy

Occupancy 通常译为占用率,表示一个 SM 上实际驻留的 Warp 数与该架构每个 SM 最大驻留 Warp 数之比。

text 复制代码
Occupancy
= 实际驻留 Warp 数 / 每个 SM 最大驻留 Warp 数

Occupancy 是每个 SM 的指标,不是整颗 GPU 的统一线程利用率。

6.1 驻留 Warp 数的计算

text 复制代码
warps_per_block
= ceil(threads_per_block / 32)
text 复制代码
resident_blocks_per_sm
= min(
    Block 数上限,
    线程数上限,
    Warp 数上限,
    寄存器容量限制,
    Shared Memory 容量限制
  )
text 复制代码
resident_warps_per_sm
= resident_blocks_per_sm × warps_per_block
text 复制代码
occupancy
= resident_warps_per_sm / max_warps_per_sm

影响 Occupancy 的主要因素包括:

  • 每个 Block 的线程数;
  • 每个线程使用的寄存器数量;
  • 每个 Block 使用的静态和动态 Shared Memory;
  • 每个 SM 的最大线程数、Warp 数和 Block 数;
  • 寄存器和 Shared Memory 的硬件分配粒度。

6.2 RTX 3070 Laptop GPU 示例

RTX 3070 Laptop GPU 的主要参数为:

text 复制代码
SM 数量:40
Compute Capability:8.6
每个 SM 最大驻留 Warp:48
每个 SM 最大驻留线程:1536

采用 256 个线程的 Block:

text 复制代码
每个 Block 的 Warp 数
= 256 / 32
= 8

若资源允许每个 SM 驻留 6 个 Block:

text 复制代码
驻留 Warp 数
= 6 × 8
= 48

Occupancy
= 48 / 48
= 100%

若寄存器或 Shared Memory 只允许每个 SM 驻留 4 个 Block:

text 复制代码
驻留 Warp 数
= 4 × 8
= 32

Occupancy
= 32 / 48
≈ 66.7%

整颗 RTX 3070 Laptop GPU 的理论最大驻留规模为:

text 复制代码
40 SM × 48 Warp/SM
= 1920 Warp

1920 Warp × 32 Thread/Warp
= 61,440 个逻辑线程状态

7. Occupancy 与性能的关系

较高的 Occupancy 能够提供更多候选 Warp,便于 Warp Scheduler 在某些 Warp 等待内存或数据依赖时切换到其他 Warp,从而隐藏延迟。

Occupancy 不等于 GPU 利用率,也不是越高越好。以下情况可能使较高 Occupancy 无法带来更高性能:

  • 所有驻留 Warp 同时等待显存;
  • Kernel 受显存带宽限制;
  • 分支发散导致大量 Lane 非活动;
  • 为提高 Occupancy 而限制寄存器,产生 Register Spill;
  • 为减少 Shared Memory 而缩小 Tile,导致数据复用下降;
  • 少量 Warp 已经足以隐藏当前指令延迟。

性能优化的目标是提供足够的可执行 Warp,同时保留合理的寄存器、Shared Memory、Tile 大小和数据复用能力,而不是机械地追求 100% Occupancy。

8. SM 数量不能直接代表 GPU 性能

SM 数量只表示一颗 GPU 包含多少个并行计算单元。跨架构比较时,GPU 性能还取决于:

text 复制代码
SM 数量
× 每个 SM 的执行能力
× 工作频率
× Tensor Core 代际和数据类型
× 显存带宽与容量
× L2 Cache 和片上互连
× 功耗限制
× 实际工作负载

例如 RTX 5090 有 170 个 SM,B200 有 148 个 SM,但两者的产品定位、SM 结构、Tensor Core、内存系统和支持的数据类型不同,不能仅根据 SM 数量判断总体性能。

9. 查询实际设备参数

9.1 CUDA Runtime

cpp 复制代码
#include <cuda_runtime.h>
#include <iostream>

int main() {
    int device = 0;
    cudaDeviceProp prop{};

    cudaError_t status = cudaGetDeviceProperties(&prop, device);
    if (status != cudaSuccess) {
        std::cerr << "CUDA error: "
                  << cudaGetErrorString(status) << '\n';
        return 1;
    }

    const int maxWarpsPerSM =
        prop.maxThreadsPerMultiProcessor / prop.warpSize;

    std::cout << "GPU: " << prop.name << '\n';
    std::cout << "Compute Capability: "
              << prop.major << '.' << prop.minor << '\n';
    std::cout << "SM count: "
              << prop.multiProcessorCount << '\n';
    std::cout << "Warp size: "
              << prop.warpSize << '\n';
    std::cout << "Max resident threads per SM: "
              << prop.maxThreadsPerMultiProcessor << '\n';
    std::cout << "Max resident warps per SM: "
              << maxWarpsPerSM << '\n';

    return 0;
}

9.2 PyTorch

python 复制代码
import torch

properties = torch.cuda.get_device_properties(0)

print("GPU:", properties.name)
print("Compute Capability:", torch.cuda.get_device_capability(0))
print("SM count:", properties.multi_processor_count)

9.3 Nsight Compute

bash 复制代码
ncu --section LaunchStats --section Occupancy ./your_program

Nsight Compute 可以显示:

  • Block 和 Grid 规模;
  • 每线程寄存器数;
  • 每 Block Shared Memory;
  • 理论 Occupancy;
  • Achieved Occupancy;
  • Occupancy 的主要限制资源。

10. 核心关系

text 复制代码
一个 Warp = 32 个 Thread
text 复制代码
一个 Block 的 Warp 数
= ceil(Block 线程数 / 32)
text 复制代码
一个 SM 可以驻留多个 Block
一个 Block 被拆成多个 Warp
Warp Scheduler 从就绪 Warp 中选择指令发射
text 复制代码
Occupancy
= 每个 SM 实际驻留 Warp 数
  ÷
  每个 SM 最大驻留 Warp 数
text 复制代码
整颗 GPU 的理论最大驻留 Warp 数
= SM 数量 × 每个 SM 最大驻留 Warp 数

SM 数量描述整颗 GPU 的并行计算单元规模;每个 SM 的最大驻留 Warp 数描述该 SM 可保存的线程级并行状态;Occupancy 描述具体 Kernel 对这一驻留能力的使用程度。

参考资料

  1. NVIDIA CUDA Programming Guide:SIMT Architecture、Hardware Multithreading、Compute Capabilities。
  2. NVIDIA CUDA GPU Compute Capability 产品列表。
  3. NVIDIA RTX Blackwell GPU Architecture Whitepaper。
  4. NVIDIA Hopper Architecture In-Depth。
  5. NVIDIA Ampere、Ada Lovelace 架构白皮书与产品规格。
  6. NVIDIA CUDA MPS MLOPart 技术说明(B200/B300 SM 数量)。
相关推荐
Mysticbinary2 年前
关于计算机体系结构的一些思考
计算机结构·计算机体系·算法和程序