针对x86 SIMD内部函数头文件针对x86 SIMD内部函数头文件(Header files fo

2019-06-14 06:47发布

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

Answer 1:

<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

<zmmintrin.h> AVX512


Answer 2:

如果你只使用

#include <x86intrin.h>

它将包括其根据编译器开关等使所有SSE / AVX头-march=corei7或只是-march=native 。 另外像一些特定的x86指令bswapror成为可用内部函数。



Answer 3:

头名取决于你的编译器和目标架构。

  • 对于Microsoft C ++(针对X86,X86-64或ARM)和Intel C / C ++编译器Windows使用intrin.h
  • 对于GCC /铛/ ICC目标的x86 / x86-64的使用x86intrin.h
  • 对于GCC /铛/定位器armcc ARM NEON与使用arm_neon.h
  • 对于GCC /铛/定位器armcc ARM与WMMX使用mmintrin.h
  • 对于GCC /铛/ xlcc与VMX(又名AltiVec技术)和/或使用VSX靶向的PowerPC altivec.h
  • 对于GCC /铛瞄准用的PowerPC SPE使用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


Answer 4:

从这个页面

+----------------+------------------------------------------------------------------------------------------+
|     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             |
+----------------+------------------------------------------------------------------------------------------+

所以一般你可以只包括immintrin.h拿到所有的英特尔扩展,或者x86intrin.h如果你想要的一切,包括_bit_scan_forward_rdtsc ,以及所有矢量内在函数包括AMD-唯一的。 如果你反对,包括更多的实际需要,那么你可以通过查看表中选择正确的包括。

x86intrin.h是推荐的方式来获得内在AMD XOP(推土机只,甚至没有未来的AMD处理器) ,而不是它自己的头。

一些编译器仍然会产生错误信息,如果你使用你没有启用指令集内部函数(如_mm_fmadd_ps而不启用FMA,即使你有immintrin.h并启用AVX2)。



Answer 5:

由于许多的答案和评论所指出的, <x86intrin.h>是用于x86 [-64] SIMD内在综合报头。 它还提供内在支持其他ISA扩展指令。 gccclang ,以及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

  • x86intrin.h似乎让所有人都得到了支持clang-3.x版本。 最新的稳定版本是clang (LLVM) 3.9.1 。 开发分支clang (LLVM) 5.0.0 。 目前还不清楚发生了什么事到4.x系列。

  • 苹果铛 :烦人的,苹果的版本不与该对应LLVM项目。 这就是说,当前版本: clang-800.0.42.1 ,是基于LLVM 3.9.0 。 第一LLVM 3.0基于版本似乎是Apple clang 2.1在后面Xcode 4.1LLVM 3.1第一次出现与Apple clang 3.1在(数字巧合) Xcode 4.3.3

    苹果还定义__apple_build_version__例如, 8000042 。 这似乎对最稳定的,严格升版本方案。 如果您不想支持传统的编译器,make最起码的要求,这些值之一。

任何最近的版本clang ,包括苹果的版本,因此应该有任何问题x86intrin.h 。 当然,随着gcc-5你总是可以使用以下命令:

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

一个窍门你真的不能依靠使用__GNUC__的版本clang 。 该版本是,由于历史的原因,停留在4.2.1 。 先于A版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)作为版本测试。 当然,如果你想编写的代码,是在所有这些不同的编译器随身携带,在这个平台上的标题名称将是至少你的问题。



文章来源: Header files for x86 SIMD intrinsics