25.2.7 混合使用C++(www.cppentry.com)和汇编代码
C++(www.cppentry.com)被认为是一种速度很快的语言,特别是和其他面向对象语言比较的时候。然而,在某些罕见的情况下,当速度至关重要的时候,您可能需要使用原始的汇编代码。编译器从您的源代码文件生成汇编代码,这个生成的汇编代码几乎对于所有的目的都足够快。编译器和链接器(当像VC++(www.cppentry.com) 2010那样支持链接时代码生成的时候)都使用了优化算法使得生成的汇编代码能够尽可能地快。通过使用特殊的处理器指令集,例如MMX和SSE,这些优化器变得越来越强大。如今,自己编写的汇编代码很难比编译器生成的代码速度更快,除非您了解这些增强指令集的所有细节。
然而,万一您需要使用汇编代码,在C++(www.cppentry.com)编译器中可以使用asm关键字插入原始汇编代码。这个关键字是C++(www.cppentry.com)标准的一部分,但是实现方式却是由编译器自己定义的。在有些编译器中,您可以通过asm关键字在程序中立即从C++(www.cppentry.com)降到汇编层次。有时,asm关键字的支持取决于您的目标架构。例如,编译32位代码的时候Microsoft VC++(www.cppentry.com) 2010支持asm关键字,但是编译64位模式的时候不支持asm。
在某些应用程序中内联汇编会有用,但是我们对大部分程序都不建议使用。应该避免内联汇编代码,原因有以下几点:
如果包含了针对您的平台的汇编代码,那么您的代码将不能移植到其他处理器。
大多数程序员不知道汇编语言,他们无法修改或维护您的代码。
汇编代码的可读性差。汇编代码可能会破坏您的程序使用的风格。
大部分时候,汇编代码是没有必要的。如果您的程序缓慢,检查算法问题或者采用第24章给出的其他性能建议。
提示:当您的应用程序遇到性能问题的时候,首先查看算法加速,原始汇编只是万不得已才考虑使用的解决方案。
实际上,如果您有一块代码计算量非常大,那么您应该把这段代码放在一个C++(www.cppentry.com)函数中。如果通过性能剖析(详见第24章)判定这函数是一个性能瓶颈,而且无法使得这段代码更简单更快,那么可以通过原始汇编尝试提高性能。
在这种情况下,您需要以extern "C"声明这个函数,这样可以避免C++(www.cppentry.com)的名称变异。然后,用汇编代码写一个单独的模块更高效地执行这个函数。一个单独的模块的好处是,有一个平台无关的C++(www.cppentry.com)"参考实现";同时还有一个平台相关的高性能汇编代码实现。使用extern "C"意味着这段汇编代码可以使用简单的命名约定(否则,您不得不逆向工程编译器的名称变异算法)。然后,可以和C++(www.cppentry.com)版本链接,也可以和汇编代码的版本链接。
您可以用汇编代码编写这个模块并通过汇编器运行这段代码,而不是使用C++(www.cppentry.com)中的内联asm指令;对于很多流行的x86兼容的64位编译器来说尤其如此,因为这些编译器不支持内联的asm关键字。
不过,除非确实有显著的性能提升,否则不要使用原始汇编代码。2倍的性能提升可以证明这个努力是有效的。10倍的提升是令人信服的。10%的提升则得不偿失。