Cortex A9 NEON 与 VFP 使用混淆 [英] Cortex A9 NEON vs VFP usage confusion

查看:50
本文介绍了Cortex A9 NEON 与 VFP 使用混淆的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为 Cortex A9 ARM 处理器(更具体地说是 OMAP4)构建一个库,但我对在浮点上下文中何时使用 NEON 与 VFP 有点困惑操作和 SIMD.需要注意的是,我知道 2 个硬件协处理器单元之间的区别(也概述了 这里是 SO),我只是对它们的正确用法有一些误解.

I'm trying to build a library for a Cortex A9 ARM processor(an OMAP4 to be more specific) and I'm in a little bit of confusion regarding which\when to use NEON vs VFP in the context of floating point operations and SIMD. To be noted that I know the difference between the 2 hardware coprocessor units(as also outlined here on SO), I just have some misunderstanding regarding their proper usage.

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

Related to this I'm using the following compilation flags:

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 文档、很多维基(喜欢这个)、论坛和博客帖子,每个人似乎都同意使用 NEON 比使用 VFP 更好或者至少混合使用 NEON(例如使用内部函数在 SIMD 中实现一些算法)和 VFP 并不是一个好主意;我还不能 100% 确定这是否适用于整个应用程序\库的上下文或仅适用于代码中的特定位置(函数).

I've read through the ARM documentation, a lot of wiki(like this one), forum and blog posts and everybody seems to agree that using NEON is better than using VFP or at least mixing NEON(e.g. using the instrinsics to implement some algos in SIMD) and VFP is not such a good idea; I'm not 100% sure yet if this applies in the context of the entire application\library or just to specific places(functions) in code.

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

So I'm using neon as the FPU for my application as I also want to use the intrinsics. As a result I'm in a little bit of trouble and my confusion on how to best use these features(NEON vs VFP) on the Cortex A9 just deepens further instead of clearing up. I have some code that does benchmarking for my app and uses some custom made timer classes in which calculations are based on double precision floating point. Using NEON as the FPU gives completely inappropriate results(trying to print those values results in printing mostly inf and NaN; the same code works without a hitch when built for x86). So I changed my calculations to use single precision floating point as is documented that NEON does not handle double precision floating point. My benchmarks still don't give the proper results(and what's worst is that now it does not work anymore on x86; I think it's because of the lost in precision but I'm not sure). So I'm almost completely lost: on one hand I want to use NEON for the SIMD capabilities and using it as the FPU does not provide the proper results, on the other hand mixing it with the VFP does not seem a very good idea. Any advice in this area will be greatly appreciated !!

我在上述 wiki 的文章中找到了在 NEON 上下文中应该为浮点优化做些什么的总结:

I found in the article in the above mentioned wiki a summary of what should be done for floating point optimization in the context of NEON:

"

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

对于 softfp:

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

"

我不能为浮动 ABI 使用 hard,因为我无法链接到我可用的库.大多数建议对我来说都有意义(除了runfast 模式",我不完全理解它应该做什么,以及目前我可以比编译器做得更好的事实)但我一直得到不一致的结果和我现在什么都不确定.

I cannot use hard for the float ABI as I cannot link with the libraries I have available. Most of the reccomendations make sense to me(except the "runfast mode" which I don't understand exactly what's supposed to do and the fact that at this moment in time I could do better than the compiler) but I keep getting inconsistent results and I'm not sure of anything right now.

谁能解释一下如何为 Cortex A9/A8 正确使用浮点和 NEON 以及我应该使用哪些编译标志?

Could anyone shed some light on how to properly use the floating point and the NEON for the Cortex A9/A8 and which compilation flags should I use?

推荐答案

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

我不确定这是否正确.根据 ARM 在 介绍 NEON 开发文章|NEON 寄存器:

I'm not sure this is correct. According to ARM at Introducing NEON Development Article | NEON registers:

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

The NEON register bank consists of 32 64-bit registers. If both Advanced SIMD and VFPv3 are implemented, they share this register bank. In this case, VFPv3 is implemented in the VFPv3-D32 form that supports 32 double-precision floating-point registers. This integration simplifies implementing context switching support, because the same routines that save and restore VFP context also save and restore NEON context.

NEON 单元可以查看与以下内容相同的寄存器组:

The NEON unit can view the same register bank as:

  • 16 个 128 位四字寄存器,Q0-Q15
  • 32 个 64 位双字寄存器,D0-D31.

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

The NEON D0-D31 registers are the same as the VFPv3 D0-D31 registers and each of the Q0-Q15 registers map onto a pair of D registers. Figure 1.3 shows the different views of the shared NEON and VFP register bank. All of these views are accessible at any time. Software does not have to explicitly switch between them, because the instruction used determines the appropriate view.

寄存器不竞争;相反,它们作为注册银行的观点共存.没有办法摆脱 NEON 和 FPU 设备.

The registers don't compete; rather, they co-exist as views of the register bank. There's no way to disgorge the NEON and FPU gear.

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

Related to this I'm using the following compilation flags:

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

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

Here's what I do; your mileage may vary. Its derived from a mashup of information gathered from the platform and compiler.

gnueabihf 告诉我平台使用硬浮点数,这可以加快过程调用.如果有疑问,请使用 softfp,因为它与硬浮点数兼容.

gnueabihf tells me the platform use hard floats, which can speed up procedural calls. If in doubt, use softfp because its compatible with hard floats.

BeagleBone Black:

$ 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 使用:

So the BeagleBone uses:

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

CubieTruck 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 使用:

So the CubieTruck uses:

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

Banana Pi 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

所以香蕉派使用:

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

树莓派 3:

RPI3 的独特之处在于它的 ARMv8,但它运行的是 32 位操作系统.这意味着它实际上是 32 位 ARM Aarch32.32 位 ARM 与 Aarch32 之间还有一些区别,但这将向您展示 Aarch32 标志

The RPI3 is unique in that its ARMv8, but its running a 32-bit OS. That means its effectively 32-bit ARM or Aarch32. There's a little more to 32-bit ARM vs Aarch32, but this will show you the Aarch32 flags

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

Also, the RPI3 uses a Broadcom A53 SoC, and it has NEON and the optional CRC32 instructions, but lacks the optional Crypto extensions.

$ 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用什么):

Or it can use (I don't know what to use for -mtune):

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

ODROID C2:

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

ODROID C2 uses an Amlogic A53 SoC, but it uses a 64-bit OS. The ODROID C2, it has NEON and the optional CRC32 instructions, but lacks the optional Crypto extensions (similar config to RPI3).

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

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

所以 ODROID 使用:

So the ODROID uses:

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

<小时>

在上面的秘籍中,我通过查看数据表了解了 ARM 处理器(如 Cortex A9 或 A53).根据 Unix 和 Linux Stack Exchange 上的这个答案,它解密了 /proc/cpuinfo 的输出代码>:


In the above recipes, I learned the ARM processor (like Cortex A9 or A53) by inspecting data sheets. According to this answer on Unix and Linux Stack Exchange, which deciphers output from /proc/cpuinfo:

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

CPU part: Part number. 0xd03 indicates Cortex-A53 processor.

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

So we may be able to lookup the value form a database. I don't know if it exists or where its located.

这篇关于Cortex A9 NEON 与 VFP 使用混淆的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆