JIT 编译器可以做什么 AOT 编译器不能做的事情?

c--*_*c-- 6 compiler-construction optimization jit compiler-optimization

即时 (JIT) 编译器可以根据提前 (AOT) 编译器无法获得的运行时信息来优化程序。

该运行时信息最明显的示例是目标平台,例如运行程序的确切CPU,或可能可用的任何加速器(例如GPU)。这就是 OpenCL 是 JIT 编译的意义。

但是假设我们提前知道目标平台是什么:我们知道哪些 SIMD 扩展可用,等等。 JIT 编译器还可以利用 AOT 编译器无法利用的其他运行时信息吗?

HotSpot 风格的 JIT 编译器会自动优化程序的热点……但是 AOT 编译器不能只优化整个程序、热点等等吗?

我想要一些 JIT 编译器可以执行而 AOT 编译器无法执行的特定优化的示例。如果您能够提供任何证据证明此类优化在“现实世界”场景中的有效性,则可获得加分。

Pet*_*ica 6

JIT 可以基于运行时信息进行优化,这会导致更严格的边界条件,而这些边界条件在编译时无法证明。例子:

  • 它可以看到内存位置没有别名(因为所采用的代码路径从未给它别名),从而将变量保留在寄存器中;
  • 它可以消除对永远不会发生的条件的测试(例如,基于参数的当前值);
  • 它可以访问完整的程序,并且可以在它认为合适的地方内联代码;
  • 它可以在运行时根据特定的使用模式进行分支预测,从而达到最佳效果。

内联原则上也对现代编译器/链接器的链接时间优化开放,但如果以防万一在整个代码中应用,可能会导致令人望而却步的代码膨胀;在运行时,可以在需要的地方应用它。

如果程序被编译两次并在中间进行测试运行,则可以使用普通编译器改进分支预测;在第一次运行中,代码会被检测,以便生成分析数据,这些数据在生产编译运行中用于优化分支预测。如果测试运行不典型(并且并不总是容易产生典型的测试数据,或者使用模式可能会在程序的生命周期内发生变化),则预测也不是最佳的。

此外,静态编译的链接时和运行时数据优化都需要在构建过程中付出巨大的努力(在某种程度上,在我一生工作过的 10 个左右的地方,我还没有看到它们在生产中得到应用);使用 JIT 时,它们默认处于打开状态。