现代编译器如何使用mmx / 3dnow / sse指令?

时间:2009-05-18 00:02:46

标签: gcc compiler-construction x86 sse assembly

我一直在阅读x86指令集扩展,它们在某些特定情况下似乎很有用(例如SSE3中的HADDPD - (Horizo​​ntal-Add-Packed-Double))。这些需要一个特定的寄存器布局,需要有意设置,或者从它之前的一系列指令中进行。像gcc这样的通用编译器多长时间实际使用这些指令(或其子集),还是主要用于手工编码的汇编程序?编译器如何检测使用SIMD指令的适当位置?

5 个答案:

答案 0 :(得分:23)

通常,很少有编译器使用它们。 GCC和Visual Studio通常不能使用SIMD指令。如果将SSE作为编译器标志启用,它将使用标量SSE指令进行常规浮点运算,但通常不要指望自动使用向量化的指令。最新版本的GCC可能在某些情况下可以使用它们,但最后我试过没有用。英特尔的C ++编译器是我所知道的唯一可以自动向量化循环的大型编译器。

一般来说,你必须自己使用它们。在原始汇编程序中,或使用编译器内在函数。一般来说,我认为内在函数是更好的方法,因为它们更好地允许编译器理解代码,因此安排和优化,但在实践中,我知道MSVC至少并不总是从内在函数生成非常有效的代码,所以普通的asm可能是那里最好的解决方案。实验,看看有效。但是不要指望编译器为你使用这些指令,除非你1)使用正确的编译器,2)编写可以简单地向量化的相当简单的循环。

2012年更新
好吧,自从我写这个答案以来已经过了三年了。 GCC已经能够自动矢量化(简单)代码几年了,而在VS2012中,MSVC 最终获得了相同的功能。当然,我的答案的主要部分仍然适用:编译器仍然只能矢量化相当简单的代码。对于任何更复杂的事情,你都会陷入内在函数或内联asm的困境。

答案 1 :(得分:9)

Mono可以使用SIMD扩展,只要您将其类用于向量即可。您可以在此处阅读:http://tirania.org/blog/archive/2008/Nov-03.html

只要您使用-O3或特定标志,GCC就应该进行一些自动矢量化。他们在这里有一个信息页面:http://gcc.gnu.org/projects/tree-ssa/vectorization.html

答案 2 :(得分:4)

如何自动开发SSE和其他小型向量单元的问题(没有来自程序员的特殊语言结构或特殊祝福编译器“内在函数”)的指导一直是编译器的主题研究了一段时间。大多数结果似乎专门针对特定问题域,例如digital signal processing。我没有跟上关于这个主题的文献,但是我已经阅读的内容表明,利用向量(SSE)单元仍然是研究的主题,而且应该对一般情况的期望值低 - 在该领域常用的目的编译器。

建议的搜索字词:向量化编译器

答案 3 :(得分:1)

我已经看到gcc使用sse将默认的std :: string对象清零。 sse并不是特别强大的用法,但是它存在。在大多数情况下,尽管您必须自己编写。

我之所以知道这一点,是因为我让堆栈变得未对齐并且崩溃了,否则我可能不会注意到!

答案 4 :(得分:0)

如果您使用矢量pascal编译器,您将获得SIMD优势类型的高效SIMD代码。基本上这是长度小于64位的任何东西。 (对于64位实数,执行SIMD实际上更慢)。 最新版本的编译器也将自动并行核心