SSE - 比较并提出我的价值?

时间:2015-07-21 13:37:22

标签: assembly sse simd intrinsics

我正在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

远程有什么东西可以实现我的目标吗?即使在组合不同的指令时,我也无法弄明白。

由于

1 个答案:

答案 0 :(得分:4)

使用PCMPEQ获取了掩码,如果你有4.1,那么你可以使用专门用于此目的的PBLENDVB指令。否则,您可以使用PANDPANDNPOR来模拟它。此外,可以使用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));
}