在 运行 基本 Avx512 代码时获取非法指令

Getting Illegal Instruction while running a basic Avx512 code

我正在尝试学习 AVX 指令,而 运行 我收到了基本代码

Illegal instruction (core dumped)

下面提到了代码,我正在使用

编译它

g++ -mavx512f 1.cpp

问题到底是什么以及如何克服它? 谢谢!

#include <immintrin.h>
#include<iostream>
using namespace std;

void add(const float a[], const float b[], float res[], int n)
{
    int i = 0;

    for(; i < (n&(~0x31)) ; i+=32 )
    {
        __m512 x = _mm512_loadu_ps( &a[i] );
        __m512 y = _mm512_loadu_ps( &b[i] );

        __m512 z = _mm512_add_ps(x,y);
        _mm512_stream_ps(&res[i],z);
    }

    for(; i<n; i++) res[i] = a[i] + b[i];
}

int main()
{
    int n = 100000;
    float a[n], b[n], res[n];
    for(int i = 0;i < n; i++)
    {
        a[i] = i;
        b[i] = i+10;
    }
    add(a,b,res,n);
    for(int i=0;i<n;i++) cout<<res[i]<<" ";
    cout<<endl;
    return 0;
}

可能您的 CPU 根本不支持 AVX512。
只有 CPU 这些和更新的世代 support AVX-512:

  • Server/workstation:Skylake-SP(“至强可扩展性能”)及更高版本,
    Skylake-X high-end desktop/workstation.
  • 客户端:Ice Lake and later e.g. i5-1035G4, and Rocket Lake桌面,例如i5-11600.
    (还有very-limited-releaseCannon Lake laptop chip
    这些的赛扬/奔腾版本有 AVX2 但没有 AVX-5121.
  • Xeon Phi 计算卡,第 2 代及更高版本 (Knight's Landing)。

编译器选项

使用 clang 或 g++ -O3 -march=native 启用您的 CPU 支持的所有内容。

如果你遇到编译错误(比如未声明的函数 _mm512_loadu_ps),你的 CPU 支持 AVX512 所以 g++ 没有启用它,所以immintrin.h 不会定义内在的。

(或者另一个可能的错误是“内联”目标选项不允许的内置错误。)

如果您想为其他 CPU 制作二进制文件,而不仅仅是您正在编译的机器,请仅使用单独的 -mavx512f-mtune= 选项。

相关:How to test AVX-512 instructions w/o supported hardware?

  • Intel AVX intrinsics: any compatibility library out?(在编译时模拟而不是 运行 时)。

MSVC 和 ICC do 允许您在不告诉编译器目标支持它们的情况下使用内部函数,因此这种根据 CPU 检查代码的方法不起作用与那些编译器。他们很乐意让您编译不会在当前 CPU 上 运行 的代码。 (因为 MSVC 假定您将进行 运行time CPU 检测和调度,而不是为每个人分发源代码以针对他们自己的机器进行优化。)


更多关于 CPUs 没有 AVX-512

英特尔processor name/number meanings

AMD 尚未发布任何 AVX-512 CPUs(谣言指向 Zen4),而较旧的 Intel 也没有。
Skylake-client没有有AVX-512,只有Skylake-server。
英特尔 Alder Lake hybrid (big.LITTLE) CPUs won't have AVX-512,即使在大核上也只有 AVX2。
Low-power CPUSilvermont / Tremont 甚至没有 AVX1。

另请注意,AVX-512 有多个扩展,例如 AVX-512VPOPCNTDQ,它引入了 SIMD 指令来计算每个 SIMD 元素中的设置位。检查 Wikipedia 的 CPUs with AVX-512 table 以查看哪个 CPU 有什么。 AVX-512F 是“基础”,AVX-512VL 允许在 128 位和 256 位向量上使用很酷的新指令。

脚注 1:Pentium/Celeron 旧版英特尔 CPU 甚至没有 AVX,只有 SSE4.2。 (也缺少 BMI1/2 因为他们禁用了 VEX 前缀的解码)。