第 42 题:编译时优化和运行时优化的权衡?AOT vs JIT?
题目
编译时优化和运行时优化的权衡?AOT vs JIT?
完整讲解
一、AOT 与 JIT 的含义
AOT(Ahead-of-Time):在 运行前(或部署前)完成编译,生成 固定 的可执行/库;运行时直接加载,无编译开销,启动快,但 无法根据运行时信息(如实际 shape、数据)再优化。JIT(Just-in-Time):在 首次运行或条件触发时 编译,可 根据当前 shape、设备、数据 做特化与优化,但 首包/首步延迟 高,且需 缓存 避免重复编译。
二、编译时 vs 运行时优化的权衡
- 编译时:能做的 全局优化、激进融合、静态分配 多;但 无运行时信息(如真实 batch、序列长),只能按 profile 或符号做保守/多版本。AOT 偏编译时:一次编译,多次运行;适合 部署形态固定、对冷启敏感的场景。
- 运行时:能 根据实际 shape、设备、甚至数据 选 kernel、做特化;但 编译不能太重,否则延迟不可接受。JIT 偏运行时:首次或条件触发编译,可特化;适合 动态 shape、多后端,接受一定首包成本。
- 权衡:启动与首步延迟(AOT 优)vs 特化与适配动态(JIT 优);编译时间与缓存(JIT 需缓存与失效策略);部署复杂度(AOT 需提前建好所有版本,JIT 需带编译器或预编译缓存)。
三、实践中的折中
- AOT + 多版本:为常见 shape/profile 预编译多份,运行时按 shape 选;折中是 二进制数量与覆盖度。
- JIT + 缓存:首次编译后写盘或内存缓存,同 shape 直接用;guard 失效(如新 shape)再编译并更新缓存。
- 分层:部分子图 AOT(稳定、热点),部分 JIT(动态、长尾);或 hybrid:AOT 主路径,JIT 兜底新 shape。
面试要点
- AOT = 运行前编译,无运行时编译开销,启动快;无法根据运行时信息再优化。
- JIT = 运行时编译,可特化 shape/设备,首包延迟高,需缓存与失效策略。
- 权衡:冷启与固定性(AOT)vs 动态与特化(JIT);实践中可 AOT 多版本、JIT+缓存、或分层。
记忆要点
- AOT:提前编译、一次运行多次;JIT:运行时编译、可特化,首包慢。
- 编译时优化多但无运行时信息;运行时可特化但编译不能太重。
- 折中:AOT 多版本、JIT 缓存、或热点 AOT + 长尾 JIT。