我一直在阅读意见,以便更好地包含哪个头文件来访问Intel的内在函数:x86intrin.h
或immintrin.h
。
两者似乎都取得了相同的结果,但是我确信在代码可移植性方面必须存在一些细微的差异。也许一个比另一个更普遍或更完整?
我找不到任何解释。如果有人知道为什么有2个文件,以及它们有什么区别,那将是一个受欢迎的SO答案。
说到可移植性,对于较旧的编译器(例如gcc
emmintrin.h
)。
答案 0 :(得分:3)
(在此处发布答案,因为Header files for x86 SIMD intrinsics的答案过时,建议包含单个头文件)。
immintrin.h
可在所有编译器中移植,并包括所有 Intel SIMD内部函数,以及一些标量扩展,例如BMI2 _pdep_u32
。 (对于AMD SSE4a和XOP(仅适用于Bulldozer系列,仅适用于Zen),您还需要包含其他标头。)
我可以想到的唯一包含<emmintrin.h>
的唯一原因是,如果您使用的是MSVC,并且希望为不需要的ISA扩展保留未定义的内在函数。
GCC的模型要求您在使用内部函数之前先启用扩展,这意味着编译器会为您进行此检查,因此您只能#include <immintrin.h>
,但是如果尝试使用{{1}仍然会出错}(_mm_shuffle_epi8
,而没有pshufb
。
请勿使用早于gcc4.4的编译器。它们已过时,并且通常会生成较慢的代码,尤其是对于决定调整设置时不存在的现代CPU。< / p>
gcc / clang的-mssse3
与MSVC x86intrin.h
仅在需要一些非SIMD内在函数(例如MSVC的intrin.h
)时才有用,而这些非SIMD内在函数并不总是可以在编译器之间移植。诸如整数旋转/位扫描内在函数之类的东西(它们是基线)(不同于BMI1 {_BitScanReverse()
/ lzcnt
或BMI2 tzcnt
),但是很难或不可能以C表示,编译器会识别并将循环转回一条指令。
英特尔在their intrinsics guide的immintrin.h中记录了其中一些文件,但是gcc / clang和MSVC实际上分别在它们的rorx
或x86intrin.h
标头中包含了它们。
有关使用intrin.h
选择正确的标题以定义#ifdef _MSC_VER
和uint64_t __rdtsc(void)
的示例,请参见Get CPU cycle count?。