AI Infra和算子开发(1)
GPU
整体而言,GPU 相比于 CPU 牺牲了复杂计算上的能力,取而代之的是大规模并行处理数据的能力。

GPU 存在三个并行层级:
- thread:GPU 上最小执行单位,对应一次函数调用的一个实例。每个 thread 有自己的寄存器和程序计数器,每个 thread 执行逻辑相同,处理的数据不同(Single Instruction Multiple Data)。
- block:由多个能互相合作的 thread 组成,每个 block 有自己的共享内存,其中的线程可以交换数据,可以与其他 block 并行执行。
- grid:是一次 kernel launch 的所有 block 的集合,对应整个 GPU 上跑的任务,不同 block 之间完全独立,调度顺序无所谓。
warp
GPU 不是以 thread 为单位执行,而是以 warp(32 个 thread)为单位执行的。
SIMT(Single Instruction, Multiple Thread)的含义:
- 这 32 个 thread 在同一个时钟周期执行完全相同的指令
- 每个 thread 操作自己那份数据(不同寄存器值)
算子开发里要尽量保证同一 warp 内的 thread 走相同控制流。比如,
1 | // 危险!同一个 warp 内不同 thread 走不同分支 |
由于 warp 必须执行同一条指令,硬件会串行执行两个分支:先让走 A 的 thread 执行 do_A(),其他 thread 闲置;再让走 B 的执行 do_B()。原本的并行变成串行,性能直接砍半。
当 warp 访问全局内存时,32 个 thread 各自请求一个地址。硬件会把这些请求合并,此时连续的寻址会更好。
Streaming Multiprocessor
SM(Streaming Multiprocessor) 是 GPU 内部一个完整的“小处理器”,负责调度和执行 block。
一次 kernel launch 有成千上万个 block,但 SM 数量有限。规则是:
- 每个 SM 可以同时驻留多个 block
- SM 用 warp 调度在这些 block 的 warp 之间快速切换,掩盖延迟
- 一个 SM 同时能跑多少 warp,取决于资源限制
一个 SM 同时能驻留多少 warp,受三种资源限制:
- 每个 SM 最多支持的 warp 数
- 每个 SM 最多支持的 block 数
- 每个 block 用的寄存器/共享内存
Occupancy(占用率)记为实际驻留的 warp 数 / SM 最大 warp 数。
算子的性能指标
1. 核心利用率
Bandwidth Utilization(带宽利用率) = 实际带宽 / 硬件峰值带宽
Compute Utilization(MFU) = 实际 FLOPS / 硬件峰值 FLOPS
FLOPS:floating-point operations per second(每秒浮点算力)
MACs:Multiply ACcumulate operations(乘加累积操作次数),一个MACs包含一个乘法操作与一个加法操作,因此1个MACs约等价于2个FLOPs。
Roofline Model
算力 $\pi$ 是一个计算平台倾尽全力每秒钟所能完成的浮点运算数(FLOPS)。
带宽 $\beta$ 是一个计算平台倾尽全力每秒所能完成的内存交换量(Byte/s)。
计算强度上限 $I_{\text{max}}=\frac{\pi}{\beta}$ 单位是FLOPs/Byte。

Compute-bound:整个计算的耗时主要在于计算本身,对显存的读写耗时较低。
Memory-bound:整个计算的耗时主要集中在存储的访问上,计算本身耗时较低。
Memory-bound 的优化方向:减少访存
- 算子融合(Fusion)
- 数据布局 / 向量化访问
- 用更小的 dtype
- 减少中间结果落盘(不写回 HBM)
Compute-bound 的优化方向:提高算力利用率
- 用 Tensor Core
- Tiling(分块)
- 双缓冲 / 流水线(Pipelining)