在一个专注于提高ARM性能的项目中,我正在使用下页中的mm_shuffle_epi8实现https://github.com/f4exb/cm256cc/blob/master/sse2neon.h#L981.
但上述实现是次优的,并导致性能成本。
对于ARM,_mm_shuffle_ep8是否存在右等价项?
等价物应该是类似的东西
uint8x16_t shuffle_epi8(uint8x16_t table, uint8x16_t index) {
int8x16_t mask = vshrq_n_s8(vreinterpretq_s8_u8(index), 7);
index = vandq_u8(index, vdupq_n_u8(15));
index = vqtbl1q_u8(table, index);
return vbicq_u8(index, vreinterpretq_u8_s8(mask));
}
在armv7上,需要通过模拟16位宽的表
inline uint8x16_t vqtbl1q_u8(uint8x16_t table, uint8x16_t idx) {
uint8x8x2_t table2{vget_low_u8(table), vget_high_u8(table)};
uint8x8_t lo = vtbl2_u8(table2, vget_low_u8(idx));
uint8x8_t hi = vtbl2_u8(table2, vget_high_u8(idx));
return vcombine_u8(lo, hi);
}
vtbl2
(可能还有vtbx2
(正是您想要的。
但请注意,这些指令的延迟很长,尤其是在Cortex-a57和Cortex-a72上。(aarch64
模式(它甚至没有在a-57上传输。
我自己会不惜一切代价避开它们:太贵了。
NEON具有优于AVX
的置换指令。也许你可以找到一个变通办法。
PS:SSE2NEON。。。。IMO,这不是一个好主意。你给出的链接的方式太可怕了。