问题描述
如何决定何时使用定点算法而不是浮点数?
我读过,当处理器中没有浮点单元时使用定点。当没有 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 个小数位。这样做的原因是乘法/除法之后的重新缩放是移位操作,而不是潜在的昂贵的乘法/除法运算,并且不会失去重新缩放的精度。
一些有用的参考:
-
https://www.drdobbs.com/cpp/optimizing-math-intensive-applications-w/207000448
-
http://jet.ro/files/The_neglected_art_of_Fixed_Point_arithmetic_20060913.pdf
如果没有可用的 FPU,编译器通常可以模拟浮点运算。但这效率低下,因为它需要很多周期。
如果您受到资源限制(您经常处于没有 FPU 的环境中),那么您可以选择使用常规整数运算的定点算法。
胡说八道:当我使用 FP 时,我错过了编译器 (C/C++) 的支持,无法将变量标记为定点(具有特定数量的小数位)。
,如果您有符合标准的编译器,那么 float
和 double
始终可用并正常工作。如果没有 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 指令时中断进程并遵循软件例程。
这两者都慢得多,所以在这样的硬件上使用定点算法可能会成为一个实用的选择。最好将定点视为一种优化技术,一旦发现性能缺陷就可以使用。