基于方法的JIT编译之挑战

 

今天,混合模式的编译系统采用的常用方法是识别频繁执行的或者叫热方法。热方法传递给JIT编译器以便编译成机器代码。然后,当解释器看见应用调用被编译过的方法时,它就会分发机器代码去执行。

 

这种面向方法的方法已经采用许多年了,但是仍然需要大量的开发方面的前期投资。直到能够编译一门语言中出现的所有功能时,这样的系统才能提高方法的执行效率。对重要的应用来说,这需要JIT编译整个语言,包含那些复杂的已经用高级虚拟指令体实现了的功能,例如那些方法调用,对象创建,异常处理。

1 Compiling Cold Code

因为一个方法被频繁执行,并不意味着方法内的所有指令也会频繁执行。实际上,热方法的部分区域可能是“冷的”,也就是说可能他们永远也不会执行。编译冷代码除了浪费时间外还有更多的隐含意味。除最高级别的优化外,分析冷代码可以证明哪些是热代码,除了这一点好除外,没有其他更多益处。一个更严重的问题是,冷代码增加了动态编译的复杂度。我们给出3个例子。


      首先,对于延迟绑定语言如Java来说,冷代码很有可能包含对那些还没有绑定的外部符号的引用,因此当冷代码最终并没有运行时,生成的代码还有支持它运行的环境(Runtime)必须处理延迟绑定的复杂性。 


       第二,某些动态优化如果不运行Profiling信息是不可能做到的. Foremost amongst these is the optimization of virtual function calls. 因此没有Profiling信息,JIT只能为冷代码生成相对慢的保守代码。这个问题对弱类型(runtime typed)的语言如python来说变得更加重要,因为虚拟指令的操作数类型可能只有在运行时刻才能知道。没有运行信息,无论是动态还是静态的Python编译器都不能判别简单算数运算如加法的操作数是什么类型,是整形、浮点型还是字符串型。

      第三,随着指令的执行,编译过的方法里以前认为冷的区域可能变热。第一次编译是作出的保守的假设现在对性能却构成了拖累。直接的方法就是再次编译这些冷代码,这样做就会对编译带来的优势造成了损害。而且,问题是如此复杂以至于对那些还在方法中执行的线程来说,它们需要做什么?或者未来如何返回到方法?


2 高效解释器的挑战

虚拟程序被解释器载入内存之后,它就可以通过分发一条条虚拟程序指定的虚拟指令体(或者叫指令体)来运行。从处理器的观点看,这种方式并不是典型的工作方式,这是因为使得CPU的控制从一个指令(体)交到另一个指令体的决定因素是那些依赖指令的虚拟程序的数据。这使得处理器很难作出分支预测。Ertl 和 Gregg 观察到高效率的解释器性能受限于指令流水线,同时及其低效的分支预测也会导致指令流水线被清空,这也限制了解释器性能。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值