非SIM内在函数的隐式定义

时间:2018-10-20 04:26:01

标签: c gcc intrinsics

在下面的链接中,有一个部分介绍了非siml intel内在函数: https://software.intel.com/sites/landingpage/IntrinsicsGuide/

这些包括汇编指令,例如bsf和bsr。对于SIMD指令,我可以复制c函数并在包含适当的标头之后运行它。

对于非Simd函数,例如_bit_scan_reverse(bsr),我得到了gcc(隐式定义)未定义此函数的信息。 GCC具有类似的“内置功能”,例如__builtin_ctz,但没有_bit_scan_reverse_mm_popcnt_u32。为什么这些内在函数不可用?

#include <stdio.h>
#include <immintrin.h>

int main(void) {
  int x = 5;
  int y = _bit_scan_reverse (x);
  printf("%d\n",y);
  return 0;
}

1 个答案:

答案 0 :(得分:2)

看来我需要进行两项更改:

首先,似乎最好的做法是包含x86intrin.h而不是更具体的包含。这似乎是特定于编译器的,并在以下内容中进行了详细介绍:

Header files for x86 SIMD intrinsics

重要的是,如果不使用gcc,您将拥有一个不同的包含。

第二,还需要启用编译器选项。对于gcc,详细信息如下:

https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html

尽管缺少许多标志的文档。

由于我的目标是分发已编译的二进制文件,因此我想尝试避免使用-march=native

我感兴趣的大多数“其他”内部函数都是与位操作相关的。 Ye Olde Wikipedia对重要的位操作固有组(如bmi2)写得不错: https://en.wikipedia.org/wiki/Bit_Manipulation_Instruction_Sets

我需要BZHI(指令)或_bzhi_u32(c)的bmi2

这样,我可以用类似的东西得到想要的东西:

-mavx2 -mbmi2

使用-mbmi2似乎足以获得bmi1和abm之类的东西(有关定义,请参见链接的Wikipedia页面),尽管我在链接的gcc页面中没有看到任何提及。这是错误的... 编辑:似乎添加bmi2支持不会添加bmi1和abm,我可能一直在使用__builtin调用。...我后来需要添加{ {1}}和-mabm明确获得我想要的说明。正如彼得·科德斯(Peter Cordes)所建议的,最好将Haswell -mbmi作为起点,然后根据需要添加其他标志。 Haswell是2013年以来第一款使用AVX2的处理器,因此在我看来-march=haswell基本上是在说,我希望您有一台2013年或以后的计算机。

此外,根据一些快速阅读,听起来似乎使用__builtin启用了必要的标志(SO的未来问题),尽管在内部函数和内建函数之间似乎没有1:1的对应关系。更具体地说,并不是所有的内在函数似乎都作为内置函数包括在内,这意味着标志设置方法似乎是必需的,而不是仅使用内置函数而不用担心设置标志。知道出于分发目的正在使用什么内在函数也很有用,因为看来bmi2仍可能在大部分计算机上丢失(例如,我认为需要2015+的AMD)。

我仍然不清楚为什么仅使用英特尔文档中指定的包含项不起作用,但是此信息使我了解到我想去的地方的99%。