【发布时间】:2011-03-20 06:51:35
【问题描述】:
当我使用我的交叉工具链编译 C 代码时,链接器会打印出警告页面,说明我的可执行文件使用了硬浮点数,但我的 libc 使用了软浮点数。有什么区别?
【问题讨论】:
-
如果是ARM架构,请将其放入标签中:-)
-
@Nils Pipenbrinck:MIPS 芯片也有这个问题
标签: c linux floating-point arm libc
当我使用我的交叉工具链编译 C 代码时,链接器会打印出警告页面,说明我的可执行文件使用了硬浮点数,但我的 libc 使用了软浮点数。有什么区别?
【问题讨论】:
标签: c linux floating-point arm libc
严格来说,所有这些答案在我看来都是错误的。
当我使用我的交叉工具链编译 C 代码时,链接器会打印出警告页面,说明我的可执行文件使用了硬浮点数,但我的 libc 使用了软浮点数。有什么区别?
Debian VFP wiki 有关于-mfloat-abi 三个选项的信息,
soft - 这是纯软件softfp - 这支持硬件 FPU,但 ABI 是软兼容的。hard - ABI 使用 float 或 VFP 寄存器。链接器(加载器)错误是因为您有一个共享库,该库将在整数寄存器中传递浮点值。您仍然可以使用-mfpu=vfp 等编译您的代码,但您应该使用-mfloat-abi=softfp,以便如果 libc 需要浮点数,它会以库可以理解的方式传递。
Linux 内核可以支持 VFP 指令的仿真。显然,对于这种情况,您最好使用 -mfpu=none 进行编译,并让编译器直接生成代码,而不是依赖任何 Linux 内核仿真。但是,我不相信 OP 的错误实际上与这个问题有关。它是单独的,也必须与-mfloat-abi 一起处理。
Armv5 shared library with ArmV7 CPU 与此相反; libc 是硬浮动的,但应用程序只是 soft。它有一些解决问题的方法,但使用正确的选项重新编译总是最简单的。
另一个问题是 Linux 内核必须支持 VFP 任务(或任何存在的 ARM 浮点)才能在上下文切换上保存/恢复寄存器。
【讨论】:
1.0L / 2.0L 在单精度 FPU 上是不可能的,但 1.0f / 2.0f 可以。通常情况下,编译器运行时(例如 libgcc)会提供缺失的长双除法的“软”版本。但是,单精度指令将是“软”包装的硬件指令。
计算可以通过浮点硬件或基于整数运算的软件来完成。
在硬件中执行此操作要快得多,但许多微控制器没有浮点硬件。在这种情况下,您可以避免使用浮点(通常是最佳选择)或依赖软件中的实现,这将成为 C 库的一部分。
在某些控制器系列中,例如 ARM,浮点硬件存在于该系列的某些型号中,但不存在于其他型号中,因此这些系列的 gcc 支持两者。您的问题似乎是您混淆了这两个选项。
【讨论】:
浮点运算的三种方式:
【讨论】:
硬浮点使用片上浮点单元。软浮动在软件中模拟一个。区别在于速度。看到两者都用在同一个目标架构上很奇怪,因为芯片要么有一个 FPU,要么没有。您可以使用 -msoft-float 在 GCC 中启用软浮点。如果您使用它,您可能需要重新编译您的 libc 以使用硬件浮点。
【讨论】:
听起来您的 libc 是为软件浮点运算而构建的,而您的 exe 是在假设硬件支持浮点的情况下编译的。在短期内,您可以强制软浮点作为编译器标志。 (如果你使用 gcc,我认为是 -msoft-float)
从长远来看,如果您的目标处理器具有对浮点运算的硬件支持,您通常会希望构建或找到启用硬件浮点以提高速度的跨工具链。一些处理器系列有一些型号变体,有的有硬件支持,有的没有硬件支持。因此,例如,仅说您的处理器是 ARM 不足以知道您是否支持硬件浮点。
【讨论】: