c - 包括正确的内在 header

标签 c gcc header intel intrinsics

我一直在阅读有关哪个头文件更适合访问英特尔内部函数的意见:x86intrin.himmintrin.h

两者似乎都达到了相同的结果,但我确信在代码可移植性方面一定存在一些细微的差异。也许其中一个比另一个更常见或更完整?

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

说到可移植性,对于较旧的编译器(例如gcc < v4.4.0),事情当然会变得更加复杂,而且两者都不可用。必须考虑包含另一个内部 header (可能是用于 SSE 支持的 emmintrin.h)。

最佳答案

(在此处发布答案,因为 Header files for x86 SIMD intrinsics 已过时的答案建议包含单独的头文件)。


<强> immintrin.h可跨所有编译器移植,并包含所有Intel SIMD 内在函数,以及一些标量扩展,例如 _pdep_u32可用 -mbmi2-march=其中包括它。 (对于 AMD SSE4a 和 XOP(仅限 Bulldozer 系列,为 Zen 放弃),您还需要包含不同的 header 。)

我能想到包括 <emmintrin.h> 的唯一原因具体来说,如果您使用 MSVC 并且希望为您不想依赖的 ISA 扩展保留未定义的内部函数。

GCC 的模型要求您先启用扩展,然后才能使用它们的内在函数,这意味着编译器会为您进行此检查,因此您只需 #include <immintrin.h>但如果您尝试使用 _mm_shuffle_epi8 仍然会出现错误( pshufb ) 没有 -mssse3 .

不要使用早于 gcc4.4 的编译器。它们已经过时,通常会生成较慢的代码,特别是对于在决定调优设置时还不存在的现代 CPU。


gcc/clang 的 x86intrin.h与 MSVC intrin.h仅当您需要一些额外的非 SIMD 内在函数(例如 MSVC 的 _BitScanReverse())时才有用。并不总是可以跨编译器移植。像整数旋转/位扫描内在函数这样的东西是基线(不像 BMI1 lzcnt/tzcnt 或 BMI2 rorx ),但很难或不可能以编译器能够识别并将循环转回循环的方式在 C 中表达单条指令。

英特尔在 their intrinsics guide 的 immintrin.h 中记录了其中一些可用的内容,但 gcc/clang 和 MSVC 实际上将它们放在 x86intrin.h 中或intrin.h分别是标题。

参见How to get the CPU cycle count in x86_64 from C++?例如使用#ifdef _MSC_VER选择正确的 header 来定义 uint64_t __rdtsc(void)__rdtscp() .

关于c - 包括正确的内在 header ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56049110/

相关文章:

c - 如何使用修复中的参数,修复是指针?

c - 如何从我生成的随机数组中删除重复元素?

C:#include 中的前缀

css - 仅使一个 Bootstrap header 无响应?

c# - 处理 WCF header 详细信息

c - 如何理解 UEFI 中的 struct typedef 组合?

c - 命令行参数如何工作?

c - C中的(一些)UTF8字符串函数是什么

linux - 无法执行 'x86_64-conda_cos6-linux-gnu-gcc' : No such file or directory (pysam installation)

javascript - 将以此格式声明的函数放入单个 .js 中以包含在其他文件中