论文
算法发现
Faster sorting algorithms discovered using deep reinforcement learning (AlphaDev)
AlphaDev:用深度强化学习在汇编级发现更快的排序算法
Daniel J. Mankowitz, Andrea Michi, Anton Zhernov, et al. (Google DeepMind) · Google DeepMind · Nature · 2023-06
一句话DeepMind 把"写汇编程序"建模成单人游戏,用 AlphaZero 式 MCTS+网络在 x86 指令级搜索,给 sort3 找到 17 条指令的程序(比人类基准少 1 条,且被穷举证明最优),成果逆向成 C++ 后合入 LLVM libc++;但"更快"的幅度在真实硬件上远比标题温和(大序列约 1.7%,第三方 cycle 级测试里 Sort5 与朴素 sorting network 基本打平)。
这是什么
排序是被调用最频繁的库函数之一,libc++ 里小规模排序(sort3/4/5)本质上是手工优化了几十年的 branchless sorting network。这篇 2023 年 6 月的 Nature 论文提出 AlphaDev:不在源码层做程序合成,而是直接在 x86 汇编指令层搜索——因为编译器输出的指令序列才是真正决定 latency 的东西,而且指令级还残留着人类没榨干的优化空间。
AlphaDev 是 AlphaZero 的直系后代(作者列表里有 Silver、Schrittwieser、Hubert)。它把"逐条追加汇编指令"当成游戏动作,以正确性 + latency 作为奖励。搜索空间比围棋还大(论文估计枚举量级 >10^700 同级),且一条错指令就让整个程序作废。最终发现的 sort3/4/5 被人工逆向成 C++ 合入 LLVM libc++(review D118029),是这些子程序十多年来第一次改动;论文还把方法迁移到 protobuf 的 VarInt 反序列化,得到 branchless 版本。
在"AI 优化 AI/软件基础设施"这条线上,它是 AlphaTensor(2022,矩阵乘法)之后、AlphaEvolve(2025,LLM 驱动)之前的关键一环:证明 RL 搜索的产物可以通过工业级 code review 落进所有软件依赖的底层库,而不只是停留在论文表格里。
AssemblyGame 的一步:上半部分是 agent 根据状态 S_t 选择动作(追加一条指令,如 MOV<Register0,Memory1>)拼进程序;下半部分是奖励计算——把当前程序跑在全部测试输入序列上,输出与期望排序结果逐项比对得到正确性奖励 r_t(图中 D' ≠ B' 即错误)。机制与做法
AssemblyGame:把写程序变成单人游戏
状态 S_t = ⟨P_t, Z_t⟩:P_t 是当前已生成的程序,Z_t 是把程序跑在预定义输入上之后的寄存器/内存状态。每一步动作是追加一条合法 x86 指令(mov/cmp/cmovX/jX 等,AT&T 语法)。正确性奖励:对 sort3 用全部长度为 3 的未排序排列做输入,输出与期望排序结果逐一比对;latency 奖励:branchless 程序里长度与 latency 强相关,直接用程序长度做代理;有分支的 VarSort 则用实测 latency。
动作空间做了强剪枝:内存按递增顺序读、寄存器递增分配、禁止对内存做 cmp/cmov、每个内存位置只读写一次、不许用未初始化寄存器、不许连续两条 cmp。这些规则把天文数字的空间砍到可搜索。
AlphaDev 发现的两个核心优化。上排(a-c):swap move——sort3 网络中因前序 comparator 已保证 B≤C,原版计算 min(A,B,C) 的位置(红色高亮)只需算 min(A,B)(绿色),省掉一条 mov;下排(d-f):copy move——sort8 中利用 D≥min(A,C) 的不变量,用 copy 替换比较逻辑再省一条。左侧是对应的 sorting network 线路图。AlphaZero 骨架 + 面向代码的表示网络 + 双 value head
学习算法就是 AlphaZero:网络输出 policy 和 value 引导 MCTS,policy 向 MCTS 访问计数回归。表示网络分两块:一个 MultiQuery Transformer 编码指令序列(opcode/operand 做 one-hot 再映射到 embedding),一个 MLP 编码 CPU 状态(寄存器和内存内容),让网络能预测程序对机器状态的作用。
针对 latency 优化的关键设计是双 value head:一个预测正确性,一个以实测 latency 为 Monte Carlo target 直接预测 latency。论文报告这比单 value head 明显更好——因为实测 latency 太贵,AlphaDev 只对不到 0.002% 的生成程序做了真实测量,其余全靠 latency head 泛化。训练用 TPU v3(每 core batch 1024,至多 16 core)+ 至多 512 个 TPU v4 actor,最坏情况约 2 天收敛。
latency 怎么测、和什么比
latency 测量用一套跨机器的 benchmark 服务:每次评估做 1000 次测量,每次在 10000 个随机输入上跑;计时用 CPU_CLK_UNHALTED.CORE 性能计数器;取第 5 百分位数作为结果(假设噪声——cache miss、抢占——都是单向使程序变慢的)。训练时用 10 台机器,最终评测用 100 台。
对照基线是把 SOTA 随机超优化器(Schkufza 风格 MCMC)改造成的 AlphaDev-S。冷启动版在固定长度 sort 上找不到最优解、在 VarSort 上全灭;用近似最优程序热启动后,在 branchless 的 sort3/4/5 上能追平 AlphaDev(而且算力更省),但在长度与 latency 脱钩的 VarSort 上仍然输——因为它无法承受对每次变异做实测 latency,只能优化长度。探索量对比:AlphaDev 最多探索约 1200 万个程序,AlphaDev-S 最多约 31 万亿个。
关键结果
- sort3 找到 17 条指令的程序(人类基准 18 条),并用约 10^32 规模的剪枝穷举(3 天多)证明 17 条是下界;sort5 也少 1 条,sort4 追平 SOTA;规模化后 sort6/7/8 分别省 3/2/1 条指令。
- 核心新颖点是两个可复用的局部优化:swap move(利用前序 comparator 保证 B≤C,把 min(A,B,C) 简化为 min(A,B),省 1 条指令)和 copy move(利用 D≥min(A,C) 的不变量用一次 copy 替代比较,省 1 条指令),模式在不同规模的 sorting network 中反复出现。
- VarSort4 的结构是质变而非省指令:不再按长度分派到不同 sorting network,而是先无条件调 sort3,长度大于 3 时再对剩余元素跑简化版 sort4,latency 收益主要来自这个新算法结构。
- 合入 LLVM libc++ 后:长度 5 的序列提升"最高 70%"(相对旧的基于插入排序的实现),超过 25 万元素的大序列约 1.7%,覆盖 uint32/uint64/float,在 ARMv8、Skylake、Zen 2 上验证。
- 迁移到 protobuf VarInt 反序列化:发现 branchless 且更短的方案,单值输入上比人类基准快约 3 倍;还学到把两个操作融合为单条指令的 assignment move。
- AlphaDev 对不到 0.002% 的候选程序做真实 latency 测量,其余靠 latency value head;t-SNE 显示随机超优化基线密集聚在种子程序附近,AlphaDev 覆盖的程序空间更分散。
实证核查
有水分"找到更短的正确程序并合入 LLVM"这部分完全扎实,汇编成果开源可验证、指令数与论文一致;但"更快"的宣传幅度打折——第三方 cycle 级 benchmark 里 Sort5 与朴素 sorting network 基本打平,libc++ 大序列收益约 1.7%,且训练系统只开源了不可运行的 pseudocode,方法本身无法复现。
论文声称发现的 sort3 只需 17 条指令(比人类基准少 1 条)且开源了成果。
属实:repo 的 sort_functions_test.cc 完整给出 Sort3(17 条)到 Sort8(91 条)和 VarSort3/4/5 的内联汇编,附带穷举所有输入排列的正确性测试,CC=clang bazel test :sort_functions_test 可本地验证;指令数与论文、README 逐一吻合。合入 LLVM 的 review 是 D118029,公开可查。
标题与宣传口径是"更快的排序算法",媒体广泛引用"最高快 70%"。
GitHub issue #2 的第三方 benchmark(cycle 计数器直测)显示 Sort5AlphaDev 与朴素 sorting network 差距在 ±1% 内(17.37 vs 17.38 cycles);后续讨论发现结果强烈依赖编译器是否生成 cmov、以及测量方式(预生成数组批量测时曾出现 6 倍差距,被 issue 参与者定位为 Clang 对朴素版生成了大量条件跳转,修正写法后差距消失)。"70%"是 libc++ 里长度 5 序列相对旧插入排序实现的提升,大序列只有约 1.7%——真实收益来自 branchless 小排序整体替换旧实现,单条指令的节省贡献很小。
论文称开源了 AlphaDev agent 与 AssemblyGame 环境。
alphadev.py 自述为 pseudocode,不可运行:没有 assembly runner(README 明说"execution can be delegated to an external library")、没有训练基础设施;issue #1(语法错误需加 pass)、#3(784 行 bug)、#11(831 行未定义变量 value)都说明这份代码从未被执行过。repo 2023-06-20 后无提交、已 archived,多数提问 issue 无官方回应,训练无法端到端复现。
AlphaDev 优于 SOTA 超优化基线。
论文自己的对照就有保留:热启动的 AlphaDev-S 在 branchless sort3/4/5 上追平 AlphaDev 且算力更省(Extended Data 部分承认),AlphaDev 的净优势只在需要实测 latency 的 VarSort 场景。这一点论文正文写得比摘要/新闻稿诚实。
与我们方向的关系
对课题组 ai4ai 方向,这篇的可借鉴点不在排序本身,而在"如何让 RL 优化一个昂贵的真实目标":双 value head(便宜代理 + 少量真实测量训练出的 latency 预测头)把真实评测压到 0.002%,这个模式可以平移到任何评测昂贵的搜索问题(kernel 调优、编译 pass 序列、超参搜索)。另一个值得记的教训是基线对比:热启动超优化器在 branchless 场景追平了 RL,说明"RL 赢"高度依赖任务结构(长度与目标脱钩、需要长程 credit assignment 时才赢)。
作为 AlphaTensor → AlphaDev → FunSearch/AlphaEvolve 谱系的一环,它标志着范式切换前夜:AlphaDev 用领域定制的 RL 环境 + 自训练网络,每个新问题都要重建环境;两年后 AlphaEvolve 用通用 LLM + 进化搜索覆盖了同类问题且不用训练。读它的价值是理解这条路线为什么被替代,以及哪些组件(真实 latency 反馈、剪枝规则、正确性测试即奖励)在 LLM 时代仍然保留。
阅读笔记
读的时候注意区分三个层次的"快":(1) 指令数更少——严格成立且被证明最优;(2) 微基准 latency 更快——依赖测量方式和编译器行为,第三方结果基本打平;(3) libc++ 用户感知的提升——主要来自用 branchless network 替换旧插入排序这个(人类完成的)工程决策。新闻稿把三者揉在一起说。另外合入 LLVM 的代码是工程师逆向汇编后手写的 C++/内联汇编,不是 AlphaDev 直接产出。
材料清单
同类条目