使用 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
寄存器进行操作,但是在存储方面,它必须重新创建具有每个部分的向量,而不是使用q0
、q1
、q2
和q3
在d
寄存器之一中,例如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 寄存器的最快方法的主要内容,如果未能解决你的问题,请参考以下文章
ARM NEON:从 NEON 寄存器(Q/D 寄存器)中包含的地址加载数据
使用内在函数测试 128 位 NEON 寄存器的值为 0 的最快方法?