Roofline 模型通过操作强度将算法特征与硬件能力关联,精准定位性能瓶颈(内存带宽受限/算力受限)。
核心概念
操作强度
OI=片外内存访问量(Bytes)浮点操作数(FLOPs)
Roofline 公式
Pmax=min(Ppeak,OI×Bmax)
| 符号 | 定义 |
|---|
| Pmax | 程序最大性能 |
| Ppeak | 硬件峰值算力 |
| Bmax | 峰值内存带宽 |
| OIridge | 临界操作强度 = Ppeak/Bmax |
瓶颈判定
| 条件 | 瓶颈类型 |
|---|
| OI<OIridge | 内存带宽受限 |
| OI>OIridge | 算力受限 |
主流 GPU 参数
| GPU | FP16 算力 (TFLOPS) | 带宽 (GB/s) | OIridge |
|---|
| H100 SXM | 989 | 3350 | 295 |
| A100 SXM | 312 | 2039 | 153 |
| V100 SXM | 125 | 900 | 138 |
常见算子操作强度
| 算子 | 操作强度 | 瓶颈类型 |
|---|
| 大矩阵乘法 | >50 | 算力受限 |
| 小矩阵乘法 | <10 | 带宽受限 |
| Element-wise | ≈0.3 | 严重带宽受限 |
| LayerNorm | <10 | 带宽受限 |
LLM 推理分析
| 阶段 | 操作强度 | 瓶颈 |
|---|
| Prefill | 2×seq_len | 算力受限(长序列) |
| Decode | 2 | 带宽受限 |
优化策略
| 瓶颈类型 | 优化方向 |
|---|
| 带宽受限 | 分块计算、算子融合、量化 |
| 算力受限 | 剪枝、Tensor Core、向量化 |
绘图代码
import matplotlib.pyplot as plt
import numpy as np
devices = [
{"name": "H100", "fp16_tflops": 989, "bw_gbps": 3350},
{"name": "A100", "fp16_tflops": 312, "bw_gbps": 2039},
]
plt.figure(figsize=(10, 6))
x = np.logspace(-1, 3, 100)
for dev in devices:
y_bw = (dev["bw_gbps"] * 1e9) * x / 1e12
y_flops = np.full_like(x, dev["fp16_tflops"])
y_roof = np.minimum(y_bw, y_flops)
plt.loglog(x, y_roof, label=dev["name"], linewidth=2)
plt.xlabel("OI (FLOPs/Byte)")
plt.ylabel("Performance (TFLOPS)")
plt.legend()
plt.grid(True, which="both", ls="--")
plt.show()
中文教程:https://lqhl.github.io/scaling-book/roofline/