【发布时间】:2013-07-23 11:21:11
【问题描述】:
我需要将 uint8 数组中的值加载到 128 NEON 寄存器中。有一个类似的question。但没有好的答案。
我的解决办法是:
uint8_t arr[4] = {1,2,3,4};
//load 4 of 8-bit vals into 64 bit reg
uint8x8_t _vld1_u8 = vld1_u8(arr);
//convert to 16-bit and move to 128-bit reg
uint16x8_t _vmovl_u8 = vmovl_u8(_vld1_u8);
//get low 64 bit and move them to 64-bit reg
uint16x4_t _vget_low_u16 = vget_low_u16(_vmovl_u8);
//convert to 32-bit and move to 128-bit reg
uint32x4_t ld32x4 = vmovl_u16(_vget_low_u16);
这很好用,但在我看来,这种方法并不是最快的。也许有更好更快的方法将 8bit 数据加载到 128 reg 作为 32bit ?
编辑:
感谢@FrankH。我用一些技巧想出了第二个版本:
uint8x16x2_t z = vzipq_u8(vld1q_u8(arr), q_zero);
uint8x16_t rr = *(uint8x16_t*)&z;
z = vzipq_u8(rr, q_zero);
ld32x4 = *(uint8x16_t*)&z;
归结为这个程序集(当编译器优化开启时):
vld1.8 {d16, d17}, [r5]
vzip.8 q8, q9
vorr q9, q4, q4
vzip.8 q8, q9
因此没有多余的存储,而且速度非常快。但它仍然比第一个解决方案慢大约 x1.5。
【问题讨论】: