我一直在阅读x86指令集扩展,它们仅在某些特定情况下才有用(例如,SSE3中的HADDPD-(Horizontal-Add-Packed-Double))。这些要求特定的寄存器布局,需要有意设置或从其之前的一系列指令中进行设置。诸如gcc之类的通用编译器实际上多久使用一次这些指令(或其子集),或者它们主要用于手工编码的汇编程序中?编译器如何检测适合使用SIMD指令的位置?
最佳答案
通常,很少有编译器使用它们。 GCC和Visual Studio通常无法使用SIMD指令。如果启用SSE作为编译器标志,它将使用标量SSE指令进行常规浮点运算,但是通常,不要期望矢量化的指令会自动使用。在某些情况下,最新版本的GCC可能可以使用它们,但我尝试上一次却没有用。英特尔的C++编译器是我所知道的唯一能够自动向量化某些循环的大型编译器。
通常,您必须自己使用它们。要么在原始汇编器中,要么通过使用编译器内部函数。总的来说,我会说内在函数是更好的方法,因为它们可以使编译器更好地理解代码,从而进行调度和优化,但是实际上,我知道至少MSVC并不总是从内在函数生成非常有效的代码,因此普通的asm可能是那里最好的解决方案。实验,看看有什么用。但是不要指望编译器为您使用这些指令,除非您1)使用正确的编译器,以及2)编写可以简单向量化的相当简单的循环。
2012年更新
好的,自从我写这个答案以来已经过去了三年。 GCC能够自动矢量化(简单)代码已有两年了,在VS2012中,MSVC最终获得了相同的功能。当然,我的答案的主要部分仍然适用:编译器仍然只能向量化相当琐碎的代码。对于更复杂的事情,您会被困于内在函数或内联汇编。
关于gcc - 现代编译器如何使用mmx/3dnow/sse指令?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/875791/