第 30 题:算子融合的收益如何评估?什么时候融合反而变慢?
题目
算子融合的收益如何评估?什么时候融合反而变慢?
完整讲解
一、融合收益如何评估?
- 理论:省 kernel launch 次数(每次 launch 有固定开销)、省 中间结果写回/读回 global memory(带宽与延迟);可粗略算「融合前读写字节数 − 融合后」和「launch 次数差」。
- 实测:用 profiler(torch.profiler、Nsight Systems)对比「融合前多 kernel 总时间 + 间隙」与「融合后单 kernel 时间」;看 端到端 延迟/吞吐,因为还可能受其他 op 影响。
- Roofline:若融合前是 memory bound(多趟读写),融合后减少访存,收益大;若已是 compute bound,融合主要省 launch,收益有限。
二、什么时候融合反而变慢?
- Register / shared 压力过大:融合后单 kernel 用太多 register 或 shared,导致 occupancy 明显下降,延迟隐藏变差,可能比「多个小 kernel、高 occupancy」更慢。
- 不利于并行:例如把可并行的两条独立链强行融成一个串行 kernel,或融合后 block 内负载不均(如分支多、warp divergence 增加)。
- 编译/代码膨胀:融合多种组合导致 多份 kernel 或巨大泛化 kernel,编译慢、缓存差、或指令 cache 压力大。
- 与硬件/调度不匹配:某些 GPU 上小 kernel 更易被调度器重叠;融合成一个大 kernel 反而减少 overlap。
三、建议
先 profile 确认瓶颈在 launch 与中间读写,再做融合;融合后 再 profile 看 occupancy、stall、throughput;若变慢,检查 register/shared、分支与并行度。
面试要点
- 收益评估:省 launch 与中间 global 读写;用 profiler 对比融合前后时间,结合 roofline 看是否 memory bound。
- 融合变慢:occupancy 掉太多、并行度下降、warp 效率变差、编译/代码膨胀、或调度重叠变差。
- 先 profile 再融合,融合后再测 occupancy 与 throughput。
记忆要点
- 收益 = 少 launch + 少中间访存;用 profiler 和 roofline 评估,memory bound 时收益大。
- 变慢常见原因:register/shared 导致 occupancy 降、并行度/divergence 变差、编译膨胀。
- 流程:profile → 融合 → 再 profile(occupancy、stall);不行则回退或拆开。