土法炼钢兴趣小组的算法知识备份

【GPU 算子工程】Roofline 模型:判断算子是 compute-bound 还是 memory-bound

文章导航

分类入口
gpuarchitecture
标签入口
#cuda#roofline#arithmetic-intensity#compute-bound#memory-bound#performance-model

源码下载

本文相关源码已整理,共 1 个文件。

打开下载目录 →

目录

Roofline 模型:判断算子是 compute-bound 还是 memory-bound

前面几篇反复说”访存密集”“算力密集”,但怎么客观判断一个算子属于哪一类?盲目优化常常白费力气——给一个受带宽限制的 kernel 加算力优化没有任何效果。Roofline 模型用一张图、一个指标,把算子定位到它的性能天花板上,告诉你优化该往哪使劲。这是动手优化前的必备一步。

一、算术强度:一个决定性的比值

算术强度(Arithmetic Intensity, AI) 定义为算子执行的浮点运算数与它从 global memory 搬运的字节数之比,单位 FLOP/byte:

\[ \text{AI} = \frac{\text{FLOPs}}{\text{Bytes moved}} \]

它衡量”每搬一字节数据,能做多少计算”。AI 低意味着搬得多算得少,瓶颈在带宽;AI 高意味着搬一次数据反复计算,瓶颈在算力。

几个例子:

二、Roofline:两条线和一个脊点

把性能(GFLOP/s)对算术强度(FLOP/byte)作双对数图,硬件的上限是两条线的下包络:

两条线相交处叫脊点(ridge point),其横坐标 \(\text{AI}_{\text{ridge}} = \dfrac{\text{峰值算力}}{\text{峰值带宽}}\)。脊点左边是 memory-bound 区,右边是 compute-bound 区。

RTX 3060 Ti 的脊点:\(16197 \text{ GFLOP/s} \div 448 \text{ GB/s} \approx 36 \text{ FLOP/byte}\)。也就是说,算术强度低于约 36 的算子受带宽限制,高于 36 的受算力限制。绝大多数深度学习的访存类算子(element-wise、归一化、注意力的部分阶段)AI 远低于 36,落在带宽区。

三、实测:在本卡上画出经验 Roofline

理论 Roofline 是两条直线,真实硬件能不能贴上去?用一个可调算术强度的 kernel 验证:每个线程读一个 float、做 \(K\) 次相关的 FMA(每次 2 FLOP)、写回一个 float。改变 \(K\) 就改变 AI(\(= 2K/8 = K/4\)),测每个 \(K\) 下的实测 GFLOP/s。

float x = in[i];
for (int k = 0; k < K; ++k) x = x*a + b;   // 2 FLOP/次,相关链不被消除
out[i] = x;

RTX 3060 Ti 实测(\(n=2^{24}\),256 线程/block,CUDA event 中位数):

\(K\) AI (FLOP/byte) 实测 GFLOP/s 实测带宽
1 0.25 97 388 GB/s
8 2 788 394 GB/s
32 8 3093 387 GB/s
128 32 10782 337 GB/s
256 64 12483 195 GB/s
1024 256 13999 55 GB/s

把这些点画到 Roofline 上:

RTX 3060 Ti 经验 Roofline:低算术强度的实测点贴着带宽斜线,高算术强度的点逼近 FP32 算力屋顶,脊点约在 36 FLOP/byte

几个观察:

这张实测图证明了 Roofline 不只是理论:硬件确实在两个区各自贴着对应的屋顶。

四、怎么用 Roofline 指导优化

拿到一个算子,三步定位:

  1. 算 AI:估算 FLOP 和 global 搬运字节,得到算术强度,和脊点(本卡约 36)比较。
  2. 测实际性能:用 profiler 测实测 GFLOP/s 和带宽利用率,看落在屋顶线哪个位置、离屋顶多远。
  3. 决定方向
    • 落在带宽区且贴着屋顶 → 别再优化计算了,唯一出路是减少访存(融合、提高复用、改数据布局、用更低精度)。
    • 落在带宽区但离屋顶远 → 访存模式有问题(不合并、bank conflict、occupancy 不足),先修这些(第 0506 篇)。
    • 落在算力区且贴着屋顶 → 已经很好,进一步只能换更高吞吐的指令(如 Tensor Core,第 11 篇)。
    • 落在算力区但离屋顶远 → 指令级并行不足、发散、或没用上专用单元。

这套判断尤其能避免一类常见浪费:给一个明明受带宽限制的 element-wise kernel 反复调指令、换算法,性能纹丝不动——因为瓶颈根本不在算力。

五、提高算术强度:优化的本质

对受带宽限制的算子,最有效的优化是提高算术强度,把它从带宽区往脊点推。手段都是让数据复用发生在片上:

六、模型的边界

Roofline 是一阶模型,几个简化要记住:

七、小结与下一步

Roofline 给方向,但要落到具体 kernel 的瓶颈,还得靠 profiler 看真实指标。下一篇讲 Nsight 调优工作流:怎么读 Nsight Compute 和 Nsight Systems,把瓶颈定位到指令和访存级别。

同主题继续阅读

把当前热点继续串成多页阅读,而不是停在单篇消费。

2026-06-28 · gpu / architecture

【GPU 算子工程】Kernel Fusion 与 epilogue:减少 HBM 往返

融合通过减少中间结果的 HBM 往返提速 memory-bound 算子。实测逐元素链融合的加速比随链长线性增长(k=16 时 16.8 倍)。讲清逐元素融合、归约融合、GEMM epilogue 融合,以及什么时候不该融合。

2026-06-26 · gpu / architecture

GPU 高性能算子工程

从 GPU 执行模型与内存层次出发,系统讲解如何写出并调优高性能 CUDA 算子:访存合并、occupancy、Roofline、Nsight 调优,reduction/GEMM/Tensor Core/FlashAttention 核心算子实现,以及 Triton、CUTLASS、kernel fusion 与算子库工程。


By .