Как сравнить два вектора с помощью SIMD и получить один логический результат?

У меня есть два вектора из 4 целых чисел, и я хотел бы использовать команду SIMD для их сравнения (например, сгенерировать вектор результата, где каждая запись равна 0 или 1 в соответствии с результатом сравнения).

Затем я хотел бы сравнить вектор результата с вектором из 4 нулей и только если они равны что-то сделать.

Знаете ли вы, какие SIMD-команды я могу использовать для этого?

Ответ 1

Чтобы сравнить два SIMD-вектора:

#include <stdint.h>
#include <xmmintrin.h>

int32_t __attribute__ ((aligned(16))) vector1[4] = { 1, 2, 3, 4 };
int32_t __attribute__ ((aligned(16))) vector2[4] = { 1, 2, 2, 2 };
int32_t __attribute__ ((aligned(16))) result[4];

__m128i v1 = _mm_load_si128((__m128i *)vector1);
__m128i v2 = _mm_load_si128((__m128i *)vector2);
__m128i vcmp = _mm_cmpeq_epi32(v1, v2);
_mm_store_si128((__m128i *)result, vcmp);

Примечания:

  • предполагается, что данные представляют собой 32-битные целые числа.
  • vector1, vector2, result все должны быть выровнены по 16 байт
  • результат будет равным -1 для 0, не равным ({ -1, -1, 0, 0 } для примера выше кода)

UPDATE

Если вам нужен только один логический результат для случая, когда все 4 элемента совпадают, вы можете сделать это следующим образом:

#include <stdint.h>
#include <xmmintrin.h>

int32_t __attribute__ ((aligned(16))) vector1[4] = { 1, 2, 3, 4 };
int32_t __attribute__ ((aligned(16))) vector2[4] = { 1, 2, 2, 2 };

__m128i v1 = _mm_load_si128((__m128i *)vector1);
__m128i v2 = _mm_load_si128((__m128i *)vector2);
__m128i vcmp = _mm_cmpeq_epi32(v1, v2);
uint16_t mask = _mm_movemask_epi8(vcmp);
int result = (mask == 0xffff);