张芷铭的个人博客

Roofline 模型通过操作强度将算法特征与硬件能力关联,精准定位性能瓶颈(内存带宽受限/算力受限)。

核心概念

操作强度

$$OI = \frac{\text{浮点操作数}(FLOPs)}{\text{片外内存访问量}(Bytes)}$$

Roofline 公式

$$P_{max} = \min(P_{peak}, OI \times B_{max})$$

符号定义
$P_{max}$程序最大性能
$P_{peak}$硬件峰值算力
$B_{max}$峰值内存带宽
$OI_{ridge}$临界操作强度 = $P_{peak}/B_{max}$

瓶颈判定

条件瓶颈类型
$OI < OI_{ridge}$内存带宽受限
$OI > OI_{ridge}$算力受限

主流 GPU 参数

GPUFP16 算力 (TFLOPS)带宽 (GB/s)$OI_{ridge}$
H100 SXM9893350295
A100 SXM3122039153
V100 SXM125900138

常见算子操作强度

算子操作强度瓶颈类型
大矩阵乘法>50算力受限
小矩阵乘法<10带宽受限
Element-wise≈0.3严重带宽受限
LayerNorm<10带宽受限

LLM 推理分析

阶段操作强度瓶颈
Prefill$2 \times seq_len$算力受限(长序列)
Decode2带宽受限

优化策略

瓶颈类型优化方向
带宽受限分块计算、算子融合、量化
算力受限剪枝、Tensor Core、向量化

绘图代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
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/

Comments