我正在编写一个带有 x86 后端的 JIT 编译器,并一边学习 x86 汇编程序和机器代码。我大约 20 年前使用过 ARM 汇编器,对这些架构之间成本模型的差异感到惊讶。
具体来说,内存访问和分支在 ARM 上的成本很高,但等效的堆栈操作和跳转在 x86 上的成本却很低。我相信现代 x86 CPU 比 ARM 内核所做的动态优化要多得多,而且我发现很难预测它们的效果。
编写 x86 汇编程序时要牢记的良好成本模型是什么?哪些指令组合便宜,哪些组合昂贵?
例如,如果我的编译器始终生成用于加载整数或跳转到偏移量的长格式,即使整数很小或偏移量接近,我的编译器也会更简单,但这会影响性能吗?
我还没有做过任何浮点运算,但我想尽快开始。普通代码和浮动代码之间的交互有什么不明显的地方吗?
我知道有很多关于 x86 优化的参考文献(例如 Michael Abrash),但我有预感,几年前的任何东西都不适用于现代 x86 CPU,因为它们最近发生了很大的变化。我对么?
最好的参考是英特尔优化手册 http://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-optimization-manual.html,它提供了有关所有最新英特尔内核的架构风险和指令延迟的相当详细的信息,以及大量的优化示例。
另一个很好的参考是Agner Fog 的优化资源 http://www.agner.org/optimize/,其优点还包括AMD核心。
请注意,特定成本模型本质上是特定于微架构的。不存在任何真正有效的“x86 成本模型”。在指令层面,Atom 的性能特征与 i7 有很大不同。
我还要指出的是,内存访问和分支在 x86 核心上实际上并不“便宜”——只是无序执行模型变得如此复杂,以至于它可以在许多简单的场景中成功隐藏它们的成本。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)