如何使用SIMD比较两个向量并获得单个布尔结果?

N.M*_*N.M 12 x86 assembly sse simd

我有两个每个4个整数的向量,我想使用SIMD命令来比较它们(比如根据比较结果生成每个条目为0或1的结果向量).

然后,我想将结果向量与4个零的向量进行比较,并且只有在它们相等的情况下做一些事情.

你知道我可以用什么SIMD命令来做吗?

Pau*_*l R 15

要比较两个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);
Run Code Online (Sandbox Code Playgroud)

笔记:

  • 假设数据是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);
Run Code Online (Sandbox Code Playgroud)

  • 错别字:_mm_movemask_epi8 返回 int 而没有 __m128i。 (2认同)