__m256i _mm256_shuffle_epi8 (__m256i a, __m256i b)
FOR j := 0 to 15
i := j*8
IF b[i+7] == 1
dst[i+7:i] := 0
ELSE
index[3:0] := b[i+3:i]
\\\ ^^^^^^^^^^^^^^^^^^^^^^ only look at lower 4 bits
dst[i+7:i] := a[index*8+7:index*8]
FI
IF b[128+i+7] == 1
dst[128+i+7:128+i] := 0
ELSE
index[3:0] := b[128+i+3:128+i]
dst[128+i+7:128+i] := a[128+index*8+7:128+index*8]
FI
ENDFOR
dst[MAX:256] := 0
< /code>
Итак, если я не ошибаюсь, вы можете просто сделать < /p>
const __m256i lo = vec; \
const __m256i hi = _mm256_srli_epi16(vec, 4); \
Я вроде как новичок в AVX, пожалуйста, скажите мне, что здесь что -то не так.
Этот код поступает из https://github.com/wojciechmula/sse-popcount/blob/master/popcnt-avx2-lookup.cpp. [code]std::uint64_t popcnt_AVX2_lookup(const uint8_t* data, const size_t n) {
#define ITER { \ const __m256i vec = _mm256_loadu_si256(reinterpret_cast(data + i)); \ const __m256i lo = _mm256_and_si256(vec, low_mask); \ \\\ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ why do we need this? const __m256i hi = _mm256_and_si256(_mm256_srli_epi16(vec, 4), low_mask); \ const __m256i popcnt1 = _mm256_shuffle_epi8(lookup, lo); \ const __m256i popcnt2 = _mm256_shuffle_epi8(lookup, hi); \ local = _mm256_add_epi8(local, popcnt1); \ local = _mm256_add_epi8(local, popcnt2); \ i += 32; \ }
while (i + 8*32 Код используется для замены функции Buildin_popcnt, которая подсчитывает число 1s при данном входе в двоичном формате. Что меня беспокоит, так это эти две строки: < /p> const __m256i lo = _mm256_and_si256(vec, low_mask); \ const __m256i hi = _mm256_and_si256(_mm256_srli_epi16(vec, 4), low_mask); \ < /code> Согласно Intel Intrinsic Guide https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#techs=avx,AVX2 & IG_EXPAND = 6392,305,6221 6389 6389 6221 6188 6769 6389 124 6050 6389 и текст = MM256_SHUFFLE , _mm256_shuffle_epi8 [/code] Инструкция рассматривает только нижние 4 бита ваших упакованных Chars B: [code]__m256i _mm256_shuffle_epi8 (__m256i a, __m256i b) FOR j := 0 to 15 i := j*8 IF b[i+7] == 1 dst[i+7:i] := 0 ELSE index[3:0] := b[i+3:i] \\\ ^^^^^^^^^^^^^^^^^^^^^^ only look at lower 4 bits dst[i+7:i] := a[index*8+7:index*8] FI IF b[128+i+7] == 1 dst[128+i+7:128+i] := 0 ELSE index[3:0] := b[128+i+3:128+i] dst[128+i+7:128+i] := a[128+index*8+7:128+index*8] FI ENDFOR dst[MAX:256] := 0 < /code> Итак, если я не ошибаюсь, вы можете просто сделать < /p> const __m256i lo = vec; \ const __m256i hi = _mm256_srli_epi16(vec, 4); \ [/code] Я вроде как новичок в AVX, пожалуйста, скажите мне, что здесь что -то не так.