现代x86成本模型
我正在编写一个带有x86后端的JIT编译器,并随时了解x86汇编器和机器代码。 大约20年前,我使用ARM汇编器,并对这些架构之间的成本模型的差异感到惊讶。
具体来说,ARM上的内存访问和分支是昂贵的,但x86上的等价堆栈操作和跳转很便宜。 我相信现代x86 CPU比ARM内核的动态优化要好得多,我发现很难预测它们的影响。
编写x86汇编程序时要记住什么是一个好的成本模型? 哪些指令组合便宜,哪些昂贵?
例如,如果我的编译器总是生成加载整数或跳转到偏移量的长整型,即使整数很小或偏移量接近但会影响性能,它的编译器会更简单一些。
我还没有做过任何浮点运算,但我想尽快进行。 对正常代码和浮点代码之间的交互有什么不明显的地方?
我知道有很多关于x86优化的参考文献(例如Michael Abrash),但我有一个比任何超过几年的预测都不适用于现代x86 CPU的预感,因为它们近来发生了很大的变化。 我对么?
最佳参考是“英特尔优化手册”,该手册提供了有关所有最新英特尔内核的体系结构危害和指令延迟的相当详细的信息,以及大量优化示例。
另一个优秀的参考资料是Agner Fog的优化资源,它也具有覆盖AMD内核的优点。
请注意,特定的成本模型本质上是特定于微架构的。 没有像“x86成本模型”那样具有任何真实有效性的东西。 在指令级别,Atom的性能特征与i7大不相同。
我还会注意到内存访问和分支在x86内核上实际上并不“廉价” - 只是无序执行模型变得非常复杂,以至于在许多简单的情况下它可以成功地隐藏它们的成本。
TorbjörnGranlund的AMD和Intel x86处理器的指令延迟和吞吐量也不错。
编辑
Granlund的文档涉及在每个时钟周期(即并行执行)中发布特定类型的指令的指令吞吐量。 他还声称英特尔的文档并不总是准确的。
值得一提的是,Rick Booth曾经有一本叫做“Inner Loops”的书,详细描述了如何手动微调英特尔80486,Pentium,Pentium Pro和Pentium MMX处理器的IA-86汇编代码,有许多有用的真实世界的代码示例(哈希,移动内存,随机数生成,霍夫曼和JPEG压缩,矩阵乘法)。
不幸的是,自1997年首次发布新版本的处理器和CPU架构以来,这本书一直没有更新过。 尽管如此,我仍然会推荐它作为对以下主题的温和介绍:
下一篇: Why There is a difference between assembly languages like Windows, Linux?