硬浮点数和软浮点数之间有什么区别?

Eva*_*ske 95 c linux floating-point arm libc

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

nmi*_*els 96

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

  • "看到两者在同一目标架构中使用是很奇怪的"这对于库在精度关键部件中是机器无关的和精确的(软浮动)以及在小偏差的部分中快速(硬浮动)是有意义的没关系 (3认同)

nin*_*alj 31

浮点运算有三种方法:

  • 如果CPU具有FPU,请使用浮动指令.(快速)
  • 让编译器将浮点运算转换为整数运算.(慢)
  • 使用浮动指令和没有FPU的CPU.您的CPU将生成异常(保留指令,未实现指令或类似指令),如果您的操作系统内核包含浮点仿真器,它将模拟这些指令(最慢).


art*_*ise 20

严格地说,所有这些答案对我来说都是错误的.

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

Debian VFP维基有三个选项的信息-mfloat-abi,

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

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

Linux内核可以支持VFP指令的仿真.显然,你最好-mfpu=none为这种情况编译并让编译直接生成代码,而不是依赖于任何Linux内核仿真.但是,我不认为OP的错误实际上与此问题有关.它是独立的,也必须与之一起处理-mfloat-abi.

与ArmV7 CPU的Armv5共享库与此相反; 在libc中是很难浮动,但应用程序只是.它有一些解决问题的方法,但使用正确的选项重新编译总是最简单的.

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

  • 这是正确的答案。浮点数的调用转换需要在代码和 libc 之间匹配。如果您从不调用任何浮点 libc 函数,它可能仍然可以在不匹配的情况下工作。 (2认同)
  • +1,因为这似乎是最正确的答案。我还要补充一点,无论您是否有 FPU。您还可以拥有一个仅支持可以在 C 程序中表达的函数子集的 FPU,例如“1.0L / 2.0L”在单精度 FPU 上是不可能的,但“1.0f / 2.0f”将是。通常情况下,编译器运行时(例如 libgcc)将提供缺失的长双除法的“软”版本。然而,单精度指令将是“软”包装的硬件指令。 (2认同)

Dig*_*ata 12

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

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


sta*_*lue 7

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

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

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