语言和虚拟机:难以优化的功能及其原因

时间:2010-03-24 22:57:04

标签: language-features language-design interpreter compiler-theory compiler-optimization

我正在为一项研究项目做准备调查。

命名一种难以优化的主流语言或语言功能,以及为什么该功能是否值得付出代价,或者只是用轶事证据揭穿我的理论。在任何人将此标记为主观之前,我要求提供语言或功能的具体示例,以及优化这些功能的想法,或者我没有考虑过的重要功能。此外,任何对证明我的理论是对还是错的实现的引用。

在我的难以优化的功能和我的理论列表中排名第一(我的一些理论未经测试且基于思想实验):

1)运行时方法重载(又名多方法调度或基于签名的调度)。与允许运行时重新编译或添加方法的功能结合使用时,难以进行优化。或者它是否很难,无论如何?调用站点缓存是许多运行时系统的常见优化,但多方法增加了额外的复杂性,并使内联方法不太实用。

2)输入变形/变体(也就是基于值的输入而不是基于变量) 当您不知道某个人的类型是否可以在基本块中更改时,无法应用传统优化。结合多种方法,必须小心地进行内联,并且可能仅针对被调用者的给定阈值大小。即。很容易考虑内联简单的属性提取(getter / setter),但内联复杂的方法可能会导致代码膨胀。另一个问题是我不能只是将一个变量分配给一个寄存器并将它JIT到本机指令,因为我必须携带类型信息,或者每个变量需要2个寄存器而不是1.在IA-32上这是不方便的,即使使用x64的额外寄存器进行了改进。这可能是我最喜欢的动态语言特性,因为它从程序员的角度简化了很多东西。

3)第一类延续 - 有多种方法可以实现它们,我在两种最常用的方法中都这样做,一种是堆栈复制,另一种是实现运行时使用继续传递样式,仙人掌堆栈,写时复制堆栈框架和垃圾收集。一流的延续有资源管理问题,即。如果继续恢复,我们必须保存所有内容,并且我不知道是否有任何语言支持留下“意图”的继续(即“我不会回到这里,所以你可以丢弃这个世界的副本” )。在线程模型和控制模型中进行编程后,我知道两者都可以完成同样的事情,但是延续的优雅会给运行时带来相当大的复杂性,也可能影响缓存的效率(使用continuation和co-routines更多地改变堆栈的位置)。另一个问题是他们只是没有映射到硬件。优化延续是针对不太常见的情况进行优化,而且正如我们所知,常见情况应该很快,而不太常见的情况应该是正确的。

4)指针算法和掩码指针的能力(以整数形式存储等)不得不把它扔进去,但实际上我可以很容易地生活。

我的感觉是,许多高级功能,尤其是动态语言中的功能都没有映射到硬件。微处理器实现在芯片上的优化背后有数十亿美元的研究,但语言特征的选择可能使许多这些特性边缘化(诸如缓存,堆栈顶部的别名到寄存器,指令并行,返回地址缓冲区,循环等功能)缓冲区和分支预测)。微特征的宏应用并不像一些开发人员想象的那样泛滥,并且在VM中实现多种语言最终将本地操作映射到函数调用(即,语言越动态,我们就越需要查找/在运行时缓存,没有任何东西可以假设,因此我们的指令组合由比传统的静态编译代码更高百分比的非本地分支组成)并且我们唯一可以真正JIT良好的是非动态类型的表达式评估和对常数或直接类型的操作。我的直觉是,由于这个原因,字节码虚拟机和JIT核心可能并不总是适用于某些语言。

我欢迎你的回答。

2 个答案:

答案 0 :(得分:5)

几条评论:

  • 所有具有动态调度功能的语言,即使基于单个对象,也很难有效地实现。看看Self的运行时优化所做的所有努力(或者最近,使用SpiderMonkey的JavaScript)。

  • 不要忽视分隔的延续。陪审团仍然没有,但他们比经典的无限延续更容易优化。阅读Gasbichler和Sperber撰写的论文。

答案 1 :(得分:1)

  

字面码是我的直觉   虚拟机和JIT核心   也许并不总是合理的   某些语言因此而存在。

没有编写IronPython来证明虚拟机不能像语言的本机实现那样好(Python)。然后IronPython的作者发现IronPython在字节码虚拟机上的动态语言表现非常好的时候相当震撼了吗?

微软自己的.Net内部组织正在声明他们认为JITter最终将胜过“普通”编译器/链接器(比如说C / C ++)。

我认为陪审团仍然没有这个。很难称之为。选择最适合这项工作的语言......