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

4

1 回答 1

6

可能你的 CPU 根本不支持 AVX512。
只有这些和更新一代的 CPU支持 AVX-512


编译器选项

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

如果你得到编译错误(比如 undeclared function _mm512_loadu_ps),你的 CPU 不支持AVX512 所以 g++ 没有启用它,所以immintrin.h不会定义那个内在的。

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

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

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

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


更多关于没有 AVX-512 的 CPU

英特尔处理器名称/编号含义

AMD 还没有发布任何 AVX-512 CPU(传闻指向 Zen4),老款 Intel 也没有它。
Skylake-client 没有AVX -512,只有 Skylake-server。
英特尔Alder Lake混合 (big.LITTLE) CPU没有 AVX-512,即使在大内核上也只有 AVX2 。
Silvermont / Tremont 等低功耗 CPU 甚至没有 AVX1。

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

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

于 2019-06-16T19:24:49.407 回答