如何决定何时使用定点算法而不是浮点数?

问题描述

如何决定何时使用定点算法而不是浮点数?

我读过,当处理器中没有浮点单元时使用定点。当没有 FPU 时,是否意味着不支持 'float' 数据类型?

解决方法

  • 如果没有 FPU 固定点会更快、更确定
  • 如果您没有 FPU,不动点在很多情况下会更小 - 当然对于简单的算术而言。
  • 如果您需要您的代码在有或没有 FPU 的情况下跨不同平台或工具链生成位相同的结果,那么定点是必要的。
  • 例如,如果您需要进行需要三角函数或对数函数的复杂数学运算,浮点数是阻力最小的路径,但绝不是唯一的选择 - 但您需要开发或找到一个库(请参阅下面的链接) -有很多方法可以做到这一点。
  • 如果您需要宽动态范围的浮点则更简单。例如,小于 1 的数字的平方根是一个较小的数字 - 对于定点,您可能会用完位并以零结束,对于浮点,只需移动该点以增加分辨率,但会牺牲范围。
  • 如果您有 FPU 并且正在使用 RTOS 并且不希望在上下文切换上堆叠 FPU 寄存器的开销(或者如果它不受支持),则定点可避免这种需要,并避免在您忘记时出错为每个需要它的任务启用该选项。

Generally if your operation is trivial,use fixed point or at least an integer representation by selecting your units appropriately.例如,将电压值以整数毫伏(或什至以 ADC 量子数)而不是以伏为单位存储可以避免不必要的浮点。

如果您在做复杂的数学运算并且有 FPU,浮点数是更简单、最不容易出错的解决方案。即使没有和 FPU,如果您的解决方案满足时序和代码大小约束,浮点可能仍然更简单,但可能会限制您在更多约束执行环境中使用相同代码的能力。因此,需要在各种平台上重用固定点可能更可取。

无论您做什么,在大多数情况下都避免使用“十进制定点”,尽可能使用二进制定点表示(Q 表示),例如 10Q6 有 10 个整数位和 6 个小数位。这样做的原因是乘法/除法之后的重新缩放是移位操作,而不是潜在的昂贵的乘法/除法运算,并且不会失去重新缩放的精度。

一些有用的参考:

,

如果没有可用的 FPU,编译器通常可以模拟浮点运算。但这效率低下,因为它需要很多周期。

如果您受到资源限制(您经常处于没有 FPU 的环境中),那么您可以选择使用常规整数运算的定点算法。

胡说八道:当我使用 FP 时,我错过了编译器 (C/C++) 的支持,无法将变量标记为定点(具有特定数量的小数位)。

,

如果您有符合标准的编译器,那么 floatdouble 始终可用并正常工作。如果没有 FPU,则计算在软件中完成(称为 soft-FPU 或 FPU 仿真)。这会更慢并且使用更多内存。

何时使用不动点主要是见仁见智,但何时使用它是当变量具有很大的动态范围时,即:当一个数字可能非常大但你仍然如果它很小,就需要它是准确的。

例如:显示汽车的速度。我需要知道 68 英里每小时和 70 英里每小时之间的区别,但我不在乎 0.68 英里每小时和 0.70 英里每小时之间的区别。这具有低动态范围(我关心),因此如果其他原因表明我可能想要,我可以使用定点。或者,测量样品的放射性:我关心每秒 100 和 90 计数之间的差异,我仍然关心每秒 1 和 0.9 计数之间的差异。这种高动态范围意味着不适合固定点。

,

如何决定何时使用定点算法而不是浮点数?

这取决于可能会或不会影响您的许多因素,包括...

优点:

  • 定点需要的电路更少,因此在更小、更简单的设备上可能更实用。
  • 定点使用更少的能量,因此可能更实用
    • 在电池供电的设备上,
    • 在密集计算会产生大量能源费用的应用中,或
    • 散热有问题的地方。
  • 定点实际上只是整数运算,因此运算是无损的。
  • 定点允许您在您选择的数字基数中precisely express real numbers,例如值 1/10 或 1/3。
  • 浮点运算可能会表现出与以下内容相关的不一致行为
    • 全局舍入模式,
    • 优化,
    • 结合性,
    • 实现定义的行为,以及
    • FPU 硬件的变化。

缺点:

  • 虽然无损,但定点算法容易出现超出范围的错误,例如溢出。 (图书馆和 UB 消毒剂可以帮助避免/检测错误。)
  • 在模运算符 (%) 的帮助下实现无损除法,这通常更难使用。
  • 大多数语言都不太支持定点算术:您必须使用整数手动执行容易出错的计算,或者找到可以帮助您的库。
  • 浮点格式在跨架构中往往更加一致,这与宽度和字节序不同的整数不同。
  • 浮点类型不仅具有动态小数点,而且会自动保持该点的最佳位置,从而避免麻烦和精度损失。

确实,浮点数是一种易于使用且得到广泛支持的用于表示实数的解决方案。如果浮点数适合您,请在探索替代方案之前仔细考虑。

例外:专业人士使定点成为自然选择的应用程序是货币。面额的无损表示在金融中尤为重要。 (example)

我读过,当处理器中没有浮点单元时使用定点。

确实如此。没有FPU,浮点运算很慢!

当没有 FPU 时,是否意味着不支持 'float' 数据类型?

不,这不一定遵循,尽管实现可能会有所不同。 (IIRC,旧版本的 GCC 有一个标志来启用浮点支持。)完全可以使用

执行浮点运算
  • 编译器,通过生成等效的 ALU 指令,或
  • 系统,通过在遇到 FPU 指令时中断进程并遵循软件例程。

这两者都慢得多,所以在这样的硬件上使用定点算法可能会成为一个实用的选择。最好将定点视为一种优化技术,一旦发现性能缺陷就可以使用。