ALPHA教程正在持续完善,部分内容仍待补充。反馈问题 ↗
Skip to content

第 2 篇:经典算子与 Kernel 实战

假设我们已经能测准一段 GPU 程序的时间,也能从 trace 里找到最慢的 kernel。接下来怎样改它?从这一篇开始,我们拿六种具体算子做实验:先算清输出依赖哪些输入,再决定如何分工,最后用测量检查这个决定。

六章会逐步增加问题的难度。数组加法的每个输出彼此独立;求和需要让线程合作;矩阵乘还要让多个输出复用输入。学会这些基本模式后,我们再把它们组合成 Attention 和 RMSNorm。

怎样阅读这一篇

每章先用一个能手算的小输入解释算法,配有可播放、可单步查看的动画。画面默认静止,先看清当前步骤再前进即可;动画里的时间只用来展示计算关系,不表示真实 GPU 耗时。

理解算法后,在 HIP / Triton 标签页中选择一条实现路线。第一次阅读只学一种语言也可以,页面会在本次浏览中记住选择。两种实现共用前面的数学解释和后面的实验结果,想对照时再切换标签。

如果还不熟悉 thread、block、program 或 tile,可以先读附录 D:HIP 与 Triton 的编程范式。附录用同一个数组加法解释两种写法,第 8 章也会在需要时给出入口。

六章怎样递进

章节先回答的问题动画帮助你看清什么
第 8 章:逐元素算子每个输出互不依赖,怎样分配下标?线程与元素的对应、访问顺序、向量化尾部、Triton mask
第 9 章:归约算子多个输入怎样合成一个输出?求和树的中间值、block partial 与第二次归约
第 10 章:归一化算子怎样把分数稳定地变成概率?减最大值、取指数、求和与归一化
第 11 章:矩阵乘类算子一份输入怎样为多个输出服务?点积、分块加载与累加结果
第 12 章:融合算子能否边读边算,少存中间矩阵?Attention 的物化数据流与在线状态更新
第 13 章:Fused RMSNorm怎样把逐元素、归约和融合组合起来?平方、求均值、广播尺度与乘权重

开始前需要会什么

这一篇会继续使用前几章的方法:

  • 第 4 章:启动一个 HIP kernel,并理解全局下标。
  • 第 5 章:预热、重复、GPU event 计时,区分 kernel 时间与端到端时间。
  • 第 6 章:从 trace 中筛选目标 kernel,读懂工作规模和资源字段。
  • 第 7 章:数清算法所需的计算与数据量,用 Roofline 提出下一步实验。

不必一次记住所有工具选项。读代码时先问“谁负责这个输出”,读结果时再问“这次时间包含什么”。

从实现走到实验

每章的源码在 code/part2-kernels/chapterN/。HIP 和 Triton 实现、运行入口、实验记录放在一起;正文摘录关键片段,完整输入生成、校验和计时仍以源文件为准。

入口用途
run_all.sh运行本章实现与正确性检查
profile_all.sh按实现分别采集 trace;参数以各章说明为准
EXPERIMENT.md记录环境、命令、源码身份和结果边界
evidence/保存正文历史表格所依据的可追溯汇总

本书当前环境统一为 Radeon RX 9070 XT(gfx1201)+ ROCm 10.0 + 原生 Ubuntu 24.04。已有性能表保留采集时的 ROCm 版本;每组数字只描述相应输入、源码和测量协议。

做完一次练习,留下输入、参考答案、测量范围和观察就已经很有价值。某个版本变慢同样值得记录:它提醒我们,减少一次写回、增加一个 tile 或少启动一个 kernel,都需要放回完整程序中验证。