c++x86avxinstruction-setavx512

Getting Illegal Instruction while running a basic Avx512 code


I am trying to learn AVX instructions and while running a basic code I recieve

Illegal instruction (core dumped)

The code is mentioned below and I am compiling it using

g++ -mavx512f 1.cpp

What exactly is the problem and how to overcome it? Thank You!

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


Solution

  • Probably your CPU doesn't support AVX512 at all.
    Only CPUs of these and newer generations support AVX-512:


    Compiler options

    Use clang or g++ -O3 -march=native to enable everything your CPU supports.

    If you get compile errors (like undeclared function _mm512_loadu_ps), your CPU does not support AVX512 so g++ didn't enable it. (Or whatever other CPU feature you're trying to use.)

    immintrin.h would still define the intrinsic, with __attribute__((always_inline,target("avx512f")). So it's required to inline, but can only do so into functions that are themselves using __attribute__((target("avx512f")) or a similar pragma, or command line options. That's why the error message is about inlining failed for an always_inline function (the intrinsic wrapper around the __builtin_ia32_...) into a function with incompatible target options.

    Only use separate -mavx512f and -mtune= options if you want to make a binary for other CPUs, not just the machine you're compiling on. Related:


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

    MSVC and ICC do let you use intrinsics without telling the compiler the target supports them, so this method of checking your code against the CPU doesn't work with those compilers. They'll happily let you compile code that won't run on the current CPU. (Because MSVC assumes you're going to do runtime CPU detection and dispatching, instead of distributing source code for everyone to optimize for their own machine.)


    More about CPUs without AVX-512

    Intel processor name/number meanings

    Skylake-client does not have AVX-512, only Skylake-server.
    Intel Alder Lake hybrid (big.LITTLE) CPUs won't have AVX-512, only AVX2 even on the big cores.
    Low-power CPUs like Silvermont / Tremont don't even have AVX1, until Gracemont (Alder Lake E-cores).

    Also note, there are multiple extensions to AVX-512, like AVX-512VPOPCNTDQ that introduces SIMD instructions to count set bits in each SIMD element. Check Wikipedia's CPUs with AVX-512 table to see which CPU has what. AVX-512F is the "foundation", and AVX-512VL allows using cool new instructions on 128 and 256-bit vectors.

    Footnote 1: Pentium/Celeron versions of older Intel CPUs don't even have AVX, just SSE4.2. (Also lacking BMI1/2 because they disabled decoding of VEX prefixes).