Зачем маскировку необходимо перед использованием перетасовки PSHUFB в качестве стола для поиска для Nibbles?C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Зачем маскировку необходимо перед использованием перетасовки PSHUFB в качестве стола для поиска для Nibbles?

Сообщение Anonymous »

Этот код поступает из https://github.com/wojciechmula/sse-pop ... lookup.cpp.

Код: Выделить всё

std::uint64_t popcnt_AVX2_lookup(const uint8_t* data, const size_t n) {

size_t i = 0;

const __m256i lookup = _mm256_setr_epi8(
/* 0 */ 0, /* 1 */ 1, /* 2 */ 1, /* 3 */ 2,
/* 4 */ 1, /* 5 */ 2, /* 6 */ 2, /* 7 */ 3,
/* 8 */ 1, /* 9 */ 2, /* a */ 2, /* b */ 3,
/* c */ 2, /* d */ 3, /* e */ 3, /* f */ 4,

/* 0 */ 0, /* 1 */ 1, /* 2 */ 1, /* 3 */ 2,
/* 4 */ 1, /* 5 */ 2, /* 6 */ 2, /* 7 */ 3,
/* 8 */ 1, /* 9 */ 2, /* a */ 2, /* b */ 3,
/* c */ 2, /* d */ 3, /* e */ 3, /* f */ 4
);

const __m256i low_mask = _mm256_set1_epi8(0x0f);

__m256i acc = _mm256_setzero_si256();

#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 
Инструкция рассматривает только нижние 4 бита ваших упакованных Chars B:

Код: Выделить всё

__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://stackoverflow.com/questions/729 ... for-nibble
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»