x86 SIMD内在函数的头文件

fre*_*low 121 x86 sse simd header-files intrinsics

哪些头文件为不同的x86 SIMD指令集扩展(MMX,SSE,AVX,...)提供内在函数?似乎不可能在网上找到这样的清单.如我错了请纠正我.

fre*_*low 161

<mmintrin.h>  MMX
<xmmintrin.h> SSE
<emmintrin.h> SSE2
<pmmintrin.h> SSE3
<tmmintrin.h> SSSE3
<smmintrin.h> SSE4.1
<nmmintrin.h> SSE4.2
<ammintrin.h> SSE4A
<wmmintrin.h> AES
<immintrin.h> AVX, AVX2, FMA
Run Code Online (Sandbox Code Playgroud)

  • 或者你可以只是`#include <x86intrin.h>`它可以提供你需要的一切. (61认同)
  • 不要直接包含`<zmmintrin.h>`; gcc甚至没有提供它.**只需使用`<immintrin.h>`**或更完整的`<x86intrin.h>`.这个答案基本上是过时的,除非你故意避免为更新版本的SSE包含内在函数,因为在编译SSE2时你的编译器没有抱怨你使用SSE4.1指令.(gcc/clang*do*抱怨,所以你应该只使用immintrin.h.IDK关于其他人.) (13认同)
  • @LưuVĩnhPhúcSSE3= Prescott新指令,SSSE3 = Tejas新指令.我认为SSE4.2和AES是指它们被引入的处理器系列(Nehalem和Westmere) (5认同)
  • 为什么SS,3,SSSE3/SSE4.1和4.2的p,t,s和n?这些角色代表什么? (3认同)
  • zmmintrin.h具有AVX-512内在函数. (2认同)

Gun*_*iez 71

如果你只使用

#include <x86intrin.h>
Run Code Online (Sandbox Code Playgroud)

它将包括其根据编译器开关等使所有SSE/AVX头-march=haswell或只是-march=native.此外,一些x86特定指令喜欢bswapror可用作内在函数.

  • +1,我还会注意到Visual C++没有那个标题. (16认同)
  • MSVC没有`<x86intrin.h>`,但`<intrin.h>`实现了类似的效果.当然,你还需要条件编译.:-( (5认同)

Mar*_*han 57

标头名称取决于您的编译器和目标体系结构.

  • 适用于Microsoft C++(针对x86,x86-64或ARM)和适用于Windows的英特尔C/C++编译器 intrin.h
  • 对于gcc/clang/icc,目标x86/x86-64使用 x86intrin.h
  • 对于使用NEON定位ARM的gcc/clang/armcc arm_neon.h
  • 对于使用WMMX的gcc/clang/armcc目标ARM mmintrin.h
  • 对于gcc/clang/xlcc,使用VMX(又名Altivec)和/或VSX使用PowerPC altivec.h
  • 对于使用SPE的gcc/clang定位PowerPC spe.h

您可以使用条件预处理指令处理所有这些情况:

#if defined(_MSC_VER)
     /* Microsoft C/C++-compatible compiler */
     #include <intrin.h>
#elif defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__))
     /* GCC-compatible compiler, targeting x86/x86-64 */
     #include <x86intrin.h>
#elif defined(__GNUC__) && defined(__ARM_NEON__)
     /* GCC-compatible compiler, targeting ARM with NEON */
     #include <arm_neon.h>
#elif defined(__GNUC__) && defined(__IWMMXT__)
     /* GCC-compatible compiler, targeting ARM with WMMX */
     #include <mmintrin.h>
#elif (defined(__GNUC__) || defined(__xlC__)) && (defined(__VEC__) || defined(__ALTIVEC__))
     /* XLC or GCC-compatible compiler, targeting PowerPC with VMX/VSX */
     #include <altivec.h>
#elif defined(__GNUC__) && defined(__SPE__)
     /* GCC-compatible compiler, targeting PowerPC with SPE */
     #include <spe.h>
#endif
Run Code Online (Sandbox Code Playgroud)


ece*_*ulm 42

从这个页面

+----------------+------------------------------------------------------------------------------------------+
|     Header     |                                         Purpose                                          |
+----------------+------------------------------------------------------------------------------------------+
| x86intrin.h    | Everything, including non-vector x86 instructions like _rdtsc().                         |
| mmintrin.h     | MMX (Pentium MMX!)                                                                       |
| mm3dnow.h      | 3dnow! (K6-2) (deprecated)                                                               |
| xmmintrin.h    | SSE + MMX (Pentium 3, Athlon XP)                                                         |
| emmintrin.h    | SSE2 + SSE + MMX (Pentium 4, Athlon 64)                                                  |
| pmmintrin.h    | SSE3 + SSE2 + SSE + MMX (Pentium 4 Prescott, Athlon 64 San Diego)                        |
| tmmintrin.h    | SSSE3 + SSE3 + SSE2 + SSE + MMX (Core 2, Bulldozer)                                      |
| popcntintrin.h | POPCNT (Nehalem (Core i7), Phenom)                                                       |
| ammintrin.h    | SSE4A + SSE3 + SSE2 + SSE + MMX (AMD-only, starting with Phenom)                         |
| smmintrin.h    | SSE4_1 + SSSE3 + SSE3 + SSE2 + SSE + MMX (Penryn, Bulldozer)                             |
| nmmintrin.h    | SSE4_2 + SSE4_1 + SSSE3 + SSE3 + SSE2 + SSE + MMX (Nehalem (aka Core i7), Bulldozer)     |
| wmmintrin.h    | AES (Core i7 Westmere, Bulldozer)                                                        |
| immintrin.h    | AVX, AVX2, AVX512, all SSE+MMX (except SSE4A and XOP), popcnt, BMI/BMI2, FMA             |
+----------------+------------------------------------------------------------------------------------------+
Run Code Online (Sandbox Code Playgroud)

因此,一般情况下,您可以包括immintrin.h获取所有英特尔扩展,或者x86intrin.h如果您想要所有内容,包括_bit_scan_forward_rdtsc,以及所有向量内在函数都包含仅限AMD的扩展.如果您反对包含您实际需要的更多内容,那么您可以通过查看表格来选择正确的包含.

x86intrin.h是推荐的AMD XOP(仅限Bulldozer,甚至未来的AMD CPU)内在函数的方法,而不是拥有自己的头文件.

如果您对未启用的指令集使用内在函数(例如,_mm_fmadd_ps未启用fma,即使包含immintrin.h并启用AVX2),某些编译器仍将生成错误消息.


Bre*_*ale 12

正如许多答案和评论所述,<x86intrin.h>是x86 [-64] SIMD内在函数综合标题.它还为其他ISA扩展提供内在支持指令.gcc,clang并且icc都已经解决了这个问题.我需要对支持标题的版本进行一些挖掘,并认为列出一些调查结果可能很有用......

  • gcc:x86intrin.h首先出现支持gcc-4.5.0.该gcc-4发行版系列将不再被保持,同时gcc-6.x当前稳定版本系列.gcc-5还介绍了__has_include所有clang-3.x版本中的扩展.gcc-7在预发布(回归测试等)并遵循当前的版本控制方案,将作为发布gcc-7.1.0.

  • clang:x86intrin.h似乎已经支持所有clang-3.x版本.最新的稳定版本是clang (LLVM) 3.9.1.开发部门是clang (LLVM) 5.0.0.目前尚不清楚该4.x系列赛发生了什么.

  • Apple clang:令人讨厌的是,Apple的版本控制与LLVM项目的版本不符.也就是说,目前的发布:clang-800.0.42.1是基于LLVM 3.9.0.第一个LLVM 3.0基础版本似乎Apple clang 2.1又回来了Xcode 4.1.LLVM 3.1首先出现Apple clang 3.1(数字巧合)Xcode 4.3.3.

    Apple还定义了__apple_build_version__例如8000042.这似乎是最稳定,严格提升的版本控制方案.如果您不想支持旧版编译器,请将其中一个值作为最低要求.

clang因此,包括Apple版本在内的任何最新版本都应该没有问题x86intrin.h.当然gcc-5,您可以随时使用以下内容:

#if defined (__has_include) && (__has_include(<x86intrin.h>))
#include <x86intrin.h>
#else
#error "upgrade your compiler. it's free..."
#endif
Run Code Online (Sandbox Code Playgroud)

您无法真正依赖的一个技巧是使用__GNUC__版本clang.由于历史原因,版本控制被困在4.2.1.x86intrin.h标题之前的版本.例如,对于保持向后兼容的简单GNU C扩展,它偶尔会有用.

  • icc:据我所知,x86intrin.h至少从英特尔C++ 16.0开始支持标头.版本测试可以通过以下方式执行:#if (__INTEL_COMPILER >= 1600).此版本(可能还有早期版本)也为__has_include扩展提供支持.

  • MSVC:看来这MSVC++ 12.0 (Visual Studio 2013)是第一个提供intrin.h标题的版本- 不是 x86intrin.h ......这表明:#if (_MSC_VER >= 1800)作为版本测试.当然,如果您正在尝试编写可在所有这些不同编译器中移植的代码,则此平台上的标题名称将是您遇到的最少问题.