在 ARM Cortex A8 上的汇编中 XOR NEON 向量/寄存器的所有元素/通道(成对?)
Posted
技术标签:
【中文标题】在 ARM Cortex A8 上的汇编中 XOR NEON 向量/寄存器的所有元素/通道(成对?)【英文标题】:XOR all elements/lanes of NEON vector/register (pairwise?) in assembly on ARM Cortex A8 【发布时间】:2014-05-18 21:55:51 【问题描述】:我不确定这里的确切命名法是什么,但问题是:
我正在处理校验和,我想获取许多不同的 [32 位] 值,将它们存储在 NEON 向量的元素中,将它们异或在一起,然后将结果传回给用于未来计算的 ARM 寄存器。 [校验和有许多基于随机数的不同块,所以我想将这些次要结果“异或”到随机数中,而不会丢失熵]。
我不担心性能(尽管操作越少越好,因为最小化 ARM 的停顿也是如此;NEON 可以停顿它需要的所有东西),或者这不是一个特别可矢量化的操作;我需要为此使用 NEON 装置。
如果有某种水平异或,那将是理想的,其中它将向量的 [4] 个元素相互异或,并返回结果,但这不存在。我显然可以做类似的事情(请原谅残酷的伪代码):
load value1 s0
load value2 s2
veon d2, d0, d1
load value3 s0
load value4 s2
veon d0, d0,d1
veon d0, d0, d2
但是有更好的方法吗?我知道有成对加法,但似乎没有成对异或。我尽可能灵活地使用尽可能多的寄存器通道或寄存器。
TL;DR:我需要在 NEON 上做:res = val1 ^ val2 ^ val3 ^ val4,这可能很愚蠢,但我正在寻找最不愚蠢的方法。
谢谢!
【问题讨论】:
您可以使用 vld4 指令将连续存储在内存中的 4 个 32 位整数加载到 4 个不同的寄存器中。这样,您可以并行异或 4 组 4 个值。 这可能会有所帮助,但数量来自 ARM 寄存器,因此在将它们加载到 NEON 寄存器之前将它们移回内存可能没有好处。另外,我没有 4 组四个值。在任何给定的块中,我都有 一个 组的四个值,我希望将它们全部异或在一起。 如果您的值已经在四个 ARM 寄存器中,只需在 ARM 模式下执行三个 EOR。即使将 ARM 寄存器转移到 NEON 寄存器并且根本不进行任何计算,也比仅使用良好的旧 ARM 计算结果要花费更长的时间。 我需要使用 NEON,因为...我需要使用 NEON。我试图解释a)。这是愚蠢的b)。我知道性能会受到影响和c)。这不是本质上的 SIMD 操作。但我不断得到不相关的答案。如果没有其他问题,我会接受下面的。 【参考方案1】:NEON 的做法。需要展开循环以获得更好的性能,因为它尝试使用需要时间加载的数据。
vld1.u32 q0,[r0]! ; load 4 32-bit values into Q0
veor.u32 d0,d0,d1 ; XOR 2 pairs of values (0<-2, 1<-3)
vext.u8 d1,d0,d0,#4 ; shift down "high" value of d0
veor.u32 d0,d0,d1 ; now element 0 of d0 has all 4 values XOR'd together
vmov.u32 r2,d0[0] ; transfer back to an ARM register
str r2,[r1]! ; store in output
ARM 的做法。加载数据有点慢,但没有等待从 NEON 到 ARM 寄存器传输的延迟。
ldmia r0!,r4-r7 ; load 4 32-bit values
eor r4,r4,r5
eor r4,r4,r6
eor r4,r4,r7 ; XOR all 4 values together
str r4,[r1]! ; store in output
如果您可以指望执行多组 4 个 32 位值,那么 NEON 可以通过加载一堆寄存器然后处理它们来为您提供优势。如果你只是调用一个可以处理 4 个整数的函数,那么 ARM 版本的性能可能会更好。
【讨论】:
感谢您的回答。我很快就会尝试第一个 [NEON] 版本。 你能解释一下这行吗:vld1.u32 q0,[r0]!
?大概它需要一个存储在 r0 的指针并加载四个连续的 32 位字?还是别的什么?以上是关于在 ARM Cortex A8 上的汇编中 XOR NEON 向量/寄存器的所有元素/通道(成对?)的主要内容,如果未能解决你的问题,请参考以下文章