带有mm_cmpeq_epi8_mask的非法指令

时间:2019-06-25 02:10:36

标签: gcc intrinsics instruction-set compiler-flags avx512

我正在尝试运行类似于以下代码

#include <immintrin.h>
void foo() {
    __m128i a = _mm_set_epi8 (0,0,6,5,4,3,2,1,8,7,6,5,4,3,2,1);
    __m128i b = _mm_set_epi8 (0,0,0,0,0,0,0,1,8,7,6,5,4,3,2,1);
    __mmask16 m = _mm_cmpeq_epi8_mask(a,b); // supposedly requires avx512vl and avx512bw
    std::cout<<m<<std::endl;
}
void bar() {
    int dataa[8] = {1,0,1,0,1,0,1,0};
    __m256i points = _mm256_lddqu_si256((__m256i *)&dataa[0]); // requires just mavx
    (void)points;
}

但是,我一直遇到错误Illegal instruction (core dumped)

我用

编译代码
  

g ++ -std = c ++ 11 -march = broadwell -mavx -mavx512vl -mavx512bw tests.cpp

根据Intel的内在文档,这些标志应足以同时运行foobar。但是,当运行foobar时,我会收到相同的错误消息。

但是,如果我删除了foo,而没有进行-mavx512vl的编译,则可以顺利运行bar

我已经检查过我的CPU是否支持mno-avx512vlmno-avx512bw标志,因此它应该支持mavx512vlmavx512bw吗?

我必须包括哪些标志才能运行这两个功能?还是我想念其他东西?

3 个答案:

答案 0 :(得分:3)

恐怕您确定CPU功能的方法不正确 非常可靠。您的gcc编译器支持AVX-512的事实并不意味着 您的CPU支持AVX-512。

在Linux命令行上,输入more /proc/cpuinfo并检查标志 部分以查看您的CPU支持哪些指令集。

在Windows上:1.打开设置,2.单击系统,3.单击关于。 这将显示处理器类型。谷歌 intel ark 'processor type',例如Google intel ark core i3 7100。 然后点击指向processor page on the Intel website的链接并检查 Advanced Technologies -> 指令集扩展项。

AVX-512支持许多级别。 AVX-512_BW AVX-512_VL是支持AVX-512的处理器的标准配置,除非您使用Knights Landing或Mill处理器。参见https://en.wikipedia.org/wiki/AVX-512#CPUs_with_AVX-512https://en.wikichip.org/wiki/x86/avx-512#Implementation

答案 1 :(得分:2)

使用gcc -march=native 进行编译。如果遇到编译错误,则您的源代码尝试使用您的CPU不支持的功能。

相关:Getting Illegal Instruction while running a basic Avx512 code


  

我已经检查过我的CPU是否支持mno-avx512vl和mno-avx512bw标志,因此它应该支持mavx512vl和mavx512bw吗?

这与GCC选项的工作方式相反。

-mno-avx512vl 禁用 -mavx512vl ,如果有任何较早的选项(例如-march=skylake-avx512-mavx512vl本身)具有设置它。

-march=broadwell未启用AVX512指令,因为Broadwell CPU无法在本地运行它们。因此,-mno-avx512vlg++ -std=c++11 -march=broadwell -mavx ...的末尾具有完全零的作用

  

许多选项的长名称都以'-f'或'-W'开头,例如-fmove-loop-invariants,-Wformat等。 其中大多数都具有正面和负面形式; -ffoo的否定形式是-fno-foo。本手册仅介绍这两种形式中的一种,而不是默认形式。

     

GCC手册中section 3: Invoking GCC 3的简介部分

({-m选项遵循与-f-W长选项相同的约定。)

foono-foo的这种风格并非GCC独有;这很常见。


使用_mm256_lddqu_si256编译后在-mavx512vl上发生故障

GCC很笨,它对负载使用EVEX编码(可能是vmovdqu64),而不是较短的VEX编码。但是您告诉它AVX512VL可用,因此这只是一个优化问题,而不是正确性。

如果仅在启用了AVX的情况下编译了该函数,则它当然只会使用AVX指令。

答案 2 :(得分:2)

对于Intel的ISA来说,一般规则是后者的架构是前者的超集。由于AVX512是您提到的最新版本,因此不必使用 -mavx 。使用 -march = broadwell 是没有用的,因为您无法针对没有AVX512 ISA的CPU进行优化。

您的命令行应该看起来像

g++ -std=c++11 -march=skylake-avx512 tests.cpp

此外,“我的CPU支持那些编译器标志”的语句很奇怪。我想您的意思是“使用这些标志构建的代码在我的CPU上运行”,但是正如前面已经提到的,前缀意味着会为这种ISA生成代码。< / p>

因此,您的编译器标记很好,因为您使用的CPU不支持所需的ISA。