使用 NEON 内部函数存储非相邻 d 寄存器的最快方法

Posted

技术标签:

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

我正在将 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,这应该意味着指针增加了与同一行上的指令写入相同的数量。

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

【问题讨论】:

【参考方案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) 是的

【讨论】:

以上是关于使用 NEON 内部函数存储非相邻 d 寄存器的最快方法的主要内容,如果未能解决你的问题,请参考以下文章

将 NEON 组件与非向量函数混合

ARM NEON:从 NEON 寄存器(Q/D 寄存器)中包含的地址加载数据

使用内在函数测试 128 位 NEON 寄存器的值为 0 的最快方法?

ARM NEON:如何对整个 64 位 d 寄存器进行位移?

使用 ARM neon 内部函数进行深度转换

存储类链接内存管理