这与ARM Neon SIMD编码有关。我正在使用ARM Neon instrinsics来处理视频解码器中的某些模块。我有一个矢量化数据如下:
氖寄存器中有四个32位元素 - 比如Q0 - 大小为128位。
3B 3A 1B 1A
在其他Neon寄存器中还有另外四个32位元素,即Q1,大小为128位。
3D 3C 1D 1C
我希望最终数据按顺序排列如下:
1D 1C 1B 1A
3D 3C 3B 3A
Neon instrinsics可以实现所需的数据顺序吗?
答案 0 :(得分:10)
这样的事情怎么样:
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。
答案 1 :(得分:4)
记住每个q寄存器由两个d寄存器组成,例如q0的低电平部分为d0,高电平部分为d1。所以实际上,这个操作只是交换d0和d3(或d1和d2,你的数据表示并不完全清楚)。在一条指令中甚至还有交换指令!
免责声明:我不知道Neon内在函数(我直接在汇编代码中编写代码),但如果使用内在函数无法做到这一点,我会感到惊讶。
答案 2 :(得分:3)
看起来您应该能够使用VTRN
指令(例如vtrnq_u32
)。
答案 3 :(得分:2)
皮埃尔是对的。
vswp d0,d3
将会这样做。
@Pierre: 我几个月前在你的博客上阅读了关于NEON的帖子。令我惊喜的是,有像我这样的人 - 编写手动优化的汇编代码,包括ARM和NEON。 很高兴见到你。