今天这篇论文「 Agentic Auto-Scheduling: An Experimenta l Study of LLM-Guided Loop Optim ization」讲的是一个很具体的问题LLM 能不能参与编译器优化让程序跑得更快这里的 Loop指的是程序里的循环结构比如for/while循环尤其是科学计算、图像处理、机器学习算子里常见的多层嵌套循环。论文提出了一个名为 COMPILOT 的实验框架把现有 LLM 和编译器放进同一个优化闭环里LLM 先提出循环结构的变换方案编译器再检查方案是否合法、能否编译并实际运行代码判断性能是提升还是下降。随后系统把检查和测速结果反馈给 LLM让它继续调整下一轮方案。LLM 和编译器的分工在 COMPILOT 的设定中LLM 并不直接改写完整代码。它输出的是一组面向编译器的优化指令比如循环融合、循环交换、并行化、二维/三维 tiling、循环展开unrolling、循环偏斜skewing等。而真正执行变换、做依赖分析、生成代码和测速的部分依旧是编译器系统。图 1Fig. 1COMPILOT 框架总览这张架构图可以按从左到右的顺序理解。左侧是输入程序、编译 / 运行环境以及最终生成的优化后程序。输入代码先进入 COMPILOT中间的 Context Initializer 会把任务说明、目标循环代码、可用变换、输出格式等信息整理成上下文发送给右侧的 LLM Agent。LLM Agent 根据这些上下文生成下一轮 schedule也就是循环结构的变换方案。它的输出会回到中间的 Interaction Loop Handler由 Response Parser 解析成编译器能执行的指令。接下来左侧的编译 / 运行环境会尝试执行这些变换检查是否合法、能否编译并实际运行代码得到性能结果。中间的 Feedback Generator 再把格式错误、非法变换、编译失败、运行时间变化等信息整理成反馈继续发给 LLM进行下一轮优化。如上所述LLM 站在“提出候选方案”的位置上编译器和运行环境负责验证、执行和测速COMPILOT 中间这层负责把两边连接起来让这个过程可以反复迭代。从多层循环到调度搜索这篇论文关注的是 loop nest optimization也就是多层循环结构的优化。在科学计算、图像处理、机器学习底层算子里性能瓶颈往往出现在这类循环结构上。多层循环怎么嵌套、哪个维度先跑、要不要分块、能不能并行都会影响缓存命中、线程利用率和最终运行时间。这类优化难在搜索空间很大。同一段循环代码可以有很多种变换方式同一种变换也可能因为参数、顺序、硬件环境和输入规模不同带来完全不同的性能结果。编译器按预设规则自动选择时未必总能选到合适结果。COMPILOT 要测试的就是能不能让 LLM 在这个空间中充当“调度方案生成器”。它会根据目标循环代码提出一组 schedule也就是循环结构的变换方案。每一组 schedule 都可以理解成一次候选尝试这次先交换循环顺序还是先做分块并行化放在哪一层tiling 参数该怎么选。为了让模型进入这个任务系统会把输入循环、可用变换、输出格式、硬件信息和错误处理规则整理成 prompt。接下来模型会先读懂目标循环结构再给出后续的 schedule 候选。图 2Fig. 2 展示系统 prompt 结构图 3Fig. 3 展示输入给 LLM 的循环代码图 4Fig. 4 展示 LLM 对循环的分析这样看COMPILOT 做的事情并不神秘它把多层循环优化拆成一轮轮候选 schedule 的搜索。LLM 负责提出下一次尝试编译器和运行环境负责判断这次尝试能不能成立、跑起来有没有更快。3 倍加速是怎么测出来的论文在 PolyBench/C 上做性能测试。它是编译器优化研究里常用的一组 C 语言基准程序包含矩阵计算、线性代数、stencil 等循环密集型 kernel适合用来测试多层循环优化效果。这个基准包含 30 个 benchmark论文使用 5 种标准数据规模所以一共是 150 个 benchmark instance。本次论文的主要实验硬件是一台双路 Intel Xeon E5-2695 v2 机器总计 48 个线程128 GB 内存。编译器侧使用的是 Tiramisu。这篇论文默认使用 Gemini-2.0-flash 作为主要 LLM并在每个实例上运行多次统计中位数加速再用几何平均聚合整体结果。论文实验里最核心的两个数字是2.66×和3.54×。在单次运行设置下也就是每个程序最多迭代 30 轮优化COMPILOT30 相比原始代码达到2.66×几何平均加速。如果允许同一个程序独立运行 5 次再从 5 次结果里选择最快的一次也就是 best-of-5 设置COMPILOT_530 的几何平均加速达到3.54×。所以标题里的“跑快 3 倍”需要带上实验前提这是在 PolyBench/C 这组循环密集型基准上按照论文统计方式得到的汇总结果。单次运行接近 3 倍best-of-5 超过 3 倍。图 5Fig. 7 COMPILOT30 在不同 benchmark 和不同输入规模上的加速结果。如上图所示从分布上看这个加速并不平均。有些 benchmark 几乎没有提升有些在 LARGE / XLARGE 这类数据规模下提升明显。这里的数据规模指的是同一个程序处理的矩阵、数组或循环迭代范围更大。数据变大后并行化和 tiling 这类优化更容易摊开开销、改善缓存访问因此收益也更容易显现。比如 correlation_XLARGE、trmm_XLARGE 等案例里COMPILOT 找到的 schedule 带来了很高的加速。所以这里的 3 倍加速更适合理解为一个受控实验结果在循环密集型 benchmark 上LLM 可以帮助编译器搜索更好的 schedule。它不能直接推到普通业务代码上。更可控的代码优化这篇论文比较值得注意的一点是它没有让 LLM 直接生成优化后的 C 代码。因为直接改代码有一个风险LLM 可能会写出能编译、甚至能通过一部分测试的代码但其实它的语义已经被改坏了。对于循环优化来说这个问题会更敏感因为很多变换涉及数据依赖关系。看起来只是调整循环顺序实际可能影响读写顺序。COMPILOT 的做法相对保守。LLM 输出的是结构化的编译器变换命令编译器再通过依赖分析判断这些变换是否合法。这样可以把 LLM 的自由度限制在一个更可控的动作空间里。论文还做了一个对照实验让 LLM 直接生成变换后的 C 代码。结果显示这种方式的几何平均加速比标准 COMPILOT 低约 14% 到 16%。不仅如此一部分初看通过的代码在二次检查中暴露出错误输出或非法变换问题。论文还提到直接生成完整代码会明显增加 token 消耗因为输出完整代码比输出简短的变换命令更贵。多轮反馈带来的差异COMPILOT 不是只让 LLM 猜一次。每一轮结束后系统都会把结果反馈给 LLM这次 schedule 是格式错误、违反依赖、编译失败还是成功运行如果成功运行速度提升了多少。论文做了一个去掉反馈的消融实验。没有反馈时LLM 只能持续基于自己的判断提出 schedule。结果在 T30 时标准 COMPILOT 的单次运行加速是 2.66×无反馈版本是 2.01×best-of-5 场景下标准版本也明显更高。这说明反馈本身是系统能工作的关键部分。LLM 会犯错尤其是在复杂循环依赖关系上。但只要编译器能把错误类型和性能结果进行反馈LLM 就有机会在后续轮次里避开一些失败模式继续试探新的组合。图 6Fig. 10 展示不同 benchmark 中 runnable / invalid / illegal schedule 的比例这个结果也提醒我们COMPILOT 并没有让 LLM 变成一个可靠的编译器专家。根据论文统计在 30 轮对话范围内LLM 提出的 schedule 中只有约 36.1% 能最终成功编译并运行31.4% 是 invalid32.5% 是 illegal。看得出来大量候选方案其实是会失败只是失败被编译器拦住并转化成下一轮反馈了。COMPILOT vs Pluto论文还把 COMPILOT 和 Pluto 这样的 polyhedral optimizer 做了比较。在 best-of-5、每次 30 轮的设置下COMPILOT_530 相比 Pluto 优化后的代码达到2.94×几何平均加速。按论文统计在 150 个 PolyBench instance 中COMPILOT 优于 Pluto 的有 119 个差距在 5% 以内的有 9 个低于 Pluto 的有 22 个。这里也需要看实验条件。论文分析认为COMPILOT 的一部分优势来自实测反馈如果某个优化方案实际运行后变慢COMPILOT 有机会在后续迭代中避开它而 Pluto 这类传统优化器更多依赖静态模型和预设规则通常不会根据真实运行结果一轮轮调整。论文也做了一个 “capped Pluto” 对照如果 Pluto 的优化导致变慢就退回原始代码。这样一来COMPILOT 相对 Pluto 的整体优势从 2.94× 降到 1.78×。这个对照说明COMPILOT 的一部分优势来自实测反馈当某个优化方案实际跑起来变慢时系统有机会在后续迭代中避开它另一部分优势则来自它确实搜索到了更好的 schedule。图 7Fig. 11COMPILOT_530 与 Pluto 的对比。红线表示与 Pluto 持平高于红线表示 COMPILOT_530 更快低于红线表示 Pluto 更快。不同模型的表现差异论文还比较了多个 LLM 在同一套流程里的表现包括 gemini-2.0-flash、gpt-4o、llama3.3、gpt-o3-mini、qwq、qwen2.5-coder、codestral 等。从结果看模型之间确实有差异但差异不完全由“是不是推理模型”或“是不是代码模型”决定。gemini-2.0-flash、gpt-4o、gpt-o3-mini 的表现比较接近推理模型没有稳定压过非推理模型专门面向代码的模型在这个任务里也没有显示出明显优势。这和 COMPILOT 的任务形式有关。模型需要遵守固定输出格式理解循环结构提出高层变换命令还要根据编译器反馈继续调整。它考验的不只是代码生成能力还包括结构化输出、规则遵守和多轮反馈利用。图 8Table I不同 LLM 在不同迭代次数下的 COMPILOTT 几何平均加速边界与适用场景整体来看这篇论文的重点不在于证明 LLM 可以自动改好所有代码而是把问题收在一个更具体的范围里循环密集型代码、编译器可验证的变换空间、多轮实测反馈。在这个范围内COMPILOT 展示了一种比较清晰的思路让 LLM 负责提出 schedule让编译器负责验证、执行和测速。效果来自这个闭环而不是模型一次性生成一段更快的代码。所以这篇论文更适合看作一个有边界的编译优化实验。它不能直接推到普通业务代码上但对于已有编译器基础设施、又需要反复调度搜索的性能优化场景提供了一个值得参考的样本。论文文献Agentic Auto-Scheduling: An Experimental Study of LLM-Guided Loop Optimization arxiv.org/pdf/2511.00592