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


Answers:


100

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


3
“很奇怪的是,它们都在相同的目标体系结构上使用”,对于在精度要求严格的部分中库是独立于机器且位精确(软浮点)而在偏差很小的部分中是快速(硬浮点)来说,这可能是有意义的没关系
PhilLab'5

它发生在32位ARM上。
亚伦·弗兰克

31

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

  • 如果您的CPU有FPU,请使用浮点指令。(快速)
  • 让您的编译器将浮点运算转换为整数运算。(慢)
  • 使用浮点指令和没有FPU的CPU。您的CPU将生成一个异常(保留指令,未实现指令或类似指令),并且如果您的OS内核包含浮点模拟器,它将模拟这些指令(最慢)。

23

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

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

Debian VFP Wiki包含有关以下三个选项的信息-mfloat-abi

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

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

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

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

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


1
现代的GCC(〜4.8 +)版本支持'multi-lib',其中具有硬浮点和软浮点库。早期版本要求您使用特定版本构建编译器。与“多库” gcc发行版链接时,有时需要正确的库路径,因为库有多个版本(需要较长的时间来构建编译器)。目录名称可能是“ hf”,“ hardf”,“ libhf”或“ hard-float”,但它们通常位于常规的“ soft”目录或附近位置。
无声的噪音

这是正确的答案。浮点数的调用转换需要在代码和libc之间匹配。如果您从不调用任何浮点libc函数,则它可能仍会不匹配。
Tor Klingberg

13

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

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


8

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

用硬件完成它要快得多,但是许多微控制器没有浮点硬件。在这种情况下,您可能会避免使用浮点数(通常是最佳选择),或者依赖于软件的实现,该实现将成为C库的一部分。

在某些控制器系列中,例如ARM,浮点硬件存在于该系列的某些型号中,而在其他型号中则没有,因此这些系列的gcc支持这两种型号。您的问题似乎是您混淆了这两种选择。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.