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

如何使用ARM Neon内部函数对矢量数据重新排序?,arm,simd,neon,intrinsics,Arm,Simd,Neon,Intrinsics,这与ARM Neon SIMD编码特别相关。我正在为视频解码器中的某个模块使用ARM Neon Instrinsic。我有一个矢量化数据,如下所示: 霓虹灯寄存器中有四个32位元素,比如Q0,大小为128位 3B 3A 1B 1A 3D 3C 1D 1C 在另一个Neon寄存器中还有4个32位元素,比如Q1,大小为128位 3B 3A 1B 1A 3D 3C 1D 1C 我希望最终数据的顺序如下所示: 1D 1C 1B 1A 3D 3C 3B 3A 什么Neon Instrinstic

这与ARM Neon SIMD编码特别相关。我正在为视频解码器中的某个模块使用ARM Neon Instrinsic。我有一个矢量化数据,如下所示:

霓虹灯寄存器中有四个32位元素,比如Q0,大小为128位

3B 3A 1B 1A
3D 3C 1D 1C
在另一个Neon寄存器中还有4个32位元素,比如Q1,大小为128位

3B 3A 1B 1A
3D 3C 1D 1C
我希望最终数据的顺序如下所示:

1D 1C 1B 1A
3D 3C 3B 3A

什么Neon Instrinstics可以实现所需的数据顺序?

看起来您应该能够使用
VTRN
指令(例如
vtrnq\u u32
)来实现这一点。

类似这样的东西怎么样:

  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 Intrinsic(我直接在汇编中编写代码),但如果不能使用Intrinsic实现这一点,我会感到惊讶。

Pierre是对的

vswp d0,d3

那就行了

@皮埃尔: 几个月前我在你的博客上读到了关于霓虹灯的帖子。我惊喜地发现,有人和我一样——编写手工优化的汇编代码,包括ARM和NEON。
很高兴见到你。

最后的数据顺序是什么?应该是
3D 3C 3B 3A
?@Paul R:谢谢,更正了它。@Paul:vtrnq_u32没有帮助。实际上,我需要做一个类似VTRN.64的操作,但遗憾的是,没有类似VTRN.64的指令/内在指令。@goldenmean:对不起-我现在明白你的意思了-NEON似乎缺少通用的排列/洗牌操作。@Antonio:谢谢-遗憾的是,教程现在似乎完全消失了,所以我删除了链接。