其头文件提供了不同的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指令bswap
或ror
成为可用内部函数。
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扩展指令。 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
。铛 :
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.1
。LLVM 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)
作为版本测试。 当然,如果你想编写的代码,是在所有这些不同的编译器随身携带,在这个平台上的标题名称将是至少你的问题。