Вот пример. Ваш вопрос содержал код, который использовал неподписанные операции, но вопрос был задан о подписанном, поэтому я не был уверен, что вы хотите. Если это беззнаковое, что вы хотите, просто удалите биты, реализующие расширение знака.
const __m128i mm_mask = _mm_set1_epi32(0x0F0F0F0F);
const __m128i mm_signed_max = _mm_set1_epi32(0x07070707);
for (size_t i = 0u, n = size / 16u; i < n; ++i)
{
// Load and deinterleave input half-bytes
__m128i mm_input_even = _mm_loadu_si128(reinterpret_cast< const __m128i* >(input) + i);
__m128i mm_input_odd = _mm_srli_epi32(mm_input_even, 4);
mm_input_even = _mm_and_si128(mm_input_even, mm_mask);
mm_input_odd = _mm_and_si128(mm_input_odd, mm_mask);
// If you need sign extension, you need the following
// Get the sign bits
__m128i mm_sign_even = _mm_cmpgt_epi8(mm_input_even, mm_signed_max);
__m128i mm_sign_odd = _mm_cmpgt_epi8(mm_input_odd, mm_signed_max);
// Combine sign bits with deinterleaved input
mm_input_even = _mm_or_si128(mm_input_even, _mm_andnot_si128(mm_mask, mm_sign_even));
mm_input_odd = _mm_or_si128(mm_input_odd, _mm_andnot_si128(mm_mask, mm_sign_odd));
// Store the results
_mm_storeu_si128(reinterpret_cast< __m128i* >(out_1) + i, mm_input_even);
_mm_storeu_si128(reinterpret_cast< __m128i* >(out_2) + i, mm_input_odd);
}
Если ваш size
не кратен 16, вам также нужно добавить обработку хвостовых байтов. Вы можете использовать для этого свой невекторизованный код.
Обратите внимание, что в приведенном выше коде вам не нужны побайтовые сдвиги, так как вам все равно нужно применить маску. Так что здесь подойдут любые более грубые сдвиги.