实时(JIT)编译器可以基于运行时信息优化程序,这些信息对于提前(AOT)编译器来说是不可用的。
这个运行时信息最明显的例子是目标平台,例如程序运行的确切CPU,或者任何可能可用的加速器(如GPU)。这就是OpenCL是JIT编译的意思。
但是,假设我们提前知道目标平台是什么:我们知道哪些SIMD扩展是可用的,等等。对于AOT编译器来说,JIT编译器可以利用哪些其他运行时信息呢?
热点风格的JIT编译器将自动优化程序的热点.但是一个AOT编译器不能只对整个程序、热点和所有的部分进行优化吗?
我想要一些JIT编译器可以执行的、AOT编译器不能执行的特定优化的例子。如果你能提供任何证据证明这类优化在“真实世界”场景中的有效性,那么你就可以得到额外的分数。
发布于 2018-09-26 15:18:16
JIT可以基于运行时信息进行优化,从而导致更严格的边界条件,而这些边界条件在编译时是无法证明的。示例:
内联也主要开放给现代编译器/链接器的链接时间优化,但如果在整个代码中应用,可能会导致代码膨胀,以防万一;在运行时,它可以在必要时应用。
如果程序被编译两次,且测试运行在两者之间,则可以用普通编译器改进分支预测;在第一次运行中,对代码进行检测,以便生成用于生产编译运行中用于优化分支预测的分析数据。如果测试运行不是典型的(并且不总是很容易推断出典型的测试数据,或者使用模式可能在程序的生命周期内发生变化),那么预测也就不是最优的。
此外,使用静态编译的链接时和运行时数据优化都需要在构建过程中付出很大的努力(在一定程度上,我还没有看到它们在我生活中工作过的大约10个地方的生产中使用);对于JIT,它们是默认的。
发布于 2018-09-26 04:48:50
JIT编译器可以做AOT编译器不能做的事情吗?
理论上没有,因为AOT编译器可以在结果代码中插入JIT编译器(和/或可以生成自修改代码,生成123个替代版本,并根据运行时信息选择要使用的版本,.)。
在实践中,AOT编译器受到编译器设计人员想要处理的复杂程度、编译语言以及编译器的使用方式的限制。例如,一些编译器(Intel的ICC)将生成多个版本的代码,并(在运行时)根据运行的CPU来决定使用哪个版本,但大多数编译器都不是这样设计的;许多语言没有提供任何控制“局部性”的方法(并减少TLB丢失和缓存丢失的可能性);通常,使用编译器的方式会造成阻碍优化的障碍(例如,稍后链接在一起的单独的“编译单元”/object文件,可能包括动态链接,在这种情况下,AOT编译器不可能完成整个程序优化,只能单独优化部分)。所有这些都是实现细节,而不是AOT的限制。
换句话说,在实践中,"AOT与JIT“是对实现的比较,而不是对"AOT与JIT”本身的真正比较;而在实践中,AOT由于实现细节而给出的性能较差,而JIT给出的性能比糟糕的性能更糟糕,因为JIT本身是糟糕的(昂贵的优化根本不可行,因为它们是在运行时完成的);JIT看起来“几乎一样好”的唯一原因是它“几乎一样好”。
发布于 2018-09-26 03:09:35
一个优点是JIT编译器可以连续地分析代码并优化输出,例如对齐/不对齐一些代码块,取消优化某些功能,重新排序分支以减少错误预测.
当然,AoT编译器也可以进行配置文件引导的优化,但是它们在开发人员和测试人员执行的测试用例中是有限的,这可能不能反映实际输入的动态性质。
例如,Android已经从AoT回归,只是当他们在Kitkat中引入了一种混合方法时,在Nougat和以后的版本中,应用程序的某些部分被快速地以较少的优化方式提前编译,然后在运行配置文件后,在手机充电时,将使用配置文件结果再次优化应用程序。
Android7.0Nurgat引入了JIT编译器,并将代码分析引入到ART中,这使得它能够在运行时不断提高Android应用程序的性能。JIT编译器预先补充ART当前的编译器,并帮助提高运行时性能。
一些相关问题:
https://stackoverflow.com/questions/52506603
复制相似问题