我有128个32位值(编号从0到127)并按以下方式排序:
0,32,64,96,1,33,65,97,... 31,63,95,127
通过这种排序,我将它们以4个为一组加载到NEON寄存器中以执行一些计算(这需要这样的排序)。
因此我有q0 = (0, 32, 64, 96)
......等等。
我想知道是否有一些简单的方法可以按照自然顺序将它们存回内存(0 1 2 3 ...)
换句话说,是否有更简单的方法或技巧:
vst1.u32 {d0[0]}, [r0]
vst1.u32 {d0[1]}, [r0,#128]
vst1.u32 {d1[0]}, [r0,#256]
vst1.u32 {d1[1]}, [r0,#384]
vst1.u32 {d2[0]}, [r0,#4]
vst1.u32 {d2[1]}, [r0,#132]
...
我不太明白@alignment
后缀与vstx
和vldx
说明的使用情况。这不是一个有用的案例吗?
答案 0 :(得分:2)
对齐(@ 128,@ 256)用于提示处理器读/写不跨越高速缓存行。在这些情况下,可以减少执行的微操作(以及最终使用的循环)的数量。
您的应用程序将受益于允许存储/加载列的指令格式。 Arm手动调用这些通道,如小节(Store a single lane of N-element structure to memory)。
格式支持两个连续的寄存器:{d0,d1,d2,...}并跳过一个寄存器{d0,d2,d4,...}。
mov #128, r1 // initialize value for increment
vst4.32 { d0[0], d2[0], d4[0], d6[0] }, [r0], r1 // columns 0..1
vst4.32 { d0[1], d2[1], d4[1], d6[1] }, [r0], r1 // store at offset 128
vst4.32 { d1[0], d3[0], d5[0], d7[0] }, [r0], r1 // columns 2..3
vst4.32 { d1[1], d3[1], d5[1], d7[1] }, [r0], r1 // columns 2..3
... etc ...
这可能是最好的,因为没有足够的寄存器来洗牌。我相信一个人需要32个Q寄存器。