2.2. 如何不使用汇编

2.2.1. 实现高效代码的通用步骤

正如 Charles Fiterman 在 comp.compilers 上关于人类与计算机生成的汇编代码所说


人类应该总是胜出,原因如下。

首先,人类用高级语言编写整个程序。
其次,他对其进行性能分析,以找出程序花费时间的热点。
第三,他让编译器为那些小段代码生成汇编代码。
第四,他对它们进行手工调整,以寻找相对于机器的微小改进
生成的代码。

人类获胜是因为他可以使用机器。

2.2.2. 具有优化编译器的语言

像 ObjectiveCAML、SML、CommonLISP、Scheme、ADA、Pascal、C、C++ 等语言,都拥有免费的优化编译器,这些编译器将优化你的大部分程序,并且通常比手工编写的汇编代码(即使对于紧凑的循环)做得更好,同时让你专注于更高层次的细节,并且一旦你达到了稳定的设计,也不会禁止你以上述方式获得百分之几的额外性能。当然,对于这些语言中的大多数,也有商业优化编译器!

一些语言的编译器可以生成 C 代码,这些代码可以被 C 编译器进一步优化:LISP、Scheme、Perl 和许多其他语言。速度相当不错。

2.2.3. 加速代码的通用步骤

至于加速代码,你应该只对程序中被性能分析工具持续识别为性能瓶颈的部分进行加速。

因此,如果你确定某个代码部分太慢,你应该

最后,在你最终编写汇编代码之前,你应该检查生成的代码,以确认问题是否真的是代码生成不良,因为情况可能并非如此:编译器生成的代码可能比你编写的代码更好,特别是在现代多流水线架构上!程序中速度慢的部分可能本质上就是如此。现代架构中快速处理器面临的最大问题是内存访问、缓存未命中、TLB 未命中和页错误造成的延迟;寄存器优化变得无用,你将更有利地重新思考数据结构和线程,以实现更好的内存访问局部性。也许完全不同的问题解决方法可能会有所帮助。

2.2.4. 检查编译器生成的代码

检查编译器生成的汇编代码有很多原因。以下是你将对这些代码执行的操作

生成汇编代码的标准方法是使用以下命令调用编译器-S标志。这适用于大多数 Unix 编译器,包括 GNU C 编译器 (GCC),但 YMMV。至于 GCC,它将使用以下命令生成更易于理解的汇编代码-fverbose-asm命令行选项。当然,如果你想获得良好的汇编代码,不要忘记你常用的优化选项和提示!