将硬浮动链接到 softfp 性能不佳

Posted

技术标签:

【中文标题】将硬浮动链接到 softfp 性能不佳【英文标题】:Linking hard float to softfp bad performance 【发布时间】:2014-07-31 13:28:15 【问题描述】:

我正在编写 c++ 代码以在 ARM cortex a9 CPU 上运行。我的代码链接到使用软浮点编译的封闭源代码 3rd 方库。我正在运行一个 cortex-a9 ARM cpu。

我注意到,如果我使用 gcc 标志 -mfloat-abi=softfp 编译我的代码,它的运行速度要比使用 -mfloat-abi=hard 编译快得多。

我认为硬浮动应该总是更快。是否有意义?

如何优化这些库调用?

谢谢!

一些注意事项:

库接口仅由整数、字符串和指针构成,并且工作正常。 softfp 的加速比约为 x8。 有关二进制文件的 readelf 平台相关信息:

第三方库:

readelf -hA libXXX.so
ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              DYN (Shared object file)
  Machine:                           ARM
  Version:                           0x1
  Entry point address:               0x13780
  Start of program headers:          52 (bytes into file)
  Start of section headers:          1617724 (bytes into file)
  Flags:                             0x4000002, has entry point, Version4 EABI
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         7
  Size of section headers:           40 (bytes)
  Number of section headers:         28
  Section header string table index: 27
Attribute Section: aeabi
File Attributes
  Tag_CPU_name: "ARM9TDMI"
  Tag_CPU_arch: v4T
  Tag_ARM_ISA_use: Yes
  Tag_THUMB_ISA_use: Thumb-1
  Tag_ABI_PCS_wchar_t: 4
  Tag_ABI_FP_denormal: Needed
  Tag_ABI_FP_exceptions: Needed
  Tag_ABI_FP_number_model: IEEE 754
  Tag_ABI_align8_needed: Yes
  Tag_ABI_align8_preserved: Yes, except leaf SP
  Tag_ABI_enum_size: int
  Tag_ABI_optimization_goals: Aggressive Speed

我的二进制文件:

readelf -hA XXX
ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           ARM
  Version:                           0x1
  Entry point address:               0x1b0d4
  Start of program headers:          52 (bytes into file)
  Start of section headers:          1392964 (bytes into file)
  Flags:                             0x5000002, has entry point, Version5 EABI
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         8
  Size of section headers:           40 (bytes)
  Number of section headers:         38
  Section header string table index: 35
Attribute Section: aeabi
File Attributes
  Tag_CPU_name: "Cortex-A9"
  Tag_CPU_arch: v7
  Tag_CPU_arch_profile: Application
  Tag_ARM_ISA_use: Yes
  Tag_THUMB_ISA_use: Thumb-2
  Tag_VFP_arch: VFPv3
  Tag_NEON_arch: NEONv1
  Tag_ABI_PCS_wchar_t: 4
  Tag_ABI_FP_denormal: Needed
  Tag_ABI_FP_exceptions: Needed
  Tag_ABI_FP_number_model: IEEE 754
  Tag_ABI_align8_needed: Yes
  Tag_ABI_align8_preserved: Yes, except leaf SP
  Tag_ABI_enum_size: int
  Tag_ABI_HardFP_use: SP and DP
  Tag_ABI_VFP_args: VFP registers
  Tag_unknown_34: 1 (0x1)
  Tag_unknown_42: 1 (0x1)
  Tag_unknown_44: 1 (0x1)
  Tag_unknown_68: 1 (0x1)

【问题讨论】:

hard-float 如果使用得当会更快。我不认为gcc 会在两者之间自动生成单板。因此,您可能有未定义的行为,这可能会导致性能下降。即,使用-O3-O0 相比,一些糟糕的代码(不符合标准的代码)可能会运行得更慢,因为代码最终会执行未定义的操作,并且通过不同的优化编译成完全不同的内容。 所以,你正在做你不应该做的事情(afaik);将 hard-floatsoftfp 链接。寄存器传递约定是不同的。我相信可以编写某种汇编程序库来在两者之间进行转换;您将填充所有第 3 方 API 并将 hf 寄存器转换为基于堆栈的传递。 根据我的经验,这种情况突然结束,链接器发出“错误:X 使用 VFP 寄存器参数,Y 没有”。显然这里正在发生一些巧妙的诡计...... 谢谢大家,我希望那里可能有别的东西。我想我将不得不使用两个独立的进程,一个 hardfloat 和一个 softfloat 链接到第 3 方,与 IPC 和共享内存通信......这是最简单的解决方案,不是吗? 【参考方案1】:

-mfloat-abi=softfp-mfloat-abi=hard选择的两个ABI不兼容。你不能混搭。

通常情况下,您甚至不能在hardfp 系统上使用softfp 进程,除非您有所有库在不同的lib 目录(即“multiarch”)中重复。 p>

如果您的代码碰巧没有在函数参数中使用 floatdouble 类型,那么您可能会发现它在实践中确实有效,但您仍然不应该这样做,或者你在玩火。

无论如何,如果您的代码完全基于整数,那么这些选项对生成的代码没有影响,因此性能变化肯定来自其他地方。当您意外指定-mfloat-abi 选项时,您使用的编译器可能会自动选择不同的 multilib 或不同的 CPU(特别是 GCC 有切换回默认 multilib 的习惯)。可能是你误开NEON,还是从A8调到A9?

【讨论】:

感谢 ams - 我很确定我的代码完全使用以下标志编译:-march=armv7-a -mfpu=neon -mfloat-abi=hard -mtune=cortex-a9。然而,第三方库是封闭源代码,所以我不知道它做了什么。它工作得很好,接受性能问题。知道为什么吗? 如果您使用的是 Neon,在 Neon/VFP 寄存器中传递参数可能会导致一些冲突。 HF 通常是一种改进,但我相信也有一些反例。 是的。 Official docs 确切地提到了这一点(尽管它可能不如 on A8 糟糕)。还需要注意的是,一些 fp 操作仍然只能在没有extra care 的 VFP 上运行。

以上是关于将硬浮动链接到 softfp 性能不佳的主要内容,如果未能解决你的问题,请参考以下文章

jQuery 滚动事件 - 检测元素滚动到视图中 - Chrome 上的性能不佳

MySQL 性能不佳 INSERT 或 PHP PDO

Elementor:浮动到内部内容右侧的元素会影响内容链接 - 如何修复?

伪类选择器、清除浮动

小米1S无线网连接时老是出现暂时关闭状态不佳的链接

Xampp - 将外部 url 重定向到 localhost