如何使用ARM Neon内在函数重新排序矢量数据?

时间:2010-04-11 07:02:14

标签: arm simd neon intrinsics

这与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可以实现所需的数据顺序吗?

4 个答案:

答案 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。 很高兴见到你。