How to compare two vectors using SIMD and get a single boolean result?
10,173
To compare two SIMD vectors:
#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);
Notes:
- data is assumed to be 32 bit integers
vector1
,vector2
,result
all need to be 16 byte aligned- result will be -1 for equal, 0 for not equal (
{ -1, -1, 0, 0 }
for above code example)
UPDATE
If you just want a single Boolean result for the case where all 4 elements match then you can do it like this:
#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);
Author by
N.M
Updated on June 21, 2022Comments
-
N.M almost 2 years
I have two vectors of 4 integers each and I'd like to use a SIMD command to compare them (say generate a result vector where each entry is 0 or 1 according to the result of the comparison).
Then, I'd like to compare the result vector to a vector of 4 zeros and only if they're equal do something.
Do you know what SIMD commands I can use to do it?
-
N.M over 12 yearsThanks. When I get the result vector, is there a simple way to check it is all zeros (I'd like to have a Boolean representing if it is all zeros or not).
-
N.M over 12 yearsI could use _mm_cmpgt_epi32 if I want to get a result for greater then, right?
-
Paul R over 12 years@N.M: yes,
_mm_cmpgt_epi32
. -
Simon over 8 yearsYou need [] after vector1 & 2 no ?
-
Paul R over 8 years@Simon: good catch - it's taken 4 years for anyone to notice !
-
Heygard Flisch over 7 yearsTypo: _mm_movemask_epi8 returns and int and no __m128i.
-
Paul R over 7 years@HeygardFlisch: thanks - I normally test the code I post - I obviously didn't this time !
-
user1794469 about 6 yearsmask should be a
uint16_t
otherwise0xffff
is out of range.