我如何使用ARM NEON内在订货矢量数据?
-
26-09-2019 - |
题
此具体涉及ARM氖SIMD编码。我使用的ARM霓虹灯instrinsics在视频解码器某个模块。我有一个矢量数据,如下所示:
有在NEON寄存器4种32位元素 - 比方说,Q0 - 这是大小为128位的。
3B 3A 1B 1A
有其他霓虹灯寄存器发言权Q1其大小为128比特的另外四个32位元素。
3D 3C 1D 1C
我想要的最终数据是在顺序如下所示:
1D 1C 1B 1A
3D 3C 3B 3A
什么霓虹灯instrinsics可以实现所期望的数据的订单?
解决方案
怎么是这样的:
int32x4_t q0, q1;
/* split into 64 bit vectors */
int32x2_t q0_hi = vget_high_s32 (q0);
int32x2_t q1_hi = vget_high_s32 (q1);
int32x2_t q0_lo = vget_low_s32 (q0);
int32x2_t q1_lo = vget_low_s32 (q1);
/* recombine into 128 bit vectors */
q0 = vcombine_s32 (q0_lo, q1_lo);
q1 = vcombine_s32 (q0_hi, q1_hi);
在理论上这应该编译成只有两个移动指令,因为vget_high和vget_low只是重新解释128位Q寄存器,两个64位d的寄存器。 vcombine OTOH只是编译为一个或两个移动(取决于寄存器分配)。
噢 - 在输出的整数的顺序可能是完全围绕着错误的方式。如果是的话只是交换的参数vcombine_s32。
其他提示
记住每个Q寄存器由两个d寄存器,例如Q0的低部分为D0和高部d1。所以,事实上,这种操作只是交换D0和D3(或D1和D2,它不完全来自你的数据呈现清除)。甚至有一个交换指令做在一个指令!
免责声明:我不知道NEON内在(我直接在汇编代码),但如果这不能使用内部函数来完成我会感到惊讶。
看起来你应该能够使用VTRN
指令(例如vtrnq_u32
)这一点。
皮尔是正确的。
VSWP D0,D3
这会做。
@Pierre: 我几个月前了解NEON后你的博客。我感到惊喜,有我这样的人 - 写手工优化汇编代码,ARM和NEON。 很高兴见到你。
不隶属于 StackOverflow