优化器:优化内联汇编

时间:2016-11-13 19:39:25

标签: c++ assembly optimization

我曾多次听说编译器不会优化内联汇编,或者内联汇编对它来说是一个黑盒子。我很怀疑,因为我没有看到编译器失败的任何情况,我都不在乎。

但是今天我在GCC维基上找到了一个名为DontUseInlineAsm的页面。 它包含了人们之前告诉我的相同问题,但没有详细说明为什么编译器不能理解内联asm,因此不会对其进行优化。那么,有没有人知道编译器不做这些优化的原因?

当然,我会把像

这样的特殊情况收起来

asm volatile("" : : "g"(value) : "memory");
asm volatile("" : : : "memory");

当我们明确地告诉编译器这段代码有可见的副作用时,因此它不应该优化它。

2 个答案:

答案 0 :(得分:11)

您的问题似乎是基于编译器首先生成程序集的错误假设,然后,如果您想要优化输出,那么它会读取它生成的程序集,对其进行优化并将其写回。如果是这种情况,那么读取和优化内联汇编应该没什么大不了的,对吧?

编译器不会优化内联汇编,因为编译器根本不会优化任何汇编。编译器无法在所需级别上理解汇编,以便使用它执行优化。这不关它的事。

编译器通过对其内部数据结构(解析树,p代码等中间语言)执行特殊技巧来生成优化的机器代码,这些内容是 not 程序集。

如果涉及程序集生成步骤,则它是一个只写步骤,这意味着编译器将为您生成此程序集,但它永远不会尝试读取它。这是汇编程序的工作。我从来没有听说过优化的汇编程序。

因此,可以非常安全地假设没有编译器会尝试优化任何人的内联汇编。

而且我不了解你,但坦率地说,如果编译器试图修改我的内联汇编,我会非常恼火。如果我要使用汇编,我会这样做,因为我知道(或者我认为我知道)比编译器更好。

答案 1 :(得分:3)

编译器不会优化内联汇编,因为这会破坏目的。当程序员认为他们比编译器更清楚时,使用内联汇编,程序员认为他们可以生成更好的代码,或者编译器不能生成他们想要的代码。在前一种情况下,程序员自己正在优化汇编代码,如果编译器没有在优化等效C代码方面做得足够好,那么它不太可能它能够改进汇编代码。在后面的例子中,没有等效的C代码,内联汇编使用的是编译器无法生成的指令或其他汇编功能。在这种情况下,它也不太可能理解这些指令实际上为了优化代码而做了什么。

没有编译器能够将内联汇编转换为其内部"字节代码"正如你在评论中所建议的那样。 GCC将内联汇编视为字符串以粘贴到其程序集输出中。它完全不了解字符串中的代码。 Clang通常不会生成汇编作为输出,所以它有一个内置汇编程序,但它也不能真正理解汇编代码。它只是将其转换为机器代码,并将其插入到目标文件输出中。微软的编译器是另一个通常不会生成汇编代码输出的编译器,它实际上已经了解了汇编,但只是在有限的范围内。它只能理解代码使用的寄存器之类的内容,因此编译器会执行诸如保留内联汇编使用的寄存器之类的操作。它不知道汇编代码实际上做了什么。

如果您希望编译器优化代码,请不要使用内联汇编。即使它们不是一个直接对应于你想要的汇编代码的语言特性,编译器也许能够生成它,就像Mike Nakis在关于ROTL的评论中所建议的那样。您还可以使用内在函数,扩展语言的函数以及与各种汇编指令相对应的函数,编译器在许多情况下都能够进行优化。