cod*_*eim 12 language-features interpreter compiler-theory language-design compiler-optimization
我正在为一项研究项目做准备调查.
说出一个难以优化的主流语言或语言特征,以及为什么这个特征是否值得付出代价,或者只是用轶事证据揭穿我的理论.在任何人将此标记为主观之前,我要求提供语言或功能的具体示例,以及优化这些功能的想法,或者我没有考虑过的重要功能.此外,任何对证明我的理论是对还是错的实现的引用.
在我的难以优化的功能和我的理论列表中排名第一(我的一些理论是未经测试的,并且基于思想实验):
1)运行时方法重载(也称为多方法调度或基于签名的调度).与允许运行时重新编译或添加方法的功能结合使用时,难以进行优化.或者它是否很难,无论如何?调用站点缓存是许多运行时系统的常见优化,但多方法增加了额外的复杂性,并使内联方法不太实用.
2)键入变形/变体(也就是基于值的键入而不是基于变量)当您不知道某个人的类型是否可以在基本块中更改时,传统的优化根本无法应用.结合多种方法,必须小心地进行内联,并且可能仅针对被调用者的给定阈值大小.即.很容易考虑内联简单的属性提取(getter/setter),但内联复杂的方法可能会导致代码膨胀.另一个问题是我不能只是将一个变量分配给一个寄存器并将它JIT转换为本机指令,因为我必须携带类型信息,或者每个变量需要2个寄存器而不是1.在IA-32上这是不方便的,即使使用x64的额外寄存器进行了改进.这可能是我最喜欢的动态语言功能,因为它从程序员的角度简化了很多东西.
3)第一类连续 - 有多种方法可以实现它们,我在两种最常用的方法中都这样做,一种是堆栈复制,另一种是实现运行时使用连续传递样式,cactus栈,copy-on - 写入堆栈帧和垃圾收集.一流的延续有资源管理问题,即.如果继续恢复,我们必须保存所有内容,并且我不知道是否有任何语言支持留下"意图"的继续(即"我不会回到这里,所以你可以丢弃这个世界的副本" ).在线程模型和控制模型中进行编程后,我知道两者都可以完成同样的事情,但是延续的优雅会给运行时带来相当大的复杂性,也可能影响缓存的效率(使用continuation和co-routines更多地改变堆栈的位置).另一个问题是他们只是没有映射到硬件.对于不太常见的情况,优化延续是优化的,并且正如我们所知,常见情况应该是快速的,并且不太常见的情况应该是正确的.
4)指针算法和掩码指针的能力(以整数存储等)不得不把它扔进去,但实际上我可以很容易地生活.
我的感觉是,许多高级功能,特别是动态语言中的功能,并没有映射到硬件.微处理器实现在芯片上的优化背后有数十亿美元的研究,但语言特征的选择可能使许多这些特性边缘化(诸如缓存,堆栈顶部的别名到寄存器,指令并行,返回地址缓冲区,循环等功能)缓冲区和分支预测).微特征的宏应用并不像某些开发人员想象的那样泛滥,并且在VM中实现多种语言最终将本机操作映射到函数调用(即,语言越动态,我们就越需要查找/在运行时缓存,没有任何东西可以假设,因此我们的指令组合由比传统的静态编译代码更高百分比的非本地分支组成)并且我们唯一可以真正JIT良好的是非动态类型的表达式评估和对常数或直接类型的操作.由于这个原因,字节码虚拟机和JIT核心可能并不总是适用于某些语言.
我欢迎你的回答.
几条评论:
所有具有动态调度的语言,即使基于单个对象,也很难有效地实现.看看Self的运行时优化(或者最近的JavaScript,使用SpiderMonkey)所做的所有努力.
不要忽视划定的延续.陪审团仍然没有,但他们比经典的无限延续更容易优化.阅读Gasbichler和Sperber撰写的论文.
归档时间: |
|
查看次数: |
396 次 |
最近记录: |