首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在SSE3中快速32位数组-> 24位数组转换?(RGB32 -> RGB24)

在SSE3中快速32位数组-> 24位数组转换?(RGB32 -> RGB24)
EN

Stack Overflow用户
提问于 2012-04-03 05:50:50
回答 2查看 1.7K关注 0票数 4

这个问题与之前回答的问题有关:Fast 24-bit array -> 32-bit array conversion?在一个答案中,友好地张贴了转换RGB24 -> RGB32的SSE3代码,但是我也需要反向转换(RGB32 -> RGB24)。我试了一试(见下文),我的代码绝对可以工作,但它比interjay的代码更复杂,而且明显更慢。我看不到如何准确地颠倒指令:在这种情况下,_mm_alignr_epi8似乎没有什么帮助,但我对SSE3并不是很熟悉。这种不对称是不可避免的吗,还是有更快的替代shifts和ORing的方法?

RGB32 -> RGB24:

代码语言:javascript
复制
__m128i *src = ...
__m128i *dst = ...
__m128i mask = _mm_setr_epi8(0,1,2,4, 5,6,8,9, 10,12,13,14, -1,-1,-1,-1);
for (UINT i = 0; i < Pixels; i += 16) {
    __m128i sa = _mm_shuffle_epi8(_mm_load_si128(src), mask);
    __m128i sb = _mm_shuffle_epi8(_mm_load_si128(src + 1), mask);
    __m128i sc = _mm_shuffle_epi8(_mm_load_si128(src + 2), mask);
    __m128i sd = _mm_shuffle_epi8(_mm_load_si128(src + 3), mask);
    _mm_store_si128(dst, _mm_or_si128(sa, _mm_slli_si128(sb, 12)));
    _mm_store_si128(dst + 1, _mm_or_si128(_mm_srli_si128(sb, 4), _mm_slli_si128(sc, 8)));
    _mm_store_si128(dst + 2, _mm_or_si128(_mm_srli_si128(sc, 8), _mm_slli_si128(sd, 4)));
    src += 4;
    dst += 3;
}

RGB24 -> RGB32 (礼貌插播):

代码语言:javascript
复制
__m128i *src = ...
__m128i *dst = ...
__m128i mask = _mm_setr_epi8(0,1,2,-1, 3,4,5,-1, 6,7,8,-1, 9,10,11,-1);
for (UINT i = 0; i < Pixels; i += 16) {
    __m128i sa = _mm_load_si128(src);
    __m128i sb = _mm_load_si128(src + 1);
    __m128i sc = _mm_load_si128(src + 2);
    __m128i val = _mm_shuffle_epi8(sa, mask);
    _mm_store_si128(dst, val);
    val = _mm_shuffle_epi8(_mm_alignr_epi8(sb, sa, 12), mask);
    _mm_store_si128(dst + 1, val);
    val = _mm_shuffle_epi8(_mm_alignr_epi8(sc, sb, 8), mask);
    _mm_store_si128(dst + 2, val);
    val = _mm_shuffle_epi8(_mm_alignr_epi8(sc, sc, 4), mask);
    _mm_store_si128(dst + 3, val);
    src += 3;
    dst += 4;
}
EN

回答 2

Stack Overflow用户

发布于 2012-04-03 06:29:56

您可以使用this answer并将混洗蒙版从RGB32更改为RGB24。

最大的区别是直接计算混洗,并使用按位操作来避免移位。此外,使用对齐的流式写入而不是对齐的写入不会影响缓存。

票数 0
EN

Stack Overflow用户

发布于 2014-06-20 18:22:33

老问题,但我也在试着解决同样的问题。

如果您右对齐它的第二个操作数,即在低位字节中放置零,则可以使用palignr。您需要第二、第三和第四个单词的左对齐版本,以及第一、第二和第三个单词的右对齐版本。

对于第二个和第三个单词,如果我使用shifts从左对齐的版本计算右对齐的版本,GCC会稍微高兴一些。如果我使用两个不同的pshufb,它会产生3个不必要的动作。

下面是代码。它恰好使用了8个寄存器;如果你是在64位模式下,你可以试着按2个寄存器展开它。

代码语言:javascript
复制
    __m128i mask_right = _mm_set_epi8(14, 13, 12, 10, 9, 8, 6, 5, 4, 2, 1, 0, 0x80, 0x80, 0x80, 0x80);
    __m128i mask = _mm_set_epi8(0x80, 0x80, 0x80, 0x80, 14, 13, 12, 10, 9, 8, 6, 5, 4, 2, 1, 0);

    for (; n; n -= 16, d += 48, s += 64) {
            __m128i v0 = _mm_load_si128((__m128i *) &s[0]);
            __m128i v1 = _mm_load_si128((__m128i *) &s[16]);
            __m128i v2 = _mm_load_si128((__m128i *) &s[32]);
            __m128i v3 = _mm_load_si128((__m128i *) &s[48]);

            v0 = _mm_shuffle_epi8(v0, mask_right);
            v1 = _mm_shuffle_epi8(v1, mask);
            v2 = _mm_shuffle_epi8(v2, mask);
            v3 = _mm_shuffle_epi8(v3, mask);

            v0 = _mm_alignr_epi8(v1, v0, 4);
            v1 = _mm_slli_si128(v1, 4);       // mask -> mask_right
            v1 = _mm_alignr_epi8(v2, v1, 8);
            v2 = _mm_slli_si128(v2, 4);       // mask -> mask_right
            v2 = _mm_alignr_epi8(v3, v2, 12);

            _mm_store_si128((__m128i *) &d[0], v0);
            _mm_store_si128((__m128i *) &d[16], v1);
            _mm_store_si128((__m128i *) &d[32], v2);
    }

中心部分也可能是这样写的。编译器少产生一条指令,看起来它的并行性更高一点,但需要进行基准测试才能给出正确的答案:

代码语言:javascript
复制
            v0 = _mm_shuffle_epi8(v0, mask_right);
            v1 = _mm_shuffle_epi8(v1, mask);
            v2 = _mm_shuffle_epi8(v2, mask_right);
            v3 = _mm_shuffle_epi8(v3, mask);

            __m128i v2l = v2;
            v0 = _mm_alignr_epi8(v1, v0, 4);
            v1 = _mm_slli_si128(v1, 4);             // mask -> mask_right
            v2 = _mm_alignr_epi8(v3, v2, 12);
            v2l = _mm_srli_si128(v2l, 4);           // mask_right -> mask
            v1 = _mm_alignr_epi8(v2l, v1, 8);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9984355

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档