【问题标题】:Assembly language and compiled languages汇编语言和编译语言
【发布时间】:2010-12-24 09:23:39
【问题描述】:

如果将两者都翻译成机器代码,汇编语言比编译语言更快吗?

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

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

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

【问题讨论】:

  • 请注意,大多数高级语言编译器首先编译为汇编代码,然后由单独的汇编器编译。因此,(最佳)汇编程序永远不会比已编译的源代码慢。如果您的(非最佳)汇编速度较慢,您可以将代码与编译器生成的代码交换,并做一些比尝试编写高效汇编程序更有用的事情。

标签: performance compiler-construction assembly


【解决方案1】:

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

编译语言通常比汇编更快,因为编写编译器的程序员通常比在一次性、有限情况下使用汇编的程序员更了解 CPU 架构。

【讨论】:

  • 情况恰恰相反:手写汇编通常比编译源代码慢,因为想成为汇编程序员的人根本不知道。
  • 不,一些程序员和编译器编写者一样了解 CPU 架构。然而,优化是一个非常困难的问题,计算机(运行编译器)通常会比聪明的程序员做得更好。
  • 对于单个热循环,通常可以使用手写 asm 击败编译器。但是在大范围内,不断的传播和各种内联的可能性使得使用 asm 来做更多的事情是不可维护的。理想情况下,您可以手持编译器通过调整源代码来制作漂亮的 asm,让您两全其美。 (现在是好的 asm, 将来适用于不同的 CPU,或不同的用例或周围的代码)。请参阅C++ code for testing the Collatz conjecture faster than hand-written assembly - why? 进行讨论。
【解决方案2】:

如果将两者都翻译成机器代码,汇编语言比编译语言更快吗?

隐含的假设是手写汇编代码。当然,大多数编译器(例如 C、C++、Fortran、Go、D 等的 GCC)正在生成一些汇编代码;例如,您可以使用g++ -fverbose-asm -Wall -S -O2 -march=native foo.cc 编译您的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”

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

    • 并指出“如果经验足够高”比大多数人想象的要罕见:编译器比大多数认为自己比编译器更聪明的人更聪明。
    【解决方案4】:

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

    但是,大多数时候,您最好相信编译器的优化器。

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

    【讨论】:

    • 此外,程序集导出将能够充分利用处理器的寄存器和指令扩展,在不访问外部存储器的情况下执行大部分计算,从而显着提升。当然,这取决于您是否针对一个或多个处理器...
    • @Laurent:这也取决于你的编译器。没有理由专门的编译器不能做到这一点。
    • 我考虑过链接这些幻灯片。这实际上是编译器知道的一系列巧妙技巧,但许多出于性能原因尝试编写程序集的人却不知道。
    • 麻烦(以及编写程序集的原因)是编译器可以做很多事情但不能做。
    • 很多人编写程序集的问题是他们经常在分析他们的应用程序之前就这样做了:)
    【解决方案5】:

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

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

    然而,大多数人不会编写比编译器更好的汇编代码,这仅仅是因为编译器是由知道大量非常奇怪但非常酷的优化的人编写的。此外,循环展开之类的东西通常会让您自己编写并在许多情况下使生成的代码更快。

    虽然计算机执行的所有内容通常都是机器代码,但运行的代码会有很大差异,具体取决于您在机器和程序员之间设置了多少抽象级别。对于 Assembler 来说这是一个层次,对于 Java 来说还有更多......

    还有很多人错误地认为,在较高抽象层进行的某些优化会在较低抽象层得到回报。情况不一定如此,编译器可能只是难以理解您正在尝试做什么并且无法正确优化它。

    【讨论】:

    • 这意味着汇编代码通常可能不会比编译代码(C/C++)快?
    • 如果您知道自己在做什么,则手写汇编代码可以比编译代码更快。大多数时候,它不会。
    • 取决于编写它的人。请参阅 yu_sha 的回答,它很好地总结了这一点。编译器实际上有一套固定的规则来更有效地编写某些东西;这些最终是由人创造的。那些可能能够使这些东西适应其他情况并产生比编译器更有效的代码的人。但在许多情况下,编译器在这些事情上要好得多。对于那些失败的sn-ps,您仍然可以使用内联汇编器,但如果您切换到更好/更新的编译器,它的运行速度会比原始代码慢,请不要感到惊讶。
    • 我通常将其与手动变速箱和自动变速箱的汽车之间的区别进行比较。人们说手动变速箱的燃油经济性更好,如果驾驶员非常熟练确实如此,因为它可以让他更好地控制,而这种控制可以让熟练的驾驶员以最佳方式换档。如果驾驶员不确切知道自己在做什么,那么更好的控制意味着他实际上会比自动驾驶汽车做得更差。
    • @iuppiter:现代编译器比 28 年前要好多了,而且我们不再为分段 x86 进行编译。扁平内存模型更容易优化。但是,您仍然可以经常在本地范围内击败编译器(对于热循环);不幸的是,错过的优化仍然很常见,其中一些很重要,而另一些则不重要。见Why is this C++ code faster than my hand-written assembly for testing the Collatz conjecture? :)
    【解决方案6】:

    所有好的答案。我唯一要补充的一点是,无论语言如何,程序员都倾向于每天编写一定数量的代码。由于高级语言的优势在于它可以让您用更少的代码完成更多的工作,因此实际上编写更少的代码需要非常严格的程序员纪律。

    这对于性能来说尤其是一个问题,因为它在任何地方都无关紧要,除了代码的一小部分。它只在您的热点中很重要 - 您编写的代码 (1) 会消耗很大一部分执行时间 (2) 而无需调用函数 (3)。

    【讨论】:

      【解决方案7】:

      当出现有关装配与高级别的问题时,我的标准答案是查看 Michael Abrash 的 Graphics Programming Black Book

      前几章很好地说明了使用汇编可以有效优化哪些方面,以及不能优化哪些方面。

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

      【讨论】:

        【解决方案8】:

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

        编译器确实可以添加额外代码,因为高阶语言具有机制,例如 C++ 中的虚拟方法和异常。因此编译器将不得不产生更多的代码。在某些情况下,原始汇编可以加快代码速度,但如今这种情况很少见。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-09-16
          • 2014-10-07
          相关资源
          最近更新 更多