C / C ++使用特殊的CPU功能

时间:2010-05-17 21:39:28

标签: c++ sse mmx

我很好奇,新的编译器会使用内置在新CPU中的一些额外功能,例如MMX SSE,3DNow!所以?

我的意思是,在最初的8086中甚至没有FPU,所以旧的编译器甚至不能使用它,但是新的编译器可以,因为FPU是每个新CPU的一部分。那么,新的编译器是否使用了CPU的新功能?

或者,更新的问题是,新的C / C ++标准库函数是否使用新功能?

感谢您的回答。

编辑:

好的,所以,如果我能帮到你们所有人,即使是一些标准操作,特别是浮点数也可以更快地使用SSE完成。

为了使用它,我必须在我的编译器中启用此功能,如果它支持它。如果是这样,我必须确保目标平台支持该功能。

如果某些系统库需要最高性能,例如OpenGL,DirectX等,系统可能支持此支持。

默认情况下,出于兼容性原因,编译器不支持它,但您可以使用由Intel提供的特殊C函数来添加此支持。这应该是最好的方法,因为您可以直接控制天气以及何时使用所需平台的特殊功能来编写支持多CPU的应用程序。

9 个答案:

答案 0 :(得分:4)

gcc将通过命令行参数支持更新的指令。有关详细信息,请参阅here。引用:

  海湾合作委员会可以利用   MMX中的其他说明,   SSE,SSE2,SSE3和3dnow扩展   最近的英特尔和AMD处理器。   选项-mmmx,-msse,-msse2,   -msse3和-m3dnow允许使用这些额外的指令   要处理的多个数据字   在平行下。生成的可执行文件   只会在支持的处理器上运行   适当的扩展 - 在其他方面   他们将崩溃的系统   非法指令错误(或类似)

答案 1 :(得分:2)

这些说明不是任何ISO C / C ++标准的一部分。它们可以通过编译器内在函数获得,具体取决于所使用的编译器。

对于MSVC,请参阅http://msdn.microsoft.com/en-us/library/26td21ds(VS.80).aspx

对于GCC,您可以查看http://developer.apple.com/hardwaredrivers/ve/sse.html

AFAIK,SSE内在函数在GCC和MSVC之间是相同的。

答案 2 :(得分:1)

编译器的目标是为处理器中的一组最小功能生成代码。它们还提供编译开关,允许您定位特定的处理器。通过这种方式,他们可以销售更多的编译器(对于那些拥有旧处理器的人以及拥有新处理器的时尚人士)。

您需要学习编译器附带的文档。

答案 3 :(得分:1)

有时,运行时库将包含一个功能的多个实现,并且库将在程序运行时动态地在实现之间进行选择。开销可能是函数指针调用的代价而不是直接函数调用,但是当使用特定于CPU的优化函数时,好处可能会大得多。

JIT编译器(适用于Java和C#等VM语言)更进了一步,编译了运行它的特定 CPU的字节码。这为您自己的代码提供了特定CPU优化的好处。这就是为什么Java代码实际上比编译的C代码更快的一个原因,因为Java JIT编译器可以延迟其优化决策,直到程序在实际目标机器上运行。 C编译器必须在不知道目标CPU是什么的情况下做出这些决定。此外,JIT编译器不断发展,可以让您的程序随着时间的推移更快,而无需做任何事情。

答案 4 :(得分:1)

如果你使用英特尔C编译器,并设置足够高的优化选项,你会发现你的一些循环得到'矢量化',这意味着编译器已经重写它们以使用SSE风格的指令。

如果要直接使用SSE操作,可以使用'xmmintrin.h'头文件中定义的内在函数;说

#include< xmmintrin.h>

__ m128 U,V,W; 漂浮ww [4];

V = _mm_set1_ps(1.5);

U = _mm_set_ps(0,1,2,3);

W = _mm_add_ps(U,V);

_mm_storeu_ps(WW,W);

答案 5 :(得分:0)

不同的编译器将使用不同的新功能。 Visual Studio将使用SSE / 2,我相信英特尔编译器将支持最新的CPU功能。当然,您应该对您最喜欢的功能的市场渗透保持警惕 至于你最喜欢的标准库使用什么,这取决于它编译的内容。但是,C ++标准库通常是在现场编译的,因为它的模板非常大,所以如果启用SSE2,C ++ std库应该使用它。至于CRT,取决于他们编写的内容。

答案 6 :(得分:0)

编译器通常有两种方法可以生成使用如下特殊功能的代码:

  1. 编译器本身编译时,将其配置为为特定体系结构生成代码,并且它可以利用它知道体系结构将具有的任何功能。例如,如果为英特尔处理器配置了gcc足够新(或“不够老”?)以包含集成FPU,它将生成浮点指令。
  2. 当调用编译器时,标志或参数可以指定将运行程序的处理器可用的功能类型,然后编译器将知道使用这些功能是安全的。如果标志不存在,它将生成等效代码,而不使用这些功能提供的特殊指令。

答案 7 :(得分:0)

如果您正在讨论用C / C ++编写的代码,那么如果您告诉编译器这样做,则会探索新功能。默认情况下,您的编译器可能针对“普通x86”(当然使用FPU :)),通常针对目前最广泛的处理器生成进行了优化,但仍然可以在较旧的处理器上运行。

如果您希望编译器在考虑新指令集的情况下生成代码,您应该通过适当的命令行开关/项目设置告诉它,例如对于Visual C ++,启用SSE / SSE2指令生成的选项是/arch

请注意,新指令集的许多功能无法直接在“普通”代码中使用,因此通常会为您提供编译器内在函数,以便对新指令集本机的特定数据类型进行操作。

答案 8 :(得分:0)

英特尔每次发布新的CPU时都会提供更新的CPUID示例代码,以便您可以检查新功能,并且只要记得。至少这是我第一次自己想到这个问题时发现的。

Using CPUID to Detect the presence of SSE 4.1 and SSE 4.2 Instruction Sets

随着新编译器的发布,他们直接添加新功能,例如VS2010。 Visual C++ Code Generation in Visual Studio 2010