111

当我用我的交叉工具链编译 C 代码时,链接器会打印出警告页面,说我的可执行文件使用硬浮点,但我的 libc 使用软浮点。有什么不同?

4

5 回答 5

109

硬浮点使用片上浮点单元。软浮动在软件中模拟一个。区别在于速度。看到两者都用在同一个目标架构上很奇怪,因为芯片要么有一个 FPU,要么没有。您可以使用 -msoft-float 在 GCC 中启用软浮点。如果您使用它,您可能需要重新编译您的 libc 以使用硬件浮点。

于 2010-07-23T19:21:40.200 回答
34

浮点运算的三种方法:

  • 如果您的 CPU 有 FPU,请使用浮点指令。(快速地)
  • 让您的编译器将浮点运算转换为整数运算。(减缓)
  • 使用浮点指令和没有 FPU 的 CPU。您的 CPU 将生成异常(保留指令、未实现指令或类似指令),如果您的操作系统内核包含浮点模拟器,它将模拟这些指令(最慢)。
于 2010-07-23T19:22:43.150 回答
31

严格来说,所有这些答案在我看来都是错误的。

当我用我的交叉工具链编译 C 代码时,链接器会打印出警告页面,说我的可执行文件使用硬浮点,但我的 libc 使用软浮点。有什么不同?

Debian VFP wiki有关于三个选项的信息-mfloat-abi

  • soft- 这是纯软件
  • softfp- 这支持硬件 FPU,但ABI是软兼容的。
  • hard- ABI 使用浮点VFP寄存器。

链接器(加载器)错误是因为您有一个共享库,它将在整数寄存器中传递浮点值。您仍然可以使用 a-mfpu=vfp等编译您的代码,但您应该使用-mfloat-abi=softfp这样,如果libc需要一个浮点数,它会以库可以理解的方式传递。

Linux 内核可以支持 VFP 指令的仿真。显然,对于这种情况,您最好编译-mfpu=none并让编译器直接生成代码,而不是依赖任何 Linux 内核仿真。但是,我不相信 OP 的错误实际上与这个问题有关。它是单独的,也必须与-mfloat-abi.

带有 ArmV7 CPU的 Armv5 共享库与此相反;libc是硬浮动的,但应用程序只是的。它有一些方法可以解决这个问题,但使用正确的选项重新编译总是最简单的。

另一个问题是 Linux 内核必须支持 VFP 任务(或任何存在的 ARM 浮点)才能在上下文切换上保存/恢复寄存器。

于 2015-04-17T17:25:47.133 回答
13

听起来您的 libc 是为软件浮点操作而构建的,而您的 exe 是在假设硬件支持浮点的情况下编译的。在短期内,您可以强制将软浮点数作为编译器标志。(如果你使用 gcc,我认为是 -msoft-float)

从长远来看,如果您的目标处理器具有对浮点​​运算的硬件支持,您通常需要构建或找到一个启用硬件浮点以提高速度的交叉工具链。一些处理器系列有一些型号变体,有的有硬件支持,有的没有硬件支持。因此,例如,仅说您的处理器是 ARM 不足以知道您是否支持硬件浮点。

于 2010-07-23T19:21:32.697 回答
9

计算可以通过浮点硬件或基于整数运算的软件来完成。

在硬件中执行此操作要快得多,但许多微控制器没有浮点硬件。在这种情况下,您可以避免使用浮点(通常是最佳选择)或依赖软件中的实现,这将成为 C 库的一部分。

在某些控制器系列中,例如 ARM,浮点硬件存在于该系列的某些型号中,但不存在于其他型号中,因此这些系列的 gcc 支持两者。您的问题似乎是您混淆了这两个选项。

于 2010-07-23T19:26:23.673 回答