将硬浮动链接到 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-float 与 softfp 链接。寄存器传递约定是不同的。我相信可以编写某种汇编程序库来在两者之间进行转换;您将填充所有第 3 方 API 并将 hf 寄存器转换为基于堆栈的传递。
根据我的经验,这种情况突然结束,链接器发出“错误:X 使用 VFP 寄存器参数,Y 没有”。显然这里正在发生一些巧妙的诡计......
谢谢大家,我希望那里可能有别的东西。我想我将不得不使用两个独立的进程,一个 hardfloat 和一个 softfloat 链接到第 3 方,与 IPC 和共享内存通信......这是最简单的解决方案,不是吗?
【参考方案1】:
-mfloat-abi=softfp
和-mfloat-abi=hard
选择的两个ABI不兼容。你不能混搭。
通常情况下,您甚至不能在hardfp
系统上使用softfp
进程,除非您有所有库在不同的lib
目录(即“multiarch”)中重复。 p>
如果您的代码碰巧没有在函数参数中使用 float
或 double
类型,那么您可能会发现它在实践中确实有效,但您仍然不应该这样做,或者你在玩火。
无论如何,如果您的代码完全基于整数,那么这些选项对生成的代码没有影响,因此性能变化肯定来自其他地方。当您意外指定-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 上的性能不佳