ARM平台替代AVX512 vpmovb2m的高效实现需求
提取512位向量字节MSB生成掩码的ARM实现方案需求
背景说明
__builtin_ia32_cvtb2mask512()是对应Intel指令vpmovb2m k, zmm的GNU C内置函数,对应的Intel intrinsic为_mm512_movepi8_mask,核心功能是提取向量中每个字节的最高有效位(MSB),生成一个整数掩码。类似的,SSE2的pmovmskb、AVX2的vpmovmskb指令分别可对16/32字节向量实现该功能,对应intrinsic为_mm_movemask_epi8和_mm256_movemask_epi8。
需求
- 寻求比以下标量实现更快的ARM通用实现
- 寻求ARM NEON实现
- 寻求ARM SVE实现
基础标量C实现
#define _(n) __attribute((vector_size(1<<n),aligned(1))) typedef char V _(6); // 64 bytes, 512 bits typedef unsigned long U; #undef _ U generic_cvtb2mask512(V v) { U mask=0;int i=0; while(i<64){ // 左移掩码1位,再或上v[i]字节的MSB mask=(mask<<1)|((v[i]&0x80)>>7); i++;} return mask; }
实现提示
在ARM平台中,可通过NEON intrinsic vshrq_n_u8()将128bit向量中每个字节的高位移至低位;优先选择不将位图存储到内存,直接以函数返回值形式输出掩码。
16字节(128bit)向量算法示例(可循环扩展至64字节)
#define _(n) __attribute((vector_size(1<<n),aligned(1))) typedef char g4 _(4); // 16 bytes, 128 bits typedef char g3 _(3); // 8 bytes, 64 bits typedef unsigned long U; #undef _ unsigned short get_16msb(g4 v) { unsigned short ret; // 每个字节的所有位都替换为该字节的MSB g4 msb = vdupq_n_u8(0x80); g4 filled = vceqq_u8(v, msb); // 创建对应每个bit位置的掩码 g4 b = {0x80, 0x40, 0x20, 0x01, 0x08, 0x04, 0x02, 0x01, 0x80, 0x40, 0x20, 0x01, 0x08, 0x04, 0x02, 0x01}; // 向量按位与 g4 z = vandq_u8 (filled,b); // 提取低8字节和高8字节 g3 lo = vget_low_u8(z); g3 hi = vget_high_u8(z); // 将低8字节的所有位或运算合并,存入ret的第1个字节 // 将高8字节的所有位或运算合并,存入ret的第2个字节 return ret; }
内容的提问来源于stack exchange,提问作者AG1
相关产品推荐
相关产品推荐

