我有4个车道d0,d1,d2,d3我希望平均四个相邻:
d0[0] = (d0[0] + d0[1] + d0[2] + d0[3]) / 4
d0[1] = (d0[4] + d0[5] + d0[6] + d0[7]) / 4
d0[2] = (d1[0] + d1[1] + d1[2] + d1[3]) / 4
...
以下霓虹灯代码是否正确?
vpaddl.u8 d0, d0
vpaddl.u8 d1, d1
vpaddl.u8 d2, d2
vpaddl.u8 d3, d3
vpadd.u16 d0, d0, d2
vshrn.u16 d0, q0, #2
如果是,有更快的方法吗?
编辑1
上面的代码不正确。我想出了以下内容:
vpaddl.u8 d0, d0
vpaddl.u8 d1, d1
vpaddl.u8 d2, d2
vpaddl.u8 d3, d3
vuzp.u16 q0, q1
vadd.u16 q0, q0, q1
vshrn.u16 d0, q0, #2
哪个有效。这非常类似于Notlikethat'的第二个建议。接受了答案,但采用的方式不太优化。
答案 0 :(得分:3)
经过一段时间playing around之后,我会说在给定的约束条件下,你的一般方法可能与你将得到的一样好。有超过4个寄存器值的数据同时处理,和/或有机会吸收算法中其他地方重新排列向量的成本,结论可能会有所不同,但其他可行选项非常有限。
但是,您在第二轮缩减中忘记了d1
和d3
,并且第一轮可以简化为两条指令,因为与vpadd
不同,{{1}确实有一个Q寄存器形式。修复这些最终结果:
vpaddl
就纯指令计数而言, 可以通过进行部分转置然后直接累积两个成对约简来降低,因此:
vpaddl.u8 q0, q0
vpaddl.u8 q1, q1
vpadd.u16 d0, d0, d1
vpadd.u16 d1, d2, d3
vshrn.u16 d0, q0, #2
但是Q-form vuzp.16 q0, q1
vpaddl.u8 q0, q0
vpadal.u8 q0, q1
vshrn.u16 d0, q0, #2
确实非常昂贵我可以找到指令时间,vuzp
的累积也不是免费的,所以几乎可以肯定最终整体表现会比更直接的版本更差。