ошибка: «_mm512_loadu_epi64» не было объявлено в этой области - PullRequest
0 голосов
/ 04 декабря 2018

Я пытаюсь создать минимальный репродуктор для отчета об этой проблеме .Кажется, есть некоторые проблемы с AVX-512, который поставляется на последних машинах Apple с процессорами Skylake.

В соответствии с примечаниями к выпуску GCC6 должно быть доступно оборудование AVX-512.В соответствии с Intel Intrinsics Guide vmovdqu64 доступен с AVX-512VL и AVX-512F:

$ cat test.cxx
#include <cstdint>
#include <immintrin.h>
int main(int argc, char* argv[])
{
    uint64_t x[8];
    __m512i y = _mm512_loadu_epi64(x);
    return 0;
}

А затем:

$ /opt/local/bin/g++-mp-6 -mavx512f -Wa,-q test.cxx -o test.exe
test.cxx: In function 'int main(int, char**)':
test.cxx:6:37: error: '_mm512_loadu_epi64' was not declared in this scope
     __m512i y = _mm512_loadu_epi64(x);
                                     ^
$ /opt/local/bin/g++-mp-6 -mavx -mavx2 -mavx512f -Wa,-q test.cxx -o test.exe
test.cxx: In function 'int main(int, char**)':
test.cxx:6:37: error: '_mm512_loadu_epi64' was not declared in this scope
     __m512i y = _mm512_loadu_epi64(x);
                                     ^
$ /opt/local/bin/g++-mp-6 -msse4.1 -msse4.2 -mavx -mavx2 -mavx512f -Wa,-q test.cxx -o test.exe
test.cxx: In function 'int main(int, char**)':
test.cxx:6:37: error: '_mm512_loadu_epi64' was not declared in this scope
     __m512i y = _mm512_loadu_epi64(x);
                                     ^

Я прошелварианты обратно к -msse2 безуспешно.Кажется, я что-то упускаю.

Что требуется для использования AVX-512 для современного GCC?


Согласно /opt/local/bin/g++-mp-6 -v, это пути поиска заголовка:

#include "..." search starts here:
#include <...> search starts here:
 /opt/local/include/gcc6/c++/
 /opt/local/include/gcc6/c++//x86_64-apple-darwin13
 /opt/local/include/gcc6/c++//backward
 /opt/local/lib/gcc6/gcc/x86_64-apple-darwin13/6.5.0/include
 /opt/local/include
 /opt/local/lib/gcc6/gcc/x86_64-apple-darwin13/6.5.0/include-fixed
 /usr/include
 /System/Library/Frameworks
 /Library/Frameworks

А потом:

$ grep -R '_mm512_' /opt/local/lib/gcc6/ | grep avx512f | head -n 8
/opt/local/lib/gcc6//gcc/x86_64-apple-darwin13/6.5.0/include/avx512fintrin.h:_mm512_set_epi64 (long long __A, long long __B, long long __C,
/opt/local/lib/gcc6//gcc/x86_64-apple-darwin13/6.5.0/include/avx512fintrin.h:_mm512_set_epi32 (int __A, int __B, int __C, int __D,
/opt/local/lib/gcc6//gcc/x86_64-apple-darwin13/6.5.0/include/avx512fintrin.h:_mm512_set_pd (double __A, double __B, double __C, double __D,
/opt/local/lib/gcc6//gcc/x86_64-apple-darwin13/6.5.0/include/avx512fintrin.h:_mm512_set_ps (float __A, float __B, float __C, float __D,
/opt/local/lib/gcc6//gcc/x86_64-apple-darwin13/6.5.0/include/avx512fintrin.h:#define _mm512_setr_epi64(e0,e1,e2,e3,e4,e5,e6,e7)                       \
/opt/local/lib/gcc6//gcc/x86_64-apple-darwin13/6.5.0/include/avx512fintrin.h:  _mm512_set_epi64(e7,e6,e5,e4,e3,e2,e1,e0)
/opt/local/lib/gcc6//gcc/x86_64-apple-darwin13/6.5.0/include/avx512fintrin.h:#define _mm512_setr_epi32(e0,e1,e2,e3,e4,e5,e6,e7,                       \
/opt/local/lib/gcc6//gcc/x86_64-apple-darwin13/6.5.0/include/avx512fintrin.h:  _mm512_set_epi32(e15,e14,e13,e12,e11,e10,e9,e8,e7,e6,e5,e4,e3,e2,e1,e0)
...

Ответы [ 2 ]

0 голосов
/ 17 июня 2019

_mm512_loadu_epi64 недоступно в 32-битном режиме.Вам нужно скомпилировать для 64-битного режима.В общем, AVX512 лучше всего работает в 64-битном режиме.

0 голосов
/ 04 декабря 2018

Без маскировки, нет никаких оснований для того, чтобы эта внутренняя сущность существовала или когда-либо использовала ее вместо эквивалентной _mm512_loadu_si512.Это просто сбивает с толку и может заставить читателей думать, что это была vmovq расширяющаяся до нуля нагрузка одного epi64.

Искатель встроенных функций Intel указывает, что он существует , нодаже текущий транк gcc (на Godbolt) не определяет его.

Почти все инструкции AVX512 поддерживают маскирование слиянием и маскирование нуля.Инструкции, которые раньше были чисто побитовыми / целыми регистрами без значимых границ элементов, теперь имеют 32- и 64-битные разновидности элементов, такие как vpxord и vpxorq.Или vmovdqa32 и vmovdqa64.Но , использующий любую версию без маскировки, по-прежнему является обычной загрузкой / хранением / регистром-копией вектора, и не имеет смысла указывать для них что-либо о размере элемента в исходном коде C ++ с внутренними элементами, а только общую ширину вектора.

См. Также В чем разница между _mm512_load_epi32 и _mm512_load_si512?


SSE * и параметры AVX1 / 2 не зависят от того, используются ли заголовки GCC или нетопределить эту внутреннюю сущность в терминах встроенных в gcc или нет;-mavx512f уже подразумевает все расширения Intel SSE / AVX до AVX512.


Он присутствует в стволе clang (но не 7.0, поэтому он был добавлен совсем недавно).

  • unaligned _mm512_loadu_si512 - поддерживается везде, используйте этот
  • unaligned _mm512_loadu_epi64 - clang trunk, not gcc.
  • выравнивается _mm512_load_si512 - поддерживается везде, используйте это
  • выравнивается _mm512_load_epi64 - также поддерживается везде, что удивительно.
  • unaligned _mm512_maskz_loadu_epi64 - поддерживается везде, используйте это для нагрузок с нулевым маскированием
  • unaligned _mm512_mask_loadu_epi64 - поддерживается везде, используйте это для нагрузок маски слияния.

Thisкод компилируется в gcc уже в 4.9.0 и в mainline (Linux) уже в 3.9, оба с -march=avx512f.Или, если они это поддерживают, -march=skylake-avx512 или -march=knl.Я не тестировал с Apple Clang.

#include <immintrin.h>

__m512i loadu_si512(void *x) { return _mm512_loadu_si512(x); }
__m512i load_epi64(void *x)  {  return _mm512_load_epi64(x); }
//__m512i loadu_epi64(void *x) {  return _mm512_loadu_epi64(x); }

__m512i loadu_maskz(void *x) { return _mm512_maskz_loadu_epi64(0xf0, x); }
__m512i loadu_mask(void *x)  { return _mm512_mask_loadu_epi64(_mm512_setzero_si512(), 0xf0, x); }

Godbolt link ;вы можете раскомментировать _mm512_loadu_epi64 и перевернуть компилятор, чтобы увидеть, как он работает.

...