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

问题描述 投票:0回答:1

我正在尝试学习 AVX 指令,并在运行我收到的基本代码时

非法指令(核心转储)

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

编译它

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;
}

c++ x86 avx instruction-set avx512
1个回答
7
投票

可能您的CPU根本不支持AVX512。
仅这些代和新一代的 CPU 支持 AVX-512:

  • 维基百科有一个很好的表格(包括按功能细分,例如 AVX512VBMI 或 FP16)

  • Zen 4(及更高版本)。

  • 服务器/工作站:Skylake-SP(“Xeon 可扩展性能”)及更高版本,
    Skylake-X高端台式机/工作站。

  • 客户:Ice Lake / Tiger Lake 例如i5-1035G4 和 Rocket Lake 台式机,例如i5-11600.
    (还有非常限量发行的Cannon Lake笔记本电脑芯片
    这些的赛扬/奔腾版本有 AVX2,但没有 AVX-5121

    不是 Alder Lake(第 12 代);英特尔取消了对 AVX-512 的支持,并积极阻止人们在芯片中使用 AVX-512 支持,该支持最初在禁用 E 核的情况下可用。

    英特尔客户端 CPU 最终将能够再次利用其芯片中存在的 AVX-512 硬件与 AVX10,这使它们能够公开 AVX-512 的 256 位矢量宽度子集以及所有有趣的功能诸如掩码、

    vpternlogd
    、更好的洗牌、32 个向量寄存器、广播内存源操作数等功能。于 2023 年宣布,但仍然没有关于支持它的客户端 CPU 的消息(这需要他们在 E 核上实现它)。我本以为微代码更新可以报告现有 AVX-512 CPU 上的 AVX10.1/512 支持,因为它在 AVX10.2 之前不会添加任何新内容(EVEX 前缀中的 FP 舍入模式覆盖除 512 之外的矢量宽度) -bit),但显然 Granite Rapids 将是第一个支持 AVX10.1 的。

  • Xeon Phi 计算卡,第二代及更高版本 (Knight's Landing)。


编译器选项

使用 clang 或

g++ -O3 -march=native
启用 CPU 支持的所有功能。

如果出现编译错误(例如未声明的函数

_mm512_loadu_ps
),则说明您的 CPU 支持 AVX512,因此 g++ 未启用它。 (或者您尝试使用的任何其他 CPU 功能。)

immintrin.h
仍然会与
__attribute__((always_inline,target("avx512f"))
一起定义内在。因此需要内联,但只能在本身使用
__attribute__((target("avx512f"))
或类似的编译指示或命令行选项的函数中这样做。这就是为什么错误消息是关于将
always_inline
函数(围绕
__builtin_ia32_...
的内在包装器)内联到具有不兼容目标选项的函数中失败的原因。

如果您想为其他 CPU(而不仅仅是您正在编译的计算机)制作二进制文件,则仅使用单独的

-mavx512f
-mtune=
选项。相关:


相关:如何在不支持硬件的情况下测试 AVX-512 指令?

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


有关不带 AVX-512 的 CPU 的更多信息

Intel 处理器名称/编号含义

Skylake-client 没有有 AVX-512,只有 Skylake-server。
Intel Alder Lake 混合(big.LITTLE)CPU 不会有 AVX-512,即使在大核心上也只有 AVX2。
像 Silvermont / Tremont 这样的低功耗 CPU 甚至没有 AVX1,直到 Gracemont(Alder Lake E-cores)。

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

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

© www.soinside.com 2019 - 2024. All rights reserved.