SSE 寄存器中第一个零之后的剩余字节为零

问题描述 投票:0回答:2

对于这个问题,我将使用符号

1
表示全 1 的字节 (0xFF),使用
0
表示全 0 的字节。

我正在寻找一种方法,使用 SSE 4.2 内在函数将 SSE 寄存器中第一个零字节后的剩余字节清零:

输入示例:
1111'1101'1011'1000
所需输出:
1111'1100'0000'0000

请注意,数据应保留在上交所寄存器中。这是在简单字节数组中完成的一项简单任务!

c++ sse sse4
2个回答
2
投票

你可以这样做:

  1. _mm_movemask_epi8
    切换到通用寄存器中的位
  2. 按位取反和
    lzcnt
    找到
    0
    的位置(如果不允许 BMI,请使用
    _BitScanReverse
  3. 使用 16 减去零位置作为索引,从 16 0x00 字节和 16 0xFF 字节的预定义内存数组中执行
    _mm_loadu_si128

最后一步与您的要求相矛盾

请注意,数据应保留在上交所寄存器中。这是在简单字节数组中完成的一项简单任务!

但是,如果该要求是出于性能原因,那么我没有找到一种方法可以在远离内存操作数的情况下更有效地完成此操作。


1
投票

SSE4.2 提供返回掩码或索引的字符串指令。在你的情况下,这应该有效:

// generate a mask of `0xff` until first `0` entry of `a`:
__m128i mask_until_first_zero(__m128i a)
{
    return _mm_cmpistrm(a, a, _SIDD_UNIT_MASK);
}
© www.soinside.com 2019 - 2024. All rights reserved.