<分区>
大多数编译器不优化内联汇编代码(VS2015,gcc),它允许我们编写它不支持的新指令。
但是 C/C++ 编译器什么时候应该实现内联汇编优化?
最佳答案
从来没有。这将违背内联汇编的目的,即准确获得您所要求的内容。
如果您想以编译器可以理解和优化的方式使用 objective-c PU 指令集的全部功能,您应该使用内部函数,而不是内联 asm.
例如而不是 popcnt
的内联汇编, 使用 int count = __builtin_popcount(x);
(在使用 -mpopcnt
编译的 GNU C 中)。 Inline-asm 也是特定于编译器的,所以如果有任何内在函数更可移植,特别是如果您使用英特尔的 x86 内在函数,所有可以针对 x86 的主要编译器都支持它。使用 #include <x86intrin.h>
你可以使用 int _popcnt32 (int a)
可靠地获得 popcnt
x86指令。参见 Intel's intrinsics finder/guide ,以及 x86 中的其他链接标记维基。
int count(){
int total = 0;
for(int i=0 ; i<4 ; ++i)
total += popc(i);
return total;
}
编译自#define popc _popcnt32
通过 gcc6.3:
mov eax, 4
ret
clang 3.9 with an inline-asm definition of popc
, on the Godbolt compiler explorer :
xor eax, eax
popcnt eax, eax
mov ecx, 1
popcnt ecx, ecx
add ecx, eax
mov edx, 2
popcnt edx, edx
add edx, ecx
mov eax, 3
popcnt eax, eax
add eax, edx
ret
这是内联 asm 击败常量传播的经典示例,如果可以避免,为什么不应该使用它来提高性能:https://gcc.gnu.org/wiki/DontUseInlineAsm .
这是我用于此测试的内联汇编定义:
int popc_asm(int x) {
// force use of the same register because popcnt has a false dependency on its output, on Intel hardware
// this is just a toy example, though, and also demonstrates how non-optimal constraints can lead to worse code
asm("popcnt %0,%0" : "+r"(x));
return x;
}
如果你不知道 popcnt
has a false dependency on its output register on Intel hardware ,这是您应尽可能将其留给编译器的另一个原因。
使用编译器不知道的特殊指令是内联汇编的一个用例,但如果编译器不知道它,它肯定无法优化它。在编译器擅长优化内在函数(例如 SIMD 指令)之前,这种事情的内联 asm 更为常见。但我们现在已经过了很多年,编译器通常对内在函数很好,即使对于像 ARM 这样的非 x86 架构也是如此。
关于c++ - 编译器何时会优化 C/C++ 源代码中的汇编代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41294779/