GPU计算核心
GPU的计算能力不是由“单个核心”决定的,而是“核心集群(SM)+专用加速单元”的协同。
流多处理器SM
SM是GPU的“最小独立计算单元”,相当于CPU的“核心”,但功能更复杂。一个GPU芯片由数十个SM组成,每个SM内部集成了“计算单元(CUDA Core/Tensor Core)、存储单元(寄存器/共享内存)、调度单元”三大模块。
- SM是资源分配和调度的基本单位,当用CUDA写kernel时,GPU会把kernel的线程块(Block)分配到某个SM上进行,SM再负责调度块内的线程。
SM内通用计算单元CUDA Core
CUDA Core是SM内执行“通用浮点/整数计算”的最小单元,对应CPU的ALU。
- 核心关系:每个SM包含数十到数百个CUDA Core,线程数大于CUDA Core数,一个SM可能同时管理数万个线程,但CUDA Core只有数十个,这需要靠调度让Core不空闲。
- 局限性:CUDA Core擅长“单指令单数据(SIMD)”的并行计算,但面对AI中大量的“矩阵乘法(GEMM)”时,效率很低,因为矩阵运算需要“单指令多数据(SIMD)”的并行,这就需要Tensor Core。
SM内AI专用加速单元Tensor Core
Tensor Core是英伟达为AI workload(尤其是深度学习的矩阵运算)设计的专用硬件加速单元,是GPU跑模型的“性能核心”(没有Tensor Core,GPU跑大模型会慢10倍以上)。
- 核心能力:专门执行“混合精度矩阵乘法-累加(FMA)”
- AI Infra的关键:所有深度学习框架的矩阵运算,最终都会调用Tensor Core;模型量化(如FP8)、混合精度训练,本质都是为了适配Tensor Core的精度要求,最大化其利用率。
GPU内存层次结构
AI workload的性能杀手往往不是计算,而是内存访问——如果数据不能快速传到计算单元,再强的算力也会空转。GPU的内存层次设计,就是为了“用不同速度/容量的内存,匹配不同访问需求”,而共享内存是并行优化的核心。
| 内存类型 | 位置 | 速度(延迟) | 容量(单 SM/A100) | 访问规则 | 核心作用 |
|---|---|---|---|---|---|
| 寄存器(Register) | SM 内,线程私有 | ~1-2 ns(最快) | 单 SM 256KB-512KB | 每个线程私有,线程结束后数据销毁 | 存储线程执行时的临时变量(如kernel中的局部变量),避免频繁访问慢内存 |
| 共享内存(Shared Memory) | SM 内,线程块共享 | ~10-20 ns | 单 SM 64KB-128KB | 同一线程块(Block)的所有线程可访问,需手动管理 | 并行优化核心:将全局内存的重复数据缓存到这里,减少全局内存访问(比如矩阵分块计算时的块数据) |
| L1 缓存 | SM 内,硬件自动管理 | ~20-30 ns | 单 SM 192KB | 硬件自动缓存全局内存 / 常量内存的访问,无需手动干预 | 辅助共享内存,减少对 L2 缓存的访问 |
| L2 缓存 | GPU 芯片级,所有 SM 共享 | ~100-200 ns | A100 总计 40MB | 所有 SM 共享,硬件自动管理 | 作为全局内存和 SM 之间的 “桥梁”,缓存多个 SM 的常用数据 |
| 全局内存(Global Memory) | GPU 外部(显存,如 HBM2) | ~400-800 ns(最慢) | A100 总计 40GB-80GB | 所有线程可访问,需通过 PCIe 或 NVLink 传输 | 存储模型权重、训练数据等 “海量数据”,但访问成本极高 |
| 常量内存(Constant Memory) | GPU 芯片级,只读 | ~50-100 ns | 总计 64KB | 所有线程只读,硬件自动缓存 | 存储训练中的常量(如模型的固定参数) |
关键结论:内存优化的核心逻辑
- 速度差决定优化方向:全局内存速度(缓慢程度)是共享内存的20-40倍,是寄存器的200-400倍——优化的本质就是“尽量让计算单元访问快内存,减少全局内存访问”。
- 容器限制决定线程数:寄存器和共享内存是SM内的“稀缺资源”——每个SM的寄存器容量是固定的,当启动的线程数越多,每个线程能分配到的寄存器就越少;如果线程数超过寄存器容量,GPU会把部分数据“溢出”到全局内存,导致性能暴跌。
并行调度
GPU的并行不是“多核心同时跑少量线程”,而是用“数万线程的并发,掩盖内存访问延迟”——依赖Warp调度和时分复用。
线程的“最小调度单元”——Warp(线约束)
GPU不单独调度“单个线程”,而是以Warp为单位调度———一个Warp包含32个连续的线程(英伟达GPU的固定值,不管架构是开普勒、伏特还是安培)
- 为什么是 32?因为 GPU 的计算单元(CUDA Core/Tensor Core)是按 32 路 SIMD 设计的 —— 一个 Warp 的 32 个线程会执行 “同一条指令”(比如同时做加法),但操作不同的数据(这就是 “单指令多线程,SIMT”)。
- 关键现象:如果一个 Warp 中的线程因为 “等待内存访问”(比如等全局内存的数据)而停滞,调度器会立刻切换到另一个 “就绪的 Warp” 继续执行 —— 通过这种 “切换”,让 CUDA Core/Tensor Core 始终有活干,不会因为等待内存而空闲。
Grid → Block → Warp → Thread
当在CUDA中启动一个kernel时,线程的组织是“三层结构”,这对应GPU的调度逻辑
Grid(网格):整个kernel的所有线程 → 由多个Block组成(可跨SM分配)
↓
Block(线程块):每个Block包含数百个线程(如256、512个)→ 必须分配到同一个SM上(因为Block内的线程要共享共享内存)
↓
Warp(线程束):每个Block按32个线程拆分成Warp → 调度器按Warp调度
↓
Thread(线程):单个线程 → 执行具体计算
高利用率——时分复用
因为“Warp切换的成本几乎为0”,GPU可以在一个SM上同时管理数百个Warp,通过时分复用让SM的计算单元始终满负荷。
- 类比理解:就像餐厅的 “服务员(CUDA Core)” 和 “顾客(Warp)”—— 如果一个顾客(Warp)需要等菜(等内存数据),服务员不会闲着,而是去服务另一个顾客(切换 Warp);当第一个顾客的菜好了(内存数据到了),服务员再回来服务他。
- 核心结论:SM 上的 Warp 数量越多,调度器能切换的 “备选 Warp” 就越多,计算单元的利用率就越高—— 但 Warp 数量受限于 SM 的寄存器和共享内存容量(每个 Warp 需要占用一定的寄存器和共享内存)。
硬件视角看AI Infra优化
| AI Infra 优化手段 | 对应的 GPU 硬件特性 | 优化逻辑 |
|---|---|---|
| 模型并行(Model Parallelism) | SM 是独立计算单元,全局内存共享 | 将模型层拆分到不同 SM,避免单个 SM 的计算 / 内存瓶颈 |
| 算子融合(Operator Fusion) | 减少全局内存访问(全局内存最慢) | 将多个算子(如 Conv+BN+ReLU)合并成一个 kernel,避免中间结果写入全局内存 |
| FP8/FP16 量化 | Tensor Core 支持低精度计算 | 用低精度减少内存带宽占用(FP8 比 FP32 少 75% 带宽),同时适配 Tensor Core 算力 |
| 共享内存分块(如 GEMM 分块) | 共享内存比全局内存快 20-40 倍 | 将大矩阵分成小块,用共享内存缓存,减少全局内存访问次数 |
| 线程块大小优化(如选 256) | Warp 是 32 线程,SM 资源有限 | 256 是 32 的整数倍(拆成 8 个 Warp),避免 Warp 内有空闲线程;同时匹配 SM 的寄存器 / 共享内存容量 |