【问题标题】:How do I reorder vector data using ARM Neon intrinsics?如何使用 ARM Neon 内在函数重新排序矢量数据?
【发布时间】:2011-02-06 15:50:05
【问题描述】:

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

在 Neon 寄存器中有四个 32 位元素 - 例如 Q0 - 大小为 128 位。

3B 3A 1B 1A

在其他 Neon 寄存器中还有另外四个 32 位元素,例如 Q1,其大小为 128 位。

3D 3C 1D 1C

我希望最终数据按如下顺序排列:

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

什么 Neon 内在函数可以实现所需的数据顺序?

【问题讨论】:

  • 最终数据顺序中的错字?应该是3D 3C 3B 3A
  • @Paul R:谢谢,已更正。

标签: arm simd neon intrinsics


【解决方案1】:

看起来您应该能够为此使用VTRN 指令(例如vtrnq_u32)。

【讨论】:

  • @Paul:vtrnq_u32 没有帮助。实际上我需要做类似 VTRN.64 的事情,但遗憾的是没有像 VTRN.64 这样的指令/内在函数。
  • @goldenmean:抱歉 - 我现在明白你的意思了 - NEON 似乎缺少通用的置换/洗牌操作。
  • @Antonio:谢谢 - 遗憾的是该教程现在似乎完全消失了,所以我删除了链接。
【解决方案2】:

这样的事情怎么样:

  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。

【讨论】:

    【解决方案3】:

    记住每个 q 寄存器由两个 d 寄存器组成,例如 q0 的低位是 d0,高位是 d1。所以其实这个操作只是交换d0和d3(或者d1和d2,从你的数据呈现上看不太清楚)。甚至还有一条交换指令可以在一条指令中完成!

    免责声明:我不知道 Neon 内在函数(我直接在汇编中编写代码),但如果使用内在函数无法做到这一点,我会感到惊讶。

    【讨论】:

      【解决方案4】:

      皮埃尔是对的。

      vswp d0, d3

      这样就可以了。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-09-18
        • 2011-05-28
        • 2013-09-16
        • 1970-01-01
        • 1970-01-01
        • 2012-06-30
        • 1970-01-01
        • 2014-05-06
        相关资源
        最近更新 更多