硬浮点数和软浮点数有什么区别?
当我使用交叉工具链编译 C 代码时,链接器会打印警告页面,指出我的可执行文件使用硬浮点数,但我的 libc 使用软浮点数。有什么区别?
When I compile C code with my cross toolchain, the linker prints pages of warnings saying that my executable uses hard floats but my libc uses soft floats. What's the difference?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
硬浮点数使用片上浮点单元。软浮标在软件中模拟浮标。区别在于速度。看到两者在同一目标架构上使用很奇怪,因为该芯片要么有 FPU,要么没有。您可以使用 -msoft-float 在 GCC 中启用软浮点。如果您使用它,您可能需要重新编译 libc 以使用硬件浮点。
Hard floats use an on-chip floating point unit. Soft floats emulate one in software. The difference is speed. It's strange to see both used on the same target architecture, since the chip either has an FPU or doesn't. You can enable soft floating point in GCC with -msoft-float. You may want to recompile your libc to use hardware floating point if you use it.
严格来说,所有这些答案对我来说似乎都是错误的。
Debian VFP wiki 提供了有关
-mfloat-abi
的三种选择的信息>,soft
- 这是纯软件softfp
- 支持硬件 FPU,但 ABI 是软兼容的。硬
- ABI 使用浮点 或VFP 寄存器。链接器(加载器)错误是因为您有一个共享库将在整数寄存器中传递浮点值。您仍然可以使用
-mfpu=vfp
等编译代码,但您应该使用-mfloat-abi=softfp
以便如果 libc需要一个浮点数,它以库理解的方式传递。Linux内核可以支持VFP指令的模拟。显然,在这种情况下,您最好使用 -mfpu=none 进行编译,并让编译直接生成代码,而不是依赖任何 Linux 内核模拟。但是,我不认为OP的错误实际上与这个问题有关。它是单独的,也必须与
-mfloat-abi
一起处理。Armv5 共享库ArmV7 CPU 与此相反; libc 是硬浮动,但应用程序只是软。它有一些方法可以解决该问题,但使用正确的选项重新编译始终是最简单的。
另一个问题是 Linux 内核必须支持 VFP 任务(或任何存在的 ARM 浮点)才能在上下文切换时保存/恢复寄存器。
Strictly speaking, all of these answers seem wrong to me.
The Debian VFP wiki has information on the three choices for
-mfloat-abi
,soft
- this is pure softwaresoftfp
- this supports a hardware FPU, but the ABI is soft compatible.hard
- the ABI uses float or VFP registers.The linker (loader) error is because you have a shared library that will pass floating point values in integer registers. You can still compile your code with a
-mfpu=vfp
, etc but you should use-mfloat-abi=softfp
so that if the libc needs a float it is passed in a way the library understands.The Linux kernel can support emulation of the VFP instructions. Obviously, you are better off to compile with
-mfpu=none
for this case and have the compile generate code directly instead of relying on any Linux kernel emulation. However, I don't believe the OP's error is actually related to this issue. It is separate and must also be dealt with along with the-mfloat-abi
.Armv5 shared library with ArmV7 CPU is an opposite of this one; the libc was hard float but the application was only soft. It has some ways to work around the issue, but recompiling with correct options is always the easiest.
Another issue is that the Linux kernel must support VFP tasks (or whatever ARM floating point is present) to save/restore the registers on a context switch.
进行浮点运算有三种方法:
There are three ways to do floating point arithmetic:
听起来你的 libc 是为软件浮点运算而构建的,而你的 exe 是在假设硬件支持浮点的情况下编译的。在短期内,您可以强制软浮点数作为编译器标志。 (如果您使用的是 gcc,我认为它是 -msoft-float)
从长远来看,如果您的目标处理器具有对浮点运算的硬件支持,您通常会希望构建或找到启用硬件浮点的交叉工具链以提高速度。某些处理器系列具有型号变体,有些具有硬件支持,有些则没有硬件支持。因此,举例来说,仅仅说您的处理器是 ARM 并不足以了解您是否有硬件浮点支持。
It sounds like your libc was built for software floating point operations while your exe was compiled assuming hardware support for floating point. In the short term, you could force soft floats as a compiler flag. (if you're using gcc I think it's -msoft-float)
Longer term, if your target's processor has hardware support for floating point operations you'll generally want to build or find a cross toolchain with hardware float enabled for speed. Some processor families have model variants some with and some without hardware support. So, for example, just saying your processor is an ARM is insufficient to know if you have hardware floating point support.
计算可以通过浮点硬件或基于整数运算的软件来完成。
在硬件中执行此操作要快得多,但许多微控制器没有浮点硬件。在这种情况下,您可以避免使用浮点(通常是最佳选择)或依赖软件实现,该实现将成为 C 库的一部分。
在某些控制器系列中,例如 ARM,浮点硬件存在于该系列的某些型号中,但不存在于其他型号中,因此这些系列的 gcc 支持这两种硬件。您的问题似乎是您混淆了这两个选项。
The computation may be done either by floating-point hardware or in software based on integer arithmetic.
Doing it in hardware is much faster, but many microcontrollers don't have floating-point hardware. In that case you may either avoid using floating point (usually the best option) or rely on an implementation in software, which will be part of the C library.
In some families of controllers, for example ARM, the floating-point hardware is present in some models of the family but not in others, so gcc for these families supports both. Your problem seems to be that you mixed up the two options.
可能的情况是,软浮点将数据单独保留在 fpu 中,而硬浮点则需要在进程激活时将 fpu 寄存器推出到缓存的开销。这就是为什么 FPU 通常在编译时对内核禁用的原因,不要在每次有人进行内核调用时浪费周期将其推入和推出内存。
It may be the case that softfloats leave the data in the fpu alone, whilst hardfloats require the overhead of pushing the fpu registers out to cache when the process becomes active. This is why FPU is normally disabled for the kernel at compile time, don't waste cycles pushing it in and out of memory every time someone makes a kernel call.