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

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

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


当前回答

在历史上插话。

当我还年轻的时候(20世纪70年代),根据我的经验,汇编是很重要的,更重要的是代码的大小,而不是代码的速度。

如果一个高级语言的模块是1300字节的代码,但该模块的汇编版本是300字节,那么当您试图将应用程序装入16K或32K的内存时,这1K字节就非常重要。

那时候编译器还不是很好。

在老式的Fortran中

X = (Y - Z)
IF (X .LT. 0) THEN
 ... do something
ENDIF

当时的编译器在X上执行了一个SUBTRACT指令,然后是一个TEST指令。 在汇编程序中,您只需在减法之后检查条件代码(LT零,零,GT零)。

对于现代系统和编译器来说,这些都不是问题。

我认为理解编译器在做什么仍然很重要。 当您使用高级语言编写代码时,您应该了解什么允许或阻止编译器执行循环展开。

当编译器执行“类似分支”的操作时,使用管道内衬和包含条件的前瞻计算。

当执行高级语言不允许的事情时,仍然需要汇编程序,比如读取或写入处理器特定的寄存器。

但在很大程度上,普通程序员不再需要它,除非对代码如何编译和执行有基本的了解。

其他回答

Walter Bright的《optimization Immutable and Purity》可能值得一看,它不是一个概要测试,但向您展示了手写和编译器生成ASM之间的区别。Walter Bright写优化编译器,所以值得一看他的其他博客文章。

我曾经和一个人一起工作过,他说“如果编译器笨到不能弄清楚你要做什么,并且不能优化它,那么你的编译器就坏了,是时候换一个新的了”。我确信在某些情况下汇编程序会打败你的C代码,但是如果你发现自己经常使用汇编程序来“赢得”编译器,那么你的编译器就完蛋了。

对于编写试图强制查询计划器执行操作的“优化”SQL也是如此。如果您发现自己重新安排查询以让计划器执行您想要的操作,那么您的查询计划器就完蛋了——请更换一个新的计划器。

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

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

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

很多年前,我教别人用c语言编程。练习是将图形旋转90度。他得到了一个花了几分钟才能完成的解,主要是因为他使用了乘法和除法等。

我向他展示了如何使用位移位重定义问题,在他拥有的非优化编译器上,处理时间缩短到大约30秒。

我刚刚得到了一个优化编译器,相同的代码在< 5秒内旋转图形。我看着编译器生成的汇编代码,从我所看到的,我决定我写汇编程序的日子结束了。