此具体涉及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。 很高兴见到你。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top