Я запускаю приведенный ниже код и у меня появляется следующая ошибка: Неопределенная переменная: выражение в [закрыто]

Мой первоначальный подход к этому был похож на @Jason R, потому что так работают «нормальные» операции, но большинство из этих операций заботятся только о высоком бите - игнорируя все остальные биты. Как только я понял это, ряд функций _mm*_maskz_broadcast*_epi*(mask,__m128i) имел наибольший смысл. Вам нужно будет включить -mavx512vl и -mavx512bw (gcc)

. Чтобы получить вектор с самым высоким битом каждого байта , установленным в соответствии с маской:

/* convert 16 bit mask to __m128i control byte mask */
_mm_maskz_broadcastb_epi8((__mmask16)mask,_mm_set1_epi32(~0))
/* convert 32 bit mask to __m256i control byte mask */
_mm256_maskz_broadcastb_epi8((__mmask32)mask,_mm_set1_epi32(~0))
/* convert 64 bit mask to __m512i control byte mask */
_mm512_maskz_broadcastb_epi8((__mmask64)mask,_mm_set1_epi32(~0))

Чтобы получить вектор с наивысшим битом каждого слова , установленным в соответствии с маской:

/* convert 8 bit mask to __m128i control word mask */
_mm_maskz_broadcastw_epi16((__mmask8)mask,_mm_set1_epi32(~0))
/* convert 16 bit mask to __m256i control word mask */
_mm256_maskz_broadcastw_epi16((__mmask16)mask,_mm_set1_epi32(~0))
/* convert 32 bit mask to __m512i control word mask */
_mm512_maskz_broadcastw_epi16((__mmask32)mask,_mm_set1_epi32(~0))

Чтобы получить вектор с наивысшим битом каждого double word установлено в соответствии с маской:

/* convert 8 bit mask to __m256i control mask */
_mm256_maskz_broadcastd_epi32((__mmask8)mask,_mm_set1_epi32(~0))
/* convert 16 bit mask to __m512i control mask */
_mm512_maskz_broadcastd_epi32((__mmask16)mask,_mm_set1_epi32(~0))

Чтобы получить вектор с самым высоким битом каждого четырехзначного слова , установленного в соответствии с маской:

/* convert 8 bit mask to __m512i control mask */
_mm512_maskz_broadcastq_epi64((__mmask8)mask,_mm_set1_epi32(~0))

Единственное, что связано с этим вопросом: _mm256_maskz_broadcastb_epi8((__mmask32)mask,_mm_set1_epi32(~0)), но я включаю другие для ссылки / сравнения.

Обратите внимание, что каждый байт / слово / ... будет либо всем один или все нули в соответствии с маской (а не только старший бит). Это также может быть полезно для выполнения векторизованных операций с битами (например, с другим вектором, например, для удаления ненужных байтов / слов).

Другое примечание: каждый _mm_set1_epi32(~0) может / должен быть преобразован в константа (либо вручную, либо компилятором), поэтому она должна составлять только одну довольно быструю операцию, хотя она может быть немного быстрее в тестировании, чем в реальной жизни, поскольку константа, вероятно, останется в регистре. Затем они преобразуются в команды VPMOVM2 {b, w, d, q}

Редактирование: если ваш компилятор не поддерживает AVX512, версия встроенной сборки должна выглядеть так:

inline __m256i dmask2epi8(__mmask32 mask){
  __m256i ret;
  __asm("vpmovm2b   %1, %0":"=x"(ret):"k"(mask):);
  return ret;
}

Другие инструкции аналогичны.

-8
задан Verde 2 October 2012 в 12:08
поделиться