第 200 题:算子融合的边界判断?融合后register pressure过高?
题目
算子融合的边界判断?融合后register pressure过高?
完整讲解
一、融合的边界
算子融合:把多个小 kernel(如 add + relu、linear + bias + gelu)合并成一个大 kernel,减少 launch 开销与显存往返。边界:并非「越融越多越好」;融合后单 kernel 的 寄存器、共享内存 占用会上升,若超过 GPU 限制会导致 occupancy 下降(并行 block 数减少),反而可能变慢;或触发 spilling,增加局部内存访问。
二、Register pressure 过高
Register pressure:每个 thread 使用的寄存器数量过多时,GPU 能同时驻留的 thread block 数 减少(由每个 block 的寄存器总需求与 SM 寄存器总量决定),即 occupancy 低。后果:延迟隐藏能力变差(更多时间在等内存)、利用率下降。判断:用 Nsight Compute 看 kernel 的 Occupancy、Register usage;若融合后 occupancy 明显下降、且 kernel 非带宽极限,可考虑拆开或减少单 kernel 内的中间变量(如用更少寄存器、或部分放 shared memory 折中)。
三、工程策略
融合前先 profile 看 launch 与带宽占比;融合后用 ncu 看 occupancy 与 register。若「小 kernel 过多、launch 占主导」则融合收益大;若「单 kernel 已很大、occupancy 已低」则谨慎再融。编译器/自动融合(如 torch.compile)也会做类似权衡;手写时可参考其生成的 kernel 大小与 occupancy。
面试要点
- 融合有边界:过大会导致 register pressure 升高、occupancy 下降,可能变慢或 spilling。
- 用 Nsight Compute 看 Occupancy、Register usage;融合后若 occupancy 明显降则考虑拆或减寄存器。
- 先 profile 看 launch vs 计算;再决定融合粒度;编译器也会做权衡。
记忆要点
- 融合边界 = 不能无限融;寄存器/共享内存有限。
- Register pressure 高 → occupancy 低 → 可能变慢。
- ncu 看 occupancy/register;按需拆或减中间变量。