手臂上的每个字节的高点,对于64个字节,例如Avx512 vpmovb2m?

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

__builtin_ia32_cvtb2mask512()
是gnu c内置的vpmovb2m k, zmm
。
Intel的内在是
_mm512_movepi8_mask

它从每个字节中提取最重要的位,产生整数掩码。
SSE2和AVX2指令
pmovmskb

vpmovmskb

对16或32字节向量执行相同的操作,在GPR中生成掩码,而不是AVX-512掩码寄存器。 (

_mm_movemask_epi8

_mm256_movemask_epi8
我希望ARM的实现比以下更快
我想实施武器霓虹灯 我想为ARMSVE
进行实施
我已经在C中附加了基本标量实现。对于那些试图用手臂实现的人,我们关心高位,但是每个字节的高钻头(在128位向量中)可以轻松地使用手臂将其转移到低位霓虹灯内在:vshrq_n_u8()。 请注意,我希望不将位图存储到内存中,它应该只是该函数的返回值,类似于以下函数。

#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){ // shift mask by 1 and OR with MSB of v[i] byte mask=(mask<<1)|((v[i]&0x80)>>7); i++;} return mask; }
  1. 这是16个字节(128B向量)的一种可能的算法,只需将其放入64个字节(512B vector)的循环中:
  2. #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; // per byte, make every bit same as msb g4 msb = vdupq_n_u8(0x80); g4 filled = vceqq_u8(v, msb); // create a mask of each bit value g4 b = {0x80, 0x40, 0x20, 0x01, 0x08, 0x04, 0x02, 0x01, 0x80, 0x40, 0x20, 0x01, 0x08, 0x04, 0x02, 0x01}; // and vectors together g4 z = vandq_u8 (filled,b); // extract lower 8 bytes, hi 8 bytes g3 lo = vget_low_u8(z); g3 hi = vget_high_u8(z); // 'or' the 8 bytes of lo together ... // put in byte 1 of ret // 'or' the 8 bytes of hi together ... // put in byte 2 of ret return ret; }
  3. 当大多数/最佳优化是特定的时,很难优化通用。尤其是您想处理的结果。
EGEG与“检查是否设置高位”的代码相比,比“检查高位设置”的代码要便宜得多。

// per byte, make every bit same as msb g4 msb = vdupq_n_u8(0x80); g4 filled = vceqq_u8(v, msb);

不会在性能上有所作为,但是它在检查是否设置了标志位,所以只需
vcltzq_s8(v)

。即,而不是仅在签名比较中检查值是负的。

如果您只关心是否有一个具有签名位设置的值,那么对于Adv Simd,您只能在比较结果上使用
v == 0x80
,然后才能使用:
c arm simd arm64 neon
1个回答
1
投票

vpmaxq_s8

对于SVE,您不需要它,因为比较本身设置标志。您可以在比较和分支的谓词结果上做
if (vgetq_lane_s64 (vreinterpretq_s64_s8 (res), 0))
。编译器应在优化期间删除

ptest

如果您需要使用哪个元素,则有多种方法。 正如彼得·科德斯(Peter Cordes)在评论中所说的那样,您可以使用AN和特殊面具,然后使用ADV。 simd.
这些模式很常见,并且本质上是标准库中的。  因此,对于最佳序列,我建议您在ARM优化的例程中检查我们在找到更好的方法时不断更新的任何内容。
for neon:

https://github.com/arm-software/optimized-routines/blob/master/string/aarch64/strchr.s

是文件,如上所述。

for sve:
https://github.com/arm-software/optimized-routines/blob/master/string/aarch64/strchr-sve.s,在那里还有一些其他代码,因为

ptest

需要检查null的null终结者,但总体想法是相同的。


clz

	
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.