了解汇编程序的原因之一是,有时可以使用汇编程序来编写比用高级语言(特别是C语言)编写的代码性能更好的代码。然而,我也听人说过很多次,尽管这并非完全错误,但实际上可以使用汇编程序来生成性能更好的代码的情况极其罕见,并且需要汇编方面的专业知识和经验。

这个问题甚至没有涉及到这样一个事实,即汇编程序指令将是特定于机器的、不可移植的,或者汇编程序的任何其他方面。当然,除了这一点之外,了解汇编还有很多很好的理由,但这是一个需要示例和数据的具体问题,而不是关于汇编程序与高级语言的扩展论述。

谁能提供一些具体的例子,说明使用现代编译器汇编代码比编写良好的C代码更快,并且您能否用分析证据支持这一说法?我相信这些案例确实存在,但我真的很想知道这些案例到底有多深奥,因为这似乎是一个有争议的问题。


当前回答

紧密循环,就像处理图像时一样,因为一张图像可能需要数百万像素。坐下来研究一下如何最好地利用有限的处理器寄存器会有很大的不同。下面是一个真实的例子:

http://danbystrom.se/2008/12/22/optimizing-away-ii/

处理器通常有一些深奥的指令,这些指令对于编译器来说太专业了,但有时汇编程序员可以很好地利用它们。以XLAT指令为例。如果您需要在循环中进行表查找,并且表限制在256字节,那么这非常棒!

更新:哦,当我们谈论一般循环时,最关键的是:编译器通常不知道常见情况下会有多少次迭代!只有程序员知道一个循环会被迭代很多次,因此用一些额外的工作来准备循环是有益的,或者如果它迭代的次数太少,以至于设置实际花费的时间比预期的迭代要长。

其他回答

在处理器速度以MHz为单位,屏幕尺寸低于100万像素的时代,一个众所周知的更快显示的技巧是展开循环:为屏幕的每个扫描行写操作。它避免了维护循环索引的开销!再加上检测屏幕刷新,它非常有效。 这是C编译器不会做的事情……(虽然通常可以在速度优化和规模优化之间进行选择,但我认为前者使用了一些类似的技巧。)

我知道有些人喜欢用汇编语言编写Windows应用程序。他们声称他们更快(很难证明)和更小(确实如此!)。 显然,虽然这样做很有趣,但可能会浪费时间(当然,学习目的除外!),特别是对于GUI操作…… 现在,也许某些操作(比如在文件中搜索字符串)可以通过精心编写的汇编代码进行优化。

使用SIMD指令的矩阵操作可能比编译器生成的代码更快。

我需要对192位或256位的每次中断进行移位操作,每50微秒发生一次。

它通过一个固定的映射(硬件限制)实现。使用C语言,制作它只需要大约10微秒。当我把它翻译到Assembler时,考虑到这个映射的特定特性,特定的寄存器缓存,并使用面向位的操作;它只花了不到3.5微秒的时间。

如果您没有查看编译器生成的内容的反汇编,您实际上无法知道编写良好的C代码是否真的很快。很多时候你会发现“写得好”是主观的。

因此,没有必要用汇编程序来获得最快的代码,但出于同样的原因,了解汇编程序当然是值得的。

CP/M-86版本的PolyPascal (Turbo Pascal的兄弟)的一个可能性是用机器语言例程取代“使用生物将字符输出到屏幕上”的功能,本质上是给定x、y和字符串放在那里。

这使得更新屏幕的速度比以前快得多!

二进制文件中有足够的空间来嵌入机器代码(几百个字节),也有其他的东西,所以尽可能多地压缩是必要的。

事实证明,由于屏幕是80x25,这两个坐标都可以容纳每个字节,所以都可以容纳两个字节的单词。这允许在更少的字节内完成所需的计算,因为单个添加可以同时操作两个值。

据我所知,没有C编译器可以在一个寄存器中合并多个值,对它们执行SIMD指令,然后再将它们分开(而且我不认为机器指令会更短)。