Ben*_*tto 7 arm simd intrinsics neon ios
我正在使用ARM NEON内在函数(llvm,iOS)向量化内循环.我一般都在使用float32x4_t
s.我的计算结束时需要对这个向量中的四个浮点数中的三个进行求和.
此时我可以回到C浮点数并vst1q_f32
获得四个值并将我需要的三个加起来.但我认为如果有一种方法可以直接用一两条指令中的向量来实现它,那么只需抓住一条单一的通道结果,但我无法弄清楚这样做的任何明确路径.
我是NEON编程的新手,现有的"文档"非常可怕.有任何想法吗?谢谢!
您应该能够将 VFP 单元用于此类任务。NEON 和 VFP 共享相同的寄存器组,这意味着您无需在寄存器周围进行混洗来利用一个单元,而且它们也可以对相同的寄存器位有不同的看法。
您float32x4_t
是 128 位,因此它必须位于 Quad (Q) 寄存器上。如果您仅使用 arm 内在函数,您将不知道您使用的是哪一个。问题是如果它高于 4,VFP 不能将其视为单精度(对于好奇的读者:我保持简单,因为 VFP 版本之间存在差异,这是最低要求。)。所以最好把你的移动float32x4_t
到一个固定的寄存器,比如Q0
. 在此之后,您可以对 S0、S1、S2 等寄存器进行求和,vadd.f32
并将结果移回 ARM 寄存器。
一些警告... VFP 和 NEON 理论上是不同的执行单元,它们共享相同的寄存器组和管道。我不确定这种方法是否比其他方法更好,我不需要再说一次,你应该做基准测试。此外,这种方法并没有通过内在霓虹灯进行简化,因此您可能需要使用内联汇编来制作代码。
我做了一个简单的片段来看看它的样子,我想出了这个:
#include "arm_neon.h"
float32_t sum3() {
register float32x4_t v asm ("q0");
float32_t ret;
asm volatile(
"vadd.f32 s0, s1\n"
"vadd.f32 s0, s2\n"
"vmov %[ret], s0\n"
: [ret] "=r" (ret)
:
:);
return ret;
}
Run Code Online (Sandbox Code Playgroud)
objdump
它看起来像(用 gcc -O3 -mfpu=neon -mfloat-abi=softfp 编译)
00000000 <sum3>:
0: ee30 0a20 vadd.f32 s0, s0, s1
4: ee30 0a01 vadd.f32 s0, s0, s2
8: ee10 3a10 vmov r0, s0
c: 4770 bx lr
e: bf00 nop
Run Code Online (Sandbox Code Playgroud)
如果你试一试,我真的很想听听你的印象!
归档时间: |
|
查看次数: |
2522 次 |
最近记录: |