【问题标题】:Illegal Instruction with mm_cmpeq_epi8_mask带有 mm_cmpeq_epi8_mask 的非法指令
【发布时间】:2019-11-06 19:33:09
【问题描述】:

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

#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 对吧?

我必须包含哪些标志才能运行这两个函数?还是我错过了什么?

【问题讨论】:

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


    【解决方案1】:

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

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

    在 Windows 上:1. 打开设置,2. 单击系统,3. 单击关于。 这将显示处理器类型。谷歌 intel ark 'processor type' 例如谷歌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

    【讨论】:

      【解决方案2】:

      gcc -march=native编译。如果你得到编译错误,你的源代码试图使用你的 CPU 不支持的东西。

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


      我已经检查过我的 cpu 支持 mno-avx512vl 和 mno-avx512bw 标志,所以它应该支持 mavx512vl 和 mavx512bw 对吧?

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

      -mno-avx512vl disables -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 独有的;这很常见。


      使用-mavx512vl 编译后出现_mm256_lddqu_si256 错误

      GCC 是愚蠢的,它对负载使用 EVEX 编码(可能是vmovdqu64)而不是更短的 VEX 编码。但是你告诉它AVX512VL是可用的,所以这只是一个优化问题,而不是正确性。

      如果你确实编译了只启用了 AVX 的函数,它当然只会使用 AVX 指令。

      【讨论】:

        【解决方案3】:

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

        你的命令行应该是这样的

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

        此外,“我的 CPU 支持那些编译器标志”的说法很奇怪。我想你的意思是“我用这些标志构建的代码在我的 CPU 上运行”,但正如已经提到的那样,no 前缀意味着 NO 为这样的 ISA 生成代码。

        所以,您的编译器标志很好,只是您的 CPU 不支持所需的 ISA。

        【讨论】:

        • -march=broadwell 永远不会没用,您应该更喜欢使用 -march 选项来设置调整选项 (-mtune=broadwell) 启用其他指令集扩展,如 popcnt、BMI1 /BMI2、CMPXCHG16B 和编译器可能利用的其他非 SIMD 扩展。使用-mavx512bw 而不是-march=skylake-avx512 的理由很少。它也可以避免这个错误,因为 OP 知道他们没有 Skylake-X CPU。除此之外,很好的答案。
        • 好的,有两种情况:-march=broadwell 获胜并且没有 AVX512 指令或-mavx512* 获胜并且生成 AVX512 指令。在第一种情况下,OP 没有发出所需的指令。在第二种情况下,gcc 将针对实际上不存在的芯片进行优化。我必须纠正自己该选项并非无用,但使用它可能会导致性能方面的意外后果。
        • @PeterCordes 当然,使用适当的-march 而不是-m 的数量的方法是首选的方法。所以,是的,-march=skylake-avx512 对于 OP 正在做的事情已经足够了。
        • 在这种特定情况下,对于支持 AVX512BW + AVX512VL 的每个现有 CPU,tune=broadwell 都优于 tune=generic。因为currently those are all Skylake-server derived 和 tune=skylake-avx512 非常接近 tune=broadwell,并且排除了对任何 AMD CPU 的调整。
        • 不,这不是-march=broadwell“获胜”与-mavx512vl的问题。它们是添加剂。 -march=broadwell 基本上启用了 AVX512 之前的所有英特尔扩展,-mavx512vl 启用了 AVX512F + AVX512VL。仅当您使用 -mno-avx2 或其他东西时,最后一个才重要。 AVX512 CPU 仍然很少,因此推荐 tune=generic 来编译任何 AVX512 代码是没有意义的;始终使用-march=skylake-avx512-march=knl(或knm)。所以你应该编辑你的答案,不建议自己使用-mavx512vl -mavx512bw;这很愚蠢。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-01-20
        • 2021-02-01
        • 2020-12-20
        • 2013-04-05
        • 2021-06-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多