我不确定这里的确切术语是什么,但这里有一个问题:
我正在研究一个校验和,我想取一些不同的[32位]值,将它们存储在NEON向量的元素中,将它们XOR在一起,然后将结果传递回ARM寄存器以供将来的计算。[基于nonce的校验和有许多不同的块,所以我想把这些次要结果异或到nonce中,而不损失熵]。
我不担心性能(虽然更少的操作总是可取的,因为是最小化延迟的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,这可能是愚蠢的,但我正在寻找最不愚蠢的方法。
谢谢!
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版本的性能可能会更好。