iphone - NEON:将 uint8_t 数组加载到 128 位寄存器中

标签 iphone c arm neon

我需要将 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);

这很好用,但在我看来这种方法并不是最快的。也许有更好更快的方法将 8 位数据作为 32 位加载到 128 reg 中?

编辑:

感谢@FrankH。我使用一些 hack 想出了第二个版本:

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。

最佳答案

你可以用零做一个“double zip”:

uint16x4_t zero = 0;

uint32x4_t ld32x4 =
    vreinterpretq_u32_u16(
        vzipq_u8(
            vzip_u8(
                vld1_u8(arr),
                vreinterpret_u8_u16(zero)
            ),
            zero
        )
    );

由于 vreinterpretq_*() 是空操作,这归结为三个指令。目前没有交叉编译器,无法验证:(

编辑: 别误会我的意思……虽然 vreinterpretq_*() 不会产生 Neon 指令,但它不是空操作;那是因为它阻止 编译器执行您在使用 widerVal.val[0] 时会看到的那些奇怪的事情。它只告诉编译器,例如:

“你有一个 uint8x16x2_t,但我只想使用其中的一半作为 uint8x16_t,给我一半的寄存器。”

或者:

“您有一个 uint8x16x2_t,但我想将这些 regs 用作 uint32x4_t。”

即它告诉编译器 alias NEON 寄存器集 - 防止 存储/加载到堆栈/从堆栈加载,如果您通过.val[...] 语法。

在某种程度上,.val[...] 语法“是一种 hack”,但更好 方法是使用 vreinterpretq_*() ,“看起来像个 hack”。 使用它会导致更多的指令和更慢/更差的代码。

关于iphone - NEON:将 uint8_t 数组加载到 128 位寄存器中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17808769/

相关文章:

iphone - 为什么我的NSUserDefault值未写入?

ios - UISearchDisplayController 不完全覆盖 subview Controller

c - 在 C 中使用 #ifdef 和 enum

java - JNI 错误 - 使用 CallVoidMethod 时无法调用 [方法]

c++ - 为什么 ARM NEON 不比普通 C++ 快?

embedded - 将 ROMFS 附加到 RAM 中意味着什么?

ios - OpenGL 游戏引擎能否创建它自己的 UIResponder 子类,类似于 Sprite Kit 为 SKNode 所做的?

c - Eclipse 构建的二进制文件太重

c - 这两个中断服务程序中的竞争条件是什么?

android - 在移动网站上使用什么标记/文档类型