你优化 CUDA kernel 的方式,可能一开始就错了|Kerminal 工程笔记

发布时间:2026/7/8 8:31:27
你优化 CUDA kernel 的方式,可能一开始就错了|Kerminal 工程笔记 写在前面在上一篇里我们讲了一个很基础但很容易被忽略的问题CUDA kernel 优化失败往往不是不会优化而是第一步就判断错了瓶颈类型。但在真实工程里这句话还有一个更残酷的版本。很多优化其实从一开始就走错方向了。不是因为不够熟练而是因为“慢”这件事本身就有不同类型。01GPU 里的“慢”不一定是“慢”如果你只盯着 runtime会很容易产生一个错觉“慢就是慢优化就是让它变快。”但在 GPU 里“慢”其实是不同性质的问题叠加出来的结果。大体上可以粗暴但有效地分成三类第一类Memory-bound不是算不动是数据“喂不进来”。这一类 kernel 的特征非常明确· global memory 访问频繁· 访问地址不连续· cache 命中率不高· warp 在等待 memory· 计算指令占比很低典型例子比如 matrix transpose。你会发现一件很反直觉的事情kernel 几乎没做什么计算但就是慢。原因不是 GPU 不够快而是❗数据在“进 GPU”的过程中就已经卡住了。这种情况下优化的方向通常不在计算而在数据流· memory coalescing 是否成立· 数据布局是否合理· 是否能 tile 到 shared memory· 是否存在重复读取· cache 是否被有效利用一个关键点是如果你在 memory-bound kernel 上继续优化计算路径本质上是在“优化一个不存在的瓶颈”。第二类Compute-bound不是数据慢是算力被用满了。这一类完全相反。这类 kernel 的特点是· arithmetic intensity 很高· 大量 matrix / math / reduction· memory 已经不再是主要瓶颈比如 GEMM、attention 中的某些 compute-heavy path。这时候你会看到memory 看起来很健康但 GPU 还是跑不满。问题通常在计算路径· 是否走了 Tensor Core 路径· 数据类型是否合理FP16 / BF16· instruction 是否高效· 是否存在重复计算· compiler 是否做了优化· warp-level execution 是否合理这里有一个非常容易踩的坑❗继续优化 memory在 compute-bound kernel 上通常不会带来收益因为瓶颈根本不在那里。第三类Occupancy / latency-bound不是慢是“GPU没有忙起来”。这一类问题最容易误判。表现是· compute utilization 不高· memory utilization 也不极端· 但整体 GPU throughput 很差看起来“什么都不突出”但就是慢。本质原因是GPU 没有足够 warp 去隐藏 latency。常见原因包括· register pressure 太高· shared memory 占用过多· block size 不合理· warp divergence· sync / barrier 过多· 并发 block 数不足这里有一个非常关键的误解occupancy 不是优化目标而是结果。很多人会把它当成调参指标但它真正的意义是是否足够隐藏延迟而不是数值高低。02大多数 CUDA 优化其实发生在“分类之前”如果你把这三类放在一起会发现一个很残酷的事实三种 bottleneck对应三种完全不同的优化方向。甚至是互相冲突的· memory-bound → 需要减少访存· compute-bound → 需要提升计算效率· occupancy-bound → 需要减少资源占用如果你分类错了优化手段不仅没用还可能互相抵消。这也是为什么很多 CUDA 优化看起来“做了很多”但效果很有限。03但现实工程里还有一个更大的问题理论上这个方法论是清晰的先分类再优化。然而即使你掌握了这套方法论也会遇到一个更现实的瓶颈kernel 太多了而且每个 kernel 的形态都在变化。尤其在· LLM training / inference· 多 stage pipeline· dynamic shape workload· 多 kernel fusion system你会逐渐发现❗“判断 bottleneck”本身开始变成成本。甚至在一些复杂系统里· profiling 一次的成本 kernel 本身优化收益· 人工判断速度跟不上 workload 变化· 同一 kernel 在不同 shape 下完全不同表现这时候问题已经开始变化了从“如何优化 kernel”变成“如何稳定地做出正确的优化判断”。你会发现一个趋势CUDA 优化正在从经验驱动变成系统问题。下篇预告下一篇我们会继续往工程现实走一步当“bottleneck 分类”本身变得昂贵时我们还能怎么做优化#CUDA#kernel优化#GPU#性能