Как лучше всего попарно сравнивать два целочисленных регистра и извлекать одинаковые элементы с помощью инструкций SSE? Например, если a = [6 4 7 2]
и b = [2 4 9 2]
(каждый регистр содержит четыре 32-битных целых числа), результат должен быть [4 2 x x]
. Альтернативная форма этого вопроса - как получить двоичную маску равных элементов (..0101b
), которую можно использовать для перетасовки или в качестве индекса для поиска параметра для инструкции перетасовки в предварительно вычисленной таблице.
Сравнение и извлечение с помощью SSE
Ответы (2)
Я бы, наверное, использовал вариант того, что предлагает drhirsch
:
int index = _mm_movemask_ps((__m128)_mm_cmp_epi32(a, b));
Это дает вам тот же индекс, который можно использовать при поиске маски тасования с использованием всего двух операций.
Невозможно извлечь и переместить одинаковые элементы с помощью одной инструкции. Но маску из равных элементов можно легко получить с помощью pcmpeqd
:
__m128i zero = _mm_set1_epi32(0);
__m128i a = _mm_set_epi32(6, 4, 7, 2);
__m128i b = _mm_set_epi32(2, 4, 9, 2);
__m128i mask = _mm_cmp_epi32(a, b); // mask is now 0, -1, 0, -1
mask = _mm_sub_epi32(zero, mask); // mask is now 0, 1, 0, 1
Изменить: если вам нужен индекс для таблицы поиска с константами перемешивания, вам потребуются дополнительные операции. Нравиться
static const __m128i zero = _mm_set1_epi32(0);
static const __m128i bits = _mm_set_epi32(1,2,4,8);
__m128i a = _mm_set_epi32(6, 4, 7, 2);
__m128i b = _mm_set_epi32(2, 4, 9, 2);
__m128i bitvector = _mm_and_si128(bits, _mm_cmp_epi32(a, b));
bitvector = _mm_hadd_epi32(bitvector, bitvector);
bitvector = _mm_hadd_epi32(bitvector, bitvector);
// now a index from 0...15 is the the low 32 bit of bitvector
Могут быть лучшие алгоритмы, чем использование таблицы поиска для вычисления тасования, возможно, вычисление тасования напрямую с использованием множителя Де Брёйна. OTOH, если у вас есть более 4 int для сравнения, дополнительные 4 int будут стоить только одного дополнительных phaddd
.
mask = ..0101b = 5d
.
- person user1128016; 13.05.2012