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 使用混淆 的相关文章

  • WPF DataGrid 多选

    我读过几篇关于这个主题的文章 但很多都是来自 VS 或框架的早期版本 我想做的是从 dataGrid 中选择多行并将这些行返回到绑定的可观察集合中 我尝试创建一个属性 类型 并将其添加到可观察集合中 它适用于单个记录 但代码永远不会触发多个
  • 如何将 std::string& 转换为 C# 引用字符串

    我正在尝试将 C 函数转换为std string参考C 我的 API 如下所示 void GetStringDemo std string str 理想情况下 我希望在 C 中看到类似的东西 void GetStringDemoWrap r
  • 根据属性的类型使用文本框或复选框

    如果我有这样的结构 public class Parent public string Name get set public List
  • 类型中的属性名称必须是唯一的

    我正在使用 Entity Framework 5 并且有以下实体 public class User public Int32 Id get set public String Username get set public virtual
  • C++11 删除重写方法

    Preface 这是一个关于最佳实践的问题 涉及 C 11 中引入的删除运算符的新含义 当应用于覆盖继承父类的虚拟方法的子类时 背景 根据标准 引用的第一个用例是明确禁止调用某些类型的函数 否则转换将是隐式的 例如最新版本第 8 4 3 节
  • 如何从 Visual Studio 将视图导航到其控制器?

    问题是解决方案资源管理器上有 29 个项目 而且项目同时具有 ASP NET MVC 和 ASP NET Web 表单结构 在MVC部分中 Controller文件夹中有大约100个子文件夹 每个文件夹至少有3 4个控制器 视图完全位于不同
  • 如何在 C# 中打开 Internet Explorer 属性窗口

    我正在开发一个 Windows 应用程序 我必须向用户提供一种通过打开 IE 设置窗口来更改代理设置的方法 Google Chrome 使用相同的方法 当您尝试更改 Chrome 中的代理设置时 它将打开 Internet Explorer
  • 传递给函数时多维数组的指针类型是什么? [复制]

    这个问题在这里已经有答案了 我在大学课堂上学习了 C 语言和指针 除了多维数组和指针之间的相似性之外 我认为我已经很好地掌握了这个概念 我认为由于所有数组 甚至多维 都存储在连续内存中 因此您可以安全地将其转换为int 假设给定的数组是in
  • 从经典 ASP 调用 .Net C# DLL 方法

    我正在开发一个经典的 asp 项目 该项目需要将字符串发送到 DLL DLL 会将其序列化并发送到 Zebra 热敏打印机 我已经构建了我的 DLL 并使用它注册了regasm其次是 代码库这使得 IIS 能够识别它 虽然我可以设置我的对象
  • -webkit-box-shadow 与 QtWebKit 模糊?

    当时有什么方法可以实现 webkit box shadow 的工作模糊吗 看完这篇评论错误报告 https bugs webkit org show bug cgi id 23291 我认识到这仍然是一个问题 尽管错误报告被标记为RESOL
  • 如何在 C++ 中标记字符串?

    Java有一个方便的分割方法 String str The quick brown fox String results str split 在 C 中是否有一种简单的方法可以做到这一点 The 增强分词器 http www boost o
  • 方程“a + bx = c + dy”的积分解

    在等式中a bx c dy 所有变量都是整数 a b c and d是已知的 我如何找到整体解决方案x and y 如果我的想法是正确的 将会有无限多个解 由最小公倍数分隔b and d 但我只需要一个解决方案 我可以计算其余的 这是一个例
  • ASP.NET Core 3.1登录后如何获取用户信息

    我试图在登录 ASP NET Core 3 1 后获取用户信息 如姓名 电子邮件 id 等信息 这是我在登录操作中的代码 var claims new List
  • 为什么这个字符串用AesCryptoServiceProvider第二次解密时不相等?

    我在 C VS2012 NET 4 5 中的文本加密和解密方面遇到问题 具体来说 当我加密并随后解密字符串时 输出与输入不同 然而 奇怪的是 如果我复制加密的输出并将其硬编码为字符串文字 解密就会起作用 以下代码示例说明了该问题 我究竟做错
  • C# xml序列化必填字段

    我需要将一些字段标记为需要写入 XML 文件 但没有成功 我有一个包含约 30 个属性的配置类 这就是为什么我不能像这样封装所有属性 public string SomeProp get return someProp set if som
  • C# 动态/expando 对象的深度/嵌套/递归合并

    我需要在 C 中 合并 2 个动态对象 我在 stackexchange 上找到的所有内容仅涵盖非递归合并 但我正在寻找能够进行递归或深度合并的东西 非常类似于jQuery 的 extend obj1 obj2 http api jquer
  • 如何在 Android 中使用 C# 生成的 RSA 公钥?

    我想在无法假定 HTTPS 可用的情况下确保 Android 应用程序和 C ASP NET 服务器之间的消息隐私 我想使用 RSA 来加密 Android 设备首次联系服务器时传输的对称密钥 RSA密钥对已在服务器上生成 私钥保存在服务器
  • 编译时展开 for 循环内的模板参数?

    维基百科 here http en wikipedia org wiki Template metaprogramming Compile time code optimization 给出了 for 循环的编译时展开 我想知道我们是否可以
  • MySQL Connector C/C API - 使用特殊字符进行查询

    我是一个 C 程序 我有一个接受域名参数的函数 void db domains query char name 使用 mysql query 我测试数据库中是否存在域名 如果不是这种情况 我插入新域名 char query 400 spri
  • Mono 应用程序在非阻塞套接字发送时冻结

    我在 debian 9 上的 mono 下运行一个服务器应用程序 大约有 1000 2000 个客户端连接 并且应用程序经常冻结 CPU 使用率达到 100 我执行 kill QUIT pid 来获取线程堆栈转储 但它总是卡在这个位置

随机推荐