2

我正在研究由两部分组成的汇编 ARM NEON 代码。第一部分从添加到某些计算值的基地址开始计算各种地址(内存)(结果是非常遥远的内存地址)。第二部分必须从第一部分计算的地址加载数据并使用它们。第一部分和第二部分都是高度可并行化的,并且仅使用 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 寄存器(可以使用更少或更多),并且我正在对 d28 和 d29 中的数据进行解交织,以模拟在阵列上工作的标准 VLD2.8。

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

4

1 回答 1

1

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

虽然 ARM->NEON 传输是灵活的,但 NEON->ARM 传输却不是。它们会导致流水线停顿,每次启动都会浪费大约 14 个周期。

在您的情况下,28 个周期白白浪费了。而且我敢肯定,用 ARM 做数学运算会少得多。

坚持ARM。在处理多个 32 位数据(如地址)时,ARMv7 极大地受益于其双(三)发能力。(乘法除外)

于 2013-09-29T23:45:42.463 回答