Cortex A9 NEON 与 VFP 使用混淆

2023-12-25

我正在尝试为 Cortex A9 ARM 处理器(更具体地说是 OMAP4)构建一个库,对于在浮点运算和 SIMD 上下文中使用 NEON 与 VFP 的情况,我有点困惑。需要注意的是,我知道两个硬件协处理器单元之间的区别(也概述了这里就这样 https://stackoverflow.com/questions/4097034/arm-cortex-a8-whats-the-difference-between-vfp-and-neon),我只是对它们的正确用法有一些误解。

与此相关的是,我使用以下编译标志:

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

我读过 ARM 文档,很多 wiki(像这个 http://pandorawiki.org/Floating_Point_Optimization)、论坛和博客文章,每个人似乎都同意使用 NEON 比使用 VFP 更好 或者至少混合 NEON(例如使用内联函数在 SIMD 中实现一些算法)和 VFP 并不是一个好主意;我还不能 100% 确定这是否适用于整个应用程序\库的上下文或仅适用于代码中的特定位置(函数)。

因此,我使用 neon 作为我的应用程序的 FPU,因为我也想使用内在函数。因此,我遇到了一些麻烦,并且我对如何在 Cortex A9 上最好地使用这些功能(NEON 与 VFP)的困惑只会进一步加深,而不是消除。我有一些代码可以为我的应用程序进行基准测试并使用一些定制的计时器类 其中计算基于双精度浮点。使用 NEON 作为 FPU 会产生完全不合适的结果(尝试打印这些值会导致打印大部分 inf 和 NaN;相同的代码在为 x86 构建时可以顺利运行)。所以我改变了我的计算以使用单精度浮点作为据记录,NEON 不处理双精度浮点。我的基准测试仍然没有给出正确的结果(最糟糕的是现在它不再在 x86 上工作;我认为这是因为精度损失,但我不确定)。所以我几乎完全迷失了:一方面我想使用 NEON 来实现 SIMD 功能,并且使用它作为 FPU 不能提供正确的结果,另一方面将它与 VFP 混合似乎不是一个好主意。 在这方面的任何建议将不胜感激!

我在上述 wiki 的文章中发现了在 NEON 环境下浮点优化应该做什么的总结:

"

  • 仅使用单精度浮点
  • 当您发现 FP 函数出现瓶颈时,请使用 NEON 内在函数/ASM。你可以比编译器做得更好。
  • 最小化条件分支
  • 启用快速运行模式

对于软fp:

  • 内联浮点代码(除非它非常大)
  • 通过指针而不是值传递 FP 参数,并在函数调用之间执行整数工作。

"

我无法对 float ABI 使用 Hard,因为我无法链接到我可用的库。 大多数建议对我来说都是有意义的(除了“运行快速模式”,我不完全理解应该做什么,而且事实上,此时我可以比编译器做得更好),但我不断得到不一致的结果,我现在什么都不确定。

谁能阐明如何正确使用 Cortex A9/A8 的浮点和 NEON 以及我应该使用哪些编译标志?


...论坛和博客文章,每个人似乎都同意使用 NEON 比使用 VFP 更好,或者至少混合 NEON(例如,使用内联函数在 SIMD 中实现一些算法),而 VFP 并不是一个好主意

我不确定这是否正确。根据 ARM 在介绍 NEON 开发文章 |霓虹灯寄存器 http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dht0002a/ch01s03s02.html:

NEON 寄存器组由 32 个 64 位寄存器组成。如果两者都 实现了高级SIMD和VFPv3,它们共享该寄存器 银行。在这种情况下,VFPv3 以 VFPv3-D32 形式实现: 支持32个双精度浮点寄存器。这 集成简化了上下文切换支持的实现,因为 保存和恢复 VFP 上下文的相同例程也保存和恢复 恢复 NEON 上下文。

NEON 单元可以将相同的寄存器组视为:

  • 16 个 128 位四字寄存器,Q0-Q15
  • 三十二个 64 位双字寄存器 D0-D31。

NEON D0-D31 寄存器与 VFPv3 D0-D31 寄存器相同 每个 Q0-Q15 寄存器映射到一对 D 寄存器。 图1.3展示了共享NEON和VFP的不同视图 注册银行。所有这些视图都可以随时访问。软件 不必在它们之间显式切换,因为 使用的指令决定适当的视图。

寄存器不竞争;相反,它们作为寄存器组的视图共存。没有办法吐出 NEON 和 FPU 装备。


与此相关的是,我使用以下编译标志:

-O3 -mcpu=cortex-a9 -mfpu=neon -mfloat-abi=softfp
-O3 -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=softfp

这就是我所做的;你的旅费可能会改变。它源自从平台和编译器收集的信息的混搭。

gnueabihf告诉我该平台使用硬浮动,这可以加快程序调用速度。如有疑问,请使用softfp因为它与硬浮动兼容。

BeagleBone 黑色:

$ 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 
...

所以 BeagleBone 使用:

-march=armv7-a -mtune=cortex-a8 -mfpu=neon -mfloat-abi=hard

立方卡车 v5:

$ 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 

所以 CubieTruck 使用:

-march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard

香蕉派 Pro:

$ 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

所以 Banana Pi 使用:

-march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard

树莓派3:

RPI3 的独特之处在于它采用 ARMv8,但运行 32 位操作系统。这意味着它实际上是 32 位 ARMorAarch32。 32 位 ARM 与 Aarch32 的区别还有更多,但这将向您显示 Aarch32 标志

此外,RPI3 使用 Broadcom A53 SoC,具有 NEON 和可选的 CRC32 指令,但缺少可选的加密扩展。

$ 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

或者可以用(我不知道用来做什么-mtune):

-march=armv7-a -mfpu=neon-vfpv4 -mfloat-abi=hard 

奥德罗德C2:

ODROID C2 使用 Amlogic A53 SoC,但它使用 64 位操作系统。 ODROID C2,它具有 NEON 和可选的 CRC32 指令,但缺少可选的加密扩展(与 RPI3 类似的配置)。

$ gcc -v 2>&1 | grep Target 
Target: aarch64-linux-gnu

$ cat /proc/cpuinfo 
Features    : fp asimd evtstrm crc32

所以 ODROID 使用:

-march=armv8-a+crc -mtune=cortex-a53

在上面的食谱中,我通过查看数据表了解了 ARM 处理器(如 Cortex A9 或 A53)。根据这个答案Unix 和 Linux 堆栈交换 https://unix.stackexchange.com/a/255615/56041,它破译输出/proc/cpuinfo:

CPU 部件:部件号。 0xd03 表示 Cortex-A53 处理器。

因此我们可以从数据库中查找该值。我不知道它是否存在或位于何处。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Cortex A9 NEON 与 VFP 使用混淆 的相关文章

随机推荐