C++ Cortex A9 NEON与VFP使用混淆
我正在尝试为Cortex A9 ARM处理器(更具体地说是OMAP4)构建一个库,但对于在浮点操作和SIMD环境中何时使用NEON vs VFP,我有点困惑。需要注意的是,我知道这两个硬件协处理器单元之间的区别(也有概述),我只是对它们的正确用法有一些误解 与此相关,我使用以下编译标志:C++ Cortex A9 NEON与VFP使用混淆,c++,c,floating-point,arm,neon,C++,C,Floating Point,Arm,Neon,我正在尝试为Cortex A9 ARM处理器(更具体地说是OMAP4)构建一个库,但对于在浮点操作和SIMD环境中何时使用NEON vs VFP,我有点困惑。需要注意的是,我知道这两个硬件协处理器单元之间的区别(也有概述),我只是对它们的正确用法有一些误解 与此相关,我使用以下编译标志: GCC -O3 -mcpu=cortex-a9 -mfpu=neon -mfloat-abi=softfp -O3 -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=softfp
GCC
-O3 -mcpu=cortex-a9 -mfpu=neon -mfloat-abi=softfp
-O3 -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=softfp
ARMCC
--cpu=Cortex-A9 --apcs=/softfp
--cpu=Cortex-A9 --fpu=VFPv3 --apcs=/softfp
-O3 -mcpu=cortex-a9 -mfpu=neon -mfloat-abi=softfp
-O3 -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=softfp
我已经阅读了ARM文档、很多wiki()、论坛和博客文章,每个人似乎都同意使用NEON比使用VFP更好
或者至少混合霓虹灯(例如,使用Instrinsic在SIMD中实现一些算法)和VFP不是一个好主意;我还不能100%确定这是否适用于整个应用程序库的上下文,还是仅适用于代码中的特定位置(函数)
因此,我使用neon作为我的应用程序的FPU,因为我也想使用Intrinsic。因此,我遇到了一点麻烦,我对如何在皮质A9上最好地使用这些功能(NEON vs VFP)的困惑进一步加深,而不是消除。我有一些代码为我的应用程序进行基准测试,并使用一些定制的计时器类
其中的计算基于双精度浮点。使用NEON作为FPU会产生完全不合适的结果(尝试打印这些值会导致打印大部分inf和NaN;为x86构建相同的代码时不会出现任何问题)。因此,我将计算改为使用单精度浮点,因为有文件证明NEON不处理双精度浮点。我的基准测试仍然没有给出正确的结果(最糟糕的是,现在它在x86上不再工作;我认为这是因为精度降低了,但我不确定)。所以我几乎完全迷路了:一方面,我想在SIMD功能中使用NEON,而在FPU不能提供正确的结果时使用它,另一方面,将其与VFP混合似乎不是一个好主意。
在此方面的任何建议都将不胜感激
我在上面提到的wiki中的文章中发现了在NEON环境下浮点优化应该做什么的摘要:
"
- 仅使用单精度浮点
- 当你发现一个瓶颈FP函数时,使用NEON intrinsics/ASM。你可以做得比编译器更好
- 最小化条件分支
- 启用快速运行模式
- 内联浮点代码(除非非常大)
- 通过指针而不是通过值传递FP参数,并在函数调用之间执行整数运算
有谁能解释一下如何正确使用Cortex A9/A8的浮点和霓虹灯,以及我应该使用哪些编译标志吗?我认为这个问题应该分成几个部分,添加一些代码示例,并详细说明目标平台和使用的工具链版本 但为了掩盖混乱的一部分: “使用霓虹灯作为FPU”的建议听起来像是一种误解。NEON是SIMD引擎,VFP是FPU。您可以使用NEON对最多4个单精度值并行执行单精度浮点操作,这(如果可能)有助于提高性能
-mfpu=neon
可以看作是-mfpu=neon-vfpv3
的缩写
有关更多信息,请参阅。我会远离VFP。这就像Thmub模式:它是为编译器设计的。没有必要为它们进行优化 这听起来可能很粗鲁,但我真的不认为霓虹灯的本质有任何意义。这是麻烦多于帮助-如果有的话 只需花两三天时间进行基本的手臂装配:您只需要学习一些环路控制/终止的说明 然后,您就可以开始编写本机NEON代码,而不用担心编译器会做出一些错误/警告 学习霓虹灯指令比所有那些内在的宏要求要低。除此之外,结果要好得多 完全优化的NEON本机代码通常比编写良好的内部代码运行速度快两倍以上 只要在下面的链接中将OP的版本与我的版本进行比较,你就会明白我的意思 问候 。。。论坛和博客帖子以及所有人似乎都同意使用NEON比使用VFP或至少混合NEON更好(例如,使用Instrinsic在SIMD中实现一些算法),而VFP并不是一个好主意 我不确定这是否正确。根据ARM at: NEON寄存器组由32个64位寄存器组成。如果两者都有 实现了高级SIMD和VFPv3,它们共享这个寄存器 银行。在这种情况下,VFPv3以VFPv3-D32形式实现 支持32个双精度浮点寄存器。这 集成简化了上下文切换支持的实现,因为 保存和恢复VFP上下文的相同例程也保存和恢复VFP上下文 还原上下文 NEON装置可以查看与以下相同的寄存器组:
- 16个128位四字寄存器,Q0-Q15
- 32个64位双字寄存器,D0-D31
$ gcc -v 2>&1 | grep Target
Target: arm-linux-gnueabihf
$ cat /proc/cpuinfo
model name : ARMv7 Processor rev 2 (v7l)
Features : half thumb fastmult vfp edsp thumbee neon vfpv3 tls vfpd32
...
-march=armv7-a -mtune=cortex-a8 -mfpu=neon -mfloat-abi=hard
$ gcc -v 2>&1 | grep Target
Target: arm-linux-gnueabihf
$ cat /proc/cpuinfo
Processor : ARMv7 Processor rev 5 (v7l)
Features : swp half thumb fastmult vfp edsp thumbee neon vfpv3 tls vfpv4
-march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard
$ gcc -v 2>&1 | grep Target
Target: arm-linux-gnueabihf
$ cat /proc/cpuinfo
Processor : ARMv7 Processor rev 4 (v7l)
Features : swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt
-march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard
$ gcc -v 2>&1 | grep Target
Target: arm-linux-gnueabihf
$ cat /proc/cpuinfo
model name : ARMv7 Processor rev 4 (v7l)
Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32
...
-march=armv8-a+crc -mtune=cortex-a53 -mfpu=neon-fp-armv8 -mfloat-abi=hard
-march=armv7-a -mfpu=neon-vfpv4 -mfloat-abi=hard
$ gcc -v 2>&1 | grep Target
Target: aarch64-linux-gnu
$ cat /proc/cpuinfo
Features : fp asimd evtstrm crc32
-march=armv8-a+crc -mtune=cortex-a53