汇编语言和编译语言

时间:2009-12-08 11:15:24

标签: performance compiler-construction assembly

如果两者都转换为机器代码,汇编语言如何比编译语言更快?

我说的是真正编译的语言,它们被翻译成机器代码。不是C#或Java,它们首先被编译成中间语言,然后由软件解释器等编译为本机代码。

Wikipedia上,我发现了一些我不确定与此有什么关系的东西。是因为从更高级别的语言翻译会产生额外的机器代码吗?或者我的理解错了吗?

  

一个名为汇编程序的实用程序用于将汇编语言语句转换为目标计算机的机器代码。汇编程序从助记语句到机器指令和数据执行或多或少的同构转换(一对一映射)。 这与高级语言形成对比,在高级语言中,单个语句通常会产生许多机器指令

8 个答案:

答案 0 :(得分:23)

嗯,这确实与你的问题有点关系。重点是编译器由于各种原因有时会产生低效的机器代码,例如无法完全分析代码,插入自动范围检查,自动检查null等对象。

另一方面,如果您手动编写汇编代码并且知道您正在做什么,那么您可以编写一些比编译器更有效的东西,尽管编译器的行为可能会被调整例如,你通常可以告诉它不要进行范围检查。

然而,大多数人不会编写比编译器更好的汇编程序代码,因为编译器是由那些知道很多非常奇怪但非常酷的优化的人编写的。此外,循环展开通常很难自己编写,并且在许多情况下使得生成的代码更快。

虽然计算机执行的所有内容通常都是机器代码,但运行的代码根据您在机器和程序员之间放置的抽象级别而有很大差异。对于Assembler而言,对于Java来说,还有一些......还有更多...

此外,许多人错误地认为在较高抽象层的某些优化会在较低的抽象层获得回报。情况不一定如此,编译器可能无法理解您要执行的操作并且无法正确优化它。

答案 1 :(得分:8)

如果汇编程序员编写的程序集比编译器生成的程序集更好,那么汇编有时可能比编译语言更快。

编译语言通常比汇编更快,因为编写编译器的程序员通常比常规程序员更了解CPU架构。

答案 2 :(得分:4)

汇编专家可能能够编写比编译器自动生成的更有效(更少指令,更有效的指令,SIMD ......)的汇编代码。

但是,大多数情况下,您最好信任编译器的优化器。

Learn what your compiler does. Then let the compiler do it.

答案 3 :(得分:2)

当关于集会与高级别的问题出现时,我的标准答案是看看Michael Abrash的Graphics Programming Black Book

前几章很好地介绍了使用装配可以有效优化的内容,以及不可以的内容。

你可以download it from GameDev - 不幸的是,杰夫的链接现在似乎已被破坏了。

答案 4 :(得分:2)

所有好的答案。我唯一的另一点是,程序员倾向于每天编写一定数量的代码行,而不管语言如何。由于高级语言的优势在于它可以让您使用更少的代码完成更多工作,因此实际上编写更少的代码需要令人难以置信的程序员纪律。

这对于性能尤其是一个问题,因为除了代码的一小部分外,几乎无处不在。它只在您的热点中起作用 - 您编写的代码(1)在不调用函数(3)的情况下消耗了大部分执行时间(2)。

答案 5 :(得分:1)

首先 - 汇编程序应仅用于小代码段,这些代码段占用程序中的大部分CPU时间 - 例如某种计算 - 在算法的“瓶颈”中。

其次 - 它取决于那些在Assembler中实现相同代码的人的ASM经验。如果“瓶颈”代码的汇编程序实现会更快。如果经验很低 - 它会慢一些。它会包含很多错误。如果经验足够高 - ASM将带来巨大的利润。

答案 6 :(得分:1)

首先,编译器生成非常好(快速)的汇编代码。

编译器确实可以添加额外的代码,因为高阶语言有机制,比如C ++中的虚方法和异常。因此编译器必须生成更多代码。在某些情况下,原始程序集可以加速代码,但现在这种情况很少见。

答案 7 :(得分:1)

  

如果两者都转换为机器代码,汇编语言如何比编译语言更快?

隐含的假设是手写汇编代码。当然,大多数编译器(例如,GCC用于C,C ++,Fortran,Go,D等...)正在生成一些汇编代码;例如,您可以使用foo.cc编译g++ -fverbose-asm -Wall -S -O2 -march=native foo.cc C ++源代码,并查看生成的foo.s汇编代码。

然而,高效的汇编程序代码难以编写,今天,编译器可以optimize比人类更好。请参阅this

实际上,不值得在汇编程序中编码(另外,考虑到开发工作的成本通常远远超过运行编译代码的硬件)。即使性能很重要并且值得花费很多钱,最好只在汇编程序中编写很少的例程,甚至在一些C例程中编写embed some assembler代码。

查看CppCon 2017讲座:Matt Godbolt “What Has My Compiler Done for Me Lately? Unbolting the Compiler's Lid”