包括正确的内部标头

时间:2019-05-08 21:11:38

标签: c gcc header intel intrinsics

我一直在阅读意见,以便更好地包含哪个头文件来访问Intel的内在函数:x86intrin.himmintrin.h

两者似乎都取得了相同的结果,但是我确信在代码可移植性方面必须存在一些细微的差异。也许一个比另一个更普遍或更完整?

我找不到任何解释。如果有人知道为什么有2个文件,以及它们有什么区别,那将是一个受欢迎的SO答案。

说到可移植性,对于较旧的编译器(例如gcc 另一个内在标头(对于SSE支持,可能是emmintrin.h)。

1 个答案:

答案 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实际上分别在它们的rorxx86intrin.h标头中包含了它们。

有关使用intrin.h选择正确的标题以定义#ifdef _MSC_VERuint64_t __rdtsc(void)的示例,请参见Get CPU cycle count?