Эквивалент _mm_alignr_epi8 (PALIGNR) в AVX2

В SSE3 инструкция PALIGNR выполняет следующее:

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

В настоящее время я занимаюсь портированием моего кода SSE4 для использования инструкций AVX2 и работы с 256-битными регистрами вместо 128-битных. Я наивно полагал, что внутренняя функция _mm256_alignr_epi8 (VPALIGNR) выполняет ту же операцию, что и _mm_alignr_epi8 , только с 256-битными регистрами. К сожалению, это не совсем так. Фактически, _mm256_alignr_epi8 обрабатывает 256-битный регистр как 2 128-битных регистра и выполняет 2 операции «выравнивания» с двумя соседними 128-битными регистрами. Эффективно выполняет ту же операцию, что и _mm_alignr_epi8 , но одновременно с 2 регистрами.Это наиболее наглядно показано здесь: _mm256_alignr_epi8

В настоящее время мое решение состоит в том, чтобы продолжать использовать _mm_alignr_epi8 , разделив регистры ymm (256 бит) на два регистра xmm (128 бит) (старший и младший), например :

__m128i xmm_ymm1_hi = _mm256_extractf128_si256(ymm1, 0);
__m128i xmm_ymm1_lo = _mm256_extractf128_si256(ymm1, 1);
__m128i xmm_ymm2_hi = _mm256_extractf128_si256(ymm2, 0);
__m128i xmm_ymm_aligned_lo = _mm_alignr_epi8(xmm_ymm1_lo, xmm_ymm1_hi, 1);
__m128i xmm_ymm_aligned_hi = _mm_alignr_epi8(xmm_ymm2_hi, xmm_ymm1_lo, 1);
__m256i xmm_ymm_aligned = _mm256_set_m128i(xmm_ymm_aligned_lo, xmm_ymm_aligned_hi);

Это работает, но должен быть способ получше, не так ли? Есть ли, возможно, более «общая» инструкция AVX2, которую следует использовать для получения того же результата?

7
задан eladidan 15 December 2011 в 10:05
поделиться