Playing with avx2 intrinsics for the first time (on a system which supports avx2, but not avx512).
Neither from the prototype or the information I got from the intel intrinsics reference, would I assume, that _mm256_loadu_epi64
and _mm256_storeu_epi64
are avx512 functions.
But if I compile the code with only -mavx2
, I get compiler errors. If, on the other hand I compile with -mavx512vl
(as recommended by the compiler error), it compiles and seems to work. But of course I get nervous about what the compiler might do in the remainder of the program, if I opt for avx512...
Compiling as I think I should compile for my avx2 machine:
clang++ -std=c++17 -O2 -mavx2 -o storeload dummy.cpp
dummy.cpp:16:21: error: always_inline function
'_mm256_loadu_epi64' requires target feature 'avx512vl',
but would be inlined into function 'main' that is
compiled without support for 'avx512vl'
__m256i avx2reg = _mm256_loadu_epi64(&input[0]);
^
dummy.cpp:17:3: error: always_inline function
'_mm256_storeu_epi64' requires target feature 'avx512vl',
but would be inlined into function 'main' that is
compiled without support for 'avx512vl'
_mm256_storeu_epi64(&output[0],avx2reg);
^
2 errors generated.
Compiles but makes me nervous:
clang++ -std=c++17 -O2 -mavx512vl -o storeload dummy.cpp
Seems to work:
./storeload
0x1111111111111111 == 0x1111111111111111 ?
0x2222222222222222 == 0x2222222222222222 ?
0x3333333333333333 == 0x3333333333333333 ?
0x4444444444444444 == 0x4444444444444444 ?
The compiler is
clang --version
Debian clang version 11.0.1-2
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
The test code is
#include <cstdint>
#include <array>
#include <cinttypes>
#include <iostream>
#include <immintrin.h>
int main(int argc, const char* argv[]) {
std::array<uint64_t,4> input
{ UINT64_C(0x1111111111111111),
UINT64_C(0x2222222222222222),
UINT64_C(0x3333333333333333),
UINT64_C(0x4444444444444444) };
std::array<uint64_t,4> output;
output.fill(UINT64_C(0));
__m256i avx2reg = _mm256_loadu_epi64(&input[0]);
_mm256_storeu_epi64(&output[0],avx2reg);
std::cout << std::hex << std::showbase;
for (size_t i=0; i < input.size(); i++) {
std::cout << input[i] << " == " << output[i] << " ?" << std::endl;
}
return 0;
}
Questions
- Is it a compiler bug, asking for avx512 when only avx2 should do?
- How do I make sure, the code (there is more code, not shown in this minimal example) will not crash on my avx2 system when I do enable avx512?
- Are there alternate functions I could/should use instead?
- Are there alternate
-m
flags I should use and have not found yet?