我正在intel intrinsic guide page。
我的经历很脆弱。
好的,我有一个阵列 - 一个很长的阵列,真的是名为&source;' source的#t;
如果匹配某个值,我想更改一些值。
int source[] = {4,5,9,8}
int mask[] = {4,4,4,4}
int replacer[] = {3,3,3,3}
所以最终来源应该看起来像{3,5,9,8}
我想用SSE< 4。
我遇到的最近的指示是_mm_cmpeq_epi32
:
FOR j := 0 to 3
i := j*32 dst[i+31:i] := ( a[i+31:i] == b[i+31:i] ) ? 0xFFFFFFFF : 0
ENDFOR
现在我想要用我的值替换原始数组,否则什么都不做:
FOR j := 0 to 3
i := j*32 dst[i+31:i] := ( a[i+31:i] == b[i+31:i] ) ? my_mask_value_here : source_value_untouched
ENDFOR
远程有什么东西可以实现我的目标吗?即使在组合不同的指令时,我也无法弄明白。
由于
答案 0 :(得分:4)
使用PCMPEQ
获取了掩码,如果你有4.1,那么你可以使用专门用于此目的的PBLENDVB
指令。否则,您可以使用PAND
,PANDN
和POR
来模拟它。此外,可以使用MASKMOVDQU
。
以下是演示3种方式的源代码:
#include <stdio.h>
#include <x86intrin.h>
int main()
{
int source[] = {4,5,9,8};
int mask[] = {4,4,4,4};
int replacer[] = {3,3,3,3};
__m128i bitmask = _mm_cmpeq_epi32(*(__m128i*)source, *(__m128i*)mask);
// manual version
__m128i result = _mm_and_si128(*(__m128i*)replacer, bitmask);
__m128i tmp = _mm_andnot_si128(bitmask, *(__m128i*)source);
result = _mm_or_si128(result, tmp);
printf("%d %d %d %d\n", *(int*)&result, *((int*)&result + 1), *((int*)&result + 2), *((int*)&result + 3));
// maskmovdqu version
result = *(__m128i*)source;
_mm_maskmoveu_si128(*(__m128i*)replacer, bitmask, (char*)&result);
printf("%d %d %d %d\n", *(int*)&result, *((int*)&result + 1), *((int*)&result + 2), *((int*)&result + 3));
// sse 4.1 version
result = _mm_blendv_epi8(*(__m128i*)source, *(__m128i*)replacer, bitmask);
printf("%d %d %d %d\n", *(int*)&result, *((int*)&result + 1), *((int*)&result + 2), *((int*)&result + 3));
}