让我们以“ABAA”为例。我可以使用result = vceqq_u8(input, vdupq_n_u8('A'))来获得FF 00 FF FF(或0xFFFF00FF)。有时我只需要知道第一个匹配项,有时我想知道所有匹配项。从结果寄存器中,有没有方法可以得到A)第一个匹配项的索引?在本例中是0,因为它以'A'开头(低字节是FF)B)得到二进制1101?(只有第二个字母不匹配,所以第二位是0)在avx2上,我使用movemask来获取位,使用tzcnt来获取索引。
result = vceqq_u8(input, vdupq_n_u8('A'))
0
dhxwm5r41#
Shift-Right-then-Narrow指令可以将128位字节掩码缩减为64位半字节掩码。这允许将掩码提取到64位通用寄存器。
uint8x16_t byte_mask = vceqq_u8(input, vdupq_n_u8('A')) uint8x8_t nibble_mask = vshrn_n_u16(vreinterpretq_u16_u8(byte_mask), 4); uint64_t result = vget_lane_u64(vreinterpret_u64_u8(nibble_mask), 0);
请参阅Danila Kutenin的这篇博客文章:Porting x86 vector bitmask optimizations to Arm NEON对于pmovmskb样式结果位掩码:提取128位比较掩码的每一半64位,然后将每一半乘以一个幻数(因为每个字节不是0xFF就是0x 00......不需要通常的AND掩码)。查看Arseny Kapoulkine的这篇博客文章:VPEXPANDB on NEON with Z3对于64字节到64位的批量操作,请参阅我对Geoff Langdale的博客文章的评论:Fitting My Head Through The ARM Holes or: Two Sequences to Substitute for the Missing PMOVMSKB Instruction on ARM NEON中的一个。基本上:转置源字节,然后使用Shift-Right-Insert指令将位组合在一起。
pmovmskb
1条答案
按热度按时间dhxwm5r41#
Shift-Right-then-Narrow指令可以将128位字节掩码缩减为64位半字节掩码。这允许将掩码提取到64位通用寄存器。
请参阅Danila Kutenin的这篇博客文章:Porting x86 vector bitmask optimizations to Arm NEON
对于
pmovmskb
样式结果位掩码:提取128位比较掩码的每一半64位,然后将每一半乘以一个幻数(因为每个字节不是0xFF就是0x 00......不需要通常的AND掩码)。查看Arseny Kapoulkine的这篇博客文章:VPEXPANDB on NEON with Z3
对于64字节到64位的批量操作,请参阅我对Geoff Langdale的博客文章的评论:Fitting My Head Through The ARM Holes or: Two Sequences to Substitute for the Missing PMOVMSKB Instruction on ARM NEON中的一个。
基本上:转置源字节,然后使用Shift-Right-Insert指令将位组合在一起。