ARM NEON:从NEON寄存器(Q/D寄存器)中包含的地址加载数据

ARM NEON:从NEON寄存器(Q/D寄存器)中包含的地址加载数据,arm,memory-address,neon,Arm,Memory Address,Neon,我正在编写一个由两部分组成的汇编代码。第一部分从基址加上一些计算值(结果是非常遥远的内存地址)开始计算各种地址(内存)。第二部分必须从第一部分中计算的地址加载数据并使用它们。第一部分和第二部分都是高度可并行的,并且只使用NEON并行 我需要的是找到结合这两部分的最佳方法:使用第一阶段输出的地址加载数据 我尝试过并且似乎有效的是最简单的解决方案: //q8 & q9 have 8 computed addresses VMOV.32 r0, d16[0] //move addresses

我正在编写一个由两部分组成的汇编代码。第一部分从基址加上一些计算值(结果是非常遥远的内存地址)开始计算各种地址(内存)。第二部分必须从第一部分中计算的地址加载数据并使用它们。第一部分和第二部分都是高度可并行的,并且只使用NEON并行

我需要的是找到结合这两部分的最佳方法:使用第一阶段输出的地址加载数据

我尝试过并且似乎有效的是最简单的解决方案:

//q8 & q9 have 8 computed addresses
VMOV.32 r0, d16[0] //move addresses to standard registers
VMOV.32 r1, d16[1]
VMOV.32 r2, d17[0]
VMOV.32 r3, d17[1]
VLD1.8 d28[0], [r0] //load uchar (deinterleaving in d28 and d29)
VLD1.8 d29[0], [r1] //otherwise do not interleave and use VUZP
VLD1.8 d28[1], [r2]
VLD1.8 d29[1], [r3]
VMOV.32 r0, d18[0]
VMOV.32 r1, d18[1]
VMOV.32 r2, d19[0]
VMOV.32 r3, d19[1]
VLD1.8 d28[2], [r0]
VLD1.8 d29[2], [r1]
VLD1.8 d28[3], [r2]
VLD1.8 d29[3], [r3]
...
//data loaded in d28 and d29
在本例中,我使用了四个R寄存器(可以使用更少或更多),并且我正在模拟一个标准VLD2.8在阵列上工作,对d28和d29中的数据进行解交错

由于这个问题(用NEON计算地址并从这些地址加载)经常发生在我身上,有没有更好的方法?
谢谢

你所做的可能有用,但你不应该那样做

手臂->霓虹灯传输灵活,而霓虹灯->手臂传输则不灵活。每次启动时,它们会导致管道暂停浪费约14个周期

在您的情况下,28个周期是白白浪费的。而且我相信用手臂做数学运算会花费更少的时间


坚持到底。在处理多个32位数据(如地址)时,ARMv7从其双重(三重)发布功能中获益匪浅。(乘法除外)

计算加载地址的算法是什么?您是否可以使用v6 simd指令?