Как эмулировать _mm256_loadu_epi32 с g cc или лязгом? - PullRequest
3 голосов
/ 08 января 2020

Intel intrinsi c содержит список встроенных c _mm256_loadu_epi32:

_m256i _mm256_loadu_epi32 (void const* mem_addr);
/*
   Instruction: vmovdqu32 ymm, m256
   CPUID Flags: AVX512VL + AVX512F
   Description
       Load 256-bits (composed of 8 packed 32-bit integers) from memory into dst.
       mem_addr does not need to be aligned on any particular boundary.
   Operation
   a[255:0] := MEM[mem_addr+255:mem_addr]
   dst[MAX:256] := 0
*/

Но clang и g cc не предоставляют этого встроенного c. Вместо этого они предоставляют (в файле avx512vlintrin.h) только маскированные версии

_mm256_mask_loadu_epi32 (__m256i, __mmask8, void const *);
_mm256_maskz_loadu_epi32 (__mmask8, void const *);

, которые сводятся к той же инструкции vmovdqu32. Мой вопрос: как мне эмулировать _mm256_loadu_epi32:

 inline _m256i _mm256_loadu_epi32(void const* mem_addr)
 {
      /* code using vmovdqu32 and compiles with gcc */
 }

без написания ассемблера, т.е. используя только доступные встроенные функции?

1 Ответ

6 голосов
/ 08 января 2020

Просто используйте _mm256_loadu_si256 как обычный человек . Единственное, что дает AVX512 intrinsi c, - это более хороший прототип (const void* вместо const __m256i*).

@ chtz предполагает, что вы все еще можете написать функцию-обертку самостоятельно, чтобы получить void* прототип. Но не называйте это _mm256_loadu_epi32; какая-то будущая версия G CC, вероятно, добавит это для совместимости с документами Intel и нарушит ваш код.


Вы даже не хотите, чтобы компилятор испускал vmovdqu32 ymm, когда вы не маскируете; vmovdqu ymm короче и делает точно то же самое, без штрафа за смешивание с инструкциями в кодировке EVEX . Компилятор всегда может использовать vmovdqu32 или 64, если он хочет загрузить в ymm16..31, в противном случае вы хотите, чтобы он использовал более короткий VEX-кодированный AVX1 vmovdqu.

Я довольно убедитесь, что G CC обрабатывает _mm256_maskz_epi32(0xffu,ptr) точно так же, как _mm256_loadu_si256((const __m256i*)ptr), и делает то же самое asm независимо от того, какой вы используете Он может оптимизировать маску 0xffu и просто использовать немаскированную загрузку, но нет необходимости в дополнительном усложнении вашего источника.

Но, к сожалению, текущая G CC пессимизирует до vmovdqu32 ymm0, [mem], когда AVX512VL включен (например, -march=skylake-avx512), даже когда вы пишете _mm256_loadu_si256. Это пропущенная оптимизация, G CC Ошибка 89346 .

Неважно, какая 256-битная загрузка встроена c вы используйте (за исключением выровненных и не выровненных), пока нет маскирования.

Связано:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...