Assembly 异或ARM Cortex A8组件中霓虹灯矢量/寄存器(成对?)的所有元素/通道

Assembly 异或ARM Cortex A8组件中霓虹灯矢量/寄存器(成对?)的所有元素/通道,assembly,arm,xor,neon,cortex-a8,Assembly,Arm,Xor,Neon,Cortex A8,我不确定确切的命名法是什么,但问题是: 我正在处理校验和,我想取一些不同的[32位]值,将它们存储在霓虹灯向量的元素中,将它们异或在一起,然后将结果传回ARM寄存器以备将来计算。[校验和有许多基于nonce的不同块,因此我想将这些次要结果“异或”到nonce中,而不损失熵] 我不担心性能(尽管更少的操作总是可取的,因为这是最小化手臂停顿;霓虹灯可以暂停它所需要的一切),或者这不是一个特别矢量化的操作;我需要用霓虹灯 如果存在某种水平XOR,它会将向量的[4]个元素彼此XOR,并返回结果,这将是理

我不确定确切的命名法是什么,但问题是:

我正在处理校验和,我想取一些不同的[32位]值,将它们存储在霓虹灯向量的元素中,将它们异或在一起,然后将结果传回ARM寄存器以备将来计算。[校验和有许多基于nonce的不同块,因此我想将这些次要结果“异或”到nonce中,而不损失熵]

我不担心性能(尽管更少的操作总是可取的,因为这是最小化手臂停顿;霓虹灯可以暂停它所需要的一切),或者这不是一个特别矢量化的操作;我需要用霓虹灯

如果存在某种水平XOR,它会将向量的[4]个元素彼此XOR,并返回结果,这将是理想的,但这并不存在。很明显,我可以这样做(请原谅残酷的伪代码):

但是有更好的办法吗?我知道有两两相加,但似乎没有两两异或。我可以灵活地使用尽可能多的寄存器通道或寄存器

TL;DR:我需要在霓虹灯上做:res=val1^val2^val3^val4,这可能很愚蠢,但我正在寻找最不愚蠢的方法


谢谢

霓虹灯的工作方式。需要展开循环以获得更好的性能,因为它尝试使用需要时间加载的数据

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

如果您可以使用多组4 32位值,那么NEON可以通过加载一组寄存器,然后对它们进行处理来为您提供优势。如果您只是调用一个可以处理4个整数的函数,那么ARM版本的性能可能会更好。

您可以使用vld4指令将4个32位整数加载到4个不同的寄存器中,这些整数连续存储在内存中。通过这种方式,您可以并行地对4组4个值进行异或运算。这可能会有所帮助,但数量来自ARM寄存器,因此在将它们加载到NEON寄存器之前将它们移回内存可能没有好处。而且,我没有4组4个值。在任何给定的块中,我都有一组四个值,我想将它们全部异或在一起。如果您的值已经在四个ARM寄存器中,只需在ARM模式下执行三个EOR。即使将ARM寄存器转移到NEON寄存器,并且根本不进行计算,也要比使用旧的ARM计算结果花费更长的时间。我需要使用NEON,因为…我需要使用NEON。我试图解释这一点。这太傻了。我知道性能会受到影响,c)。这不是本质上的SIMD操作。但我一直得到不相关的答案。如果没有其他问题,我会接受下面的答案。谢谢你的回答。我很快会试用第一个[霓虹灯]版本。你能解释一下这句话吗:
vld1.u32{q0},[r0]?大概它接受一个存储在r0的指针并加载四个连续的32位字?还是别的什么?
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
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