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

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

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

有三种方法可以做浮点运算:

  • 如果CPU有FPU,请使用浮点指令。 (快速)
  • 让您的编译器将浮点运算转换为整数运算。 (慢)
  • 使用浮点指令和一个没有FPU的CPU。 你的CPU会产生一个exception(保留指令,未执行指令或类似的),如果你的操作系统内核包含一个浮点模拟器,它将模拟这些指令(最慢)。

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

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

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

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

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

Linux内核可以支持仿真VFP指令。 显然,你最好用-mfpu=none进行编译,直接编译生成代码,而不是依靠任何Linux内核模拟。 但是,我不相信OP的错误实际上与这个问题有关。 它是分开的,也必须与-mfloat-abi一起处理。

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

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

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

长期来看,如果您的目标处理器具有硬件支持浮点操作,您通常会想要build立或find一个交叉工具链,启用硬件浮点速度。 某些处理器系列具有一些型号变体,有些则没有硬件支持。 所以,举个例子,只是说你的处理器是ARM​​就不足以知道你是否有硬件浮点支持。

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

在硬件上做这件事要快得多,但许多微控制器没有浮点硬件。 在这种情况下,您可以避免使用浮点(通常是最好的select),也可以依靠软件中的实现,这将成为C库的一部分。

在一些控制器系列中,例如ARM,浮点硬件出现在一些家族的模型中,但在其他的模型中则不存在,所以这些家族的gcc都支持这两种。 你的问题似乎是你混淆了两个选项。