【问题标题】:Fastest way of storing non-adjacent d registers with NEON intrinsics使用 NEON 内部函数存储非相邻 d 寄存器的最快方法
【发布时间】:2026-01-14 14:00:02
【问题描述】:

我正在将 32 位 NEON asm 代码移植到 NEON 内部函数,我想知道是否可以使用内部函数以简洁的方式编写此代码:

vst4.32 {d0[0], d2[0], d4[0], d6[0]}, [%[v1]]!

1) 前面的代码对q 寄存器进行操作,但是在存储方面,它必须重新创建具有每个部分的向量,而不是使用q0q1q2q3d 寄存器之一中,例如v1[0] = d0[0], v1[1] = d2[0] ... v2[0] = d0[1], v2[1] = d2[1] ... v3[0] = d1[0], v3[1] = d3[0] ...

此操作是 asm 中的单行操作,但如果使用内在函数,我不知道是否可以在不首先拆分高位和低位并构建新的 float32x4x4_t 变量以提供给 vst4_f32 的情况下做到这一点。

这可能吗?

2) 我不完全确定 [%[v1]]! 做了什么(是的,我用谷歌搜索了很多):它应该是对名为 v1 的变量的引用,感叹号会做 writeback,这应该意味着指针增加了与同一行上的指令写入相同的数量。

对吗?有什么方法可以用内在函数复制它?

【问题讨论】:

    标签: ios neon


    【解决方案1】:

    经过一番调查,我找到了store a specific lane of an array of 4 vectors的这个具体指令,所以不需要分成高位和低位变量:

    float32x4x4_t u = { q0, q1, q2, q3 };
    vst4q_lane_f32(v1, u, 0);
    v1 += 4;
    

    正如@charlesbaylis 所写,Writeback 只是一个增加的指针。

    【讨论】:

      【解决方案2】:

      原则上,足够智能的编译器可以为 vst4_f32 内部函数使用您想要的指令,但实际上,没有编译器那么好。

      要获得索引后写回,您可以编写

      vst4_f32(ptr, v);
      ptr += 4;
      

      一些编译器会识别这一点。 GCC 5.1(发布时)至少在某些情况下会这样做。

      [编辑:误读问题,vst4q_lane_f32 确实完美映射到所需指令]

      【讨论】:

      • 谢谢我做了类似的事情,看看我的回答。
      • PS:由于问题被标记为 iOS,编译器仅是 Clang
      【解决方案3】:

      它似乎是内联汇编。 无论如何,答案是:

      1) 没有

      2) 是的

      【讨论】: