Embedded 如何决定何时使用定点运算而不是浮点运算?

Embedded 如何决定何时使用定点运算而不是浮点运算?,embedded,fixed-point,integer-arithmetic,Embedded,Fixed Point,Integer Arithmetic,如何决定何时使用定点运算而不是浮点运算 我读过,当处理器中没有浮点单元时,使用定点。当没有FPU时,这是否意味着不支持“浮点”数据类型?如果没有可用的FPU,编译器通常可以模拟浮点算术。但这是低效的,因为它需要很多周期 如果您受资源约束(通常在没有FPU的环境中),则可以选择使用常规整数运算的定点算法 漫无边际:当我使用FP时,我错过了编译器(C/C++)的支持,无法将变量标记为定点(具有特定数量的小数位数)。如果您有一个符合标准的编译器,那么float和double始终可用,并且工作正常。如果

如何决定何时使用定点运算而不是浮点运算


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

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

如果您受资源约束(通常在没有FPU的环境中),则可以选择使用常规整数运算的定点算法


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

如果您有一个符合标准的编译器,那么
float
double
始终可用,并且工作正常。如果没有FPU,则通过软件(称为软FPU或FPU仿真)进行计算。这是较慢的,并使用更多的内存

何时使用固定点主要取决于意见,但何时不使用固定点则取决于变量具有较大的动态范围,即:当一个数字可能非常大,但如果它非常小,您仍然需要它精确

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

  • 如果没有FPU,固定点将更快、更具确定性
  • 如果没有FPU,在许多情况下,固定点会更小——当然对于简单的算术来说
  • 如果您需要您的代码在不同的平台或工具链(有或没有FPU)上生成完全相同的结果,那么定点是必要的
  • 例如,如果您需要进行复杂的数学运算,需要使用trig或log函数,那么浮点运算是阻力最小的路径,但绝不是唯一的选择——但您需要开发或找到一个库(请参见下面的链接)——而且有很多方法做得很糟糕
  • 如果需要宽动态范围,则浮点更简单。例如,小于1的数字的平方根是一个较小的数字-对于定点,您可能会耗尽位并以零结束,对于浮点,只需移动点以增加分辨率,而牺牲范围
  • 如果您有一个FPU并且正在使用RTOS,并且不希望在上下文开关上堆叠FPU寄存器的开销(或者如果不支持),则定点可以避免这种需要,如果您忘记为每个需要它的任务启用该选项,则可以避免错误
通常,如果您的操作很简单,请通过适当选择单位来使用定点或至少整数表示。例如,将电压值存储在整数毫伏(甚至ADC量子)而不是伏特可以避免不必要的浮点

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

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

一些有用的参考资料:

如何决定何时使用定点运算而不是浮点运算

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

优点:

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

  • 虽然是无损的,但定点算法容易出现溢出等超出范围的错误。(库和UB消毒液有助于避免/检测错误。)
  • 无损除法是在模运算符(
    %
    )的帮助下实现的,这通常更难使用
  • 大多数语言都不支持定点运算:您必须手动使用整数执行容易出错的计算,或者找到一个库来帮助您
  • 浮点格式在不同的体系结构中往往更为一致,而整数的宽度和长度各不相同
  • 浮点类型不仅有一个动态的基数,而且自动保持该点的最佳位置,省去了麻烦和精度