【问题标题】:SSE - compare and put my value?SSE - 比较我的价值?
【发布时间】:2015-07-21 13:37:22
【问题描述】:

我在这个intel intrinsic guide page

我的 sse 体验有点脆弱。


好的,我有一个数组 - 一个很长的数组,实际上是一个名为 'source' 的整数。

示例:

如果它匹配某个值,我想更改它的一些值。

int source[] = {4,5,9,8}
int mask[] = {4,4,4,4}
int replacer[] = {3,3,3,3} 

所以最终的来源应该是 {3,5,9,8}

我想使用 SSE

我遇到的最接近的指令是_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

是否有远程实现我正在尝试的东西?即使结合不同的指令,我也无法弄清楚..

谢谢

【问题讨论】:

    标签: assembly sse simd intrinsics


    【解决方案1】:

    使用 PCMPEQ 获得面具后,如果您有 sse 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));
    }
    

    【讨论】:

    • 不,maskmovq 仅适用于 mmx,但它的朋友 maskmovdqu 适用于 sse,但它只写入内存。不过可能有用。
    • 您链接的页面显示它仅适用于 mmx。 _mm_maskmoveu_si128maskmovdqu 的内在函数,但正如您所见,它需要一个内存操作数。
    • 没有。 void _m_maskmovq (__m64 a, __m64 mask, char* mem_addr) #include "xmmintrin.h" 指令:maskmovq mm, mm CPUID 标志:SSE
    • __m64 是 mmx,而不是 sse,即使指令是 sse 集的一部分。
    • 啊啊好吧!我的坏小丑
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-18
    • 2013-11-18
    • 2011-05-30
    • 2012-01-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多