“避免使用浮点”的经验法则是否适用于带有浮点单元 (FPU) 的微控制器?

电器工程 微控制器 C rtos 浮点
2022-01-02 14:04:54

根据经验,我尽量避免在我的嵌入式系统代码库中使用浮点。

浮点变量是:

  • 计算密集型
  • 非原子性(可能导致 RTOS 应用程序出现问题或出现中断)
  • 它们的精度会导致不明显的行为(浮点比较问题)。

但是带有浮点单元的微控制器(如 STM32F4)呢?

这些担忧仍然适用吗?你还会建议不要使用浮点吗?

4个回答

您应该记住,这些微控制器上的 FPU 通常只是单精度 FPU。单精度浮点只有 24 位尾数(带有隐藏的 MSB),因此在某些情况下,您可以从 32 位整数中获得更好的精度。

我已经使用定点算法完成了工作,对于数据具有有限动态范围的情况,您可以使用 32 位定点实现与单精度浮点相同的精度,并且执行时间大约提高一个数量级. 我还看到编译器为 FPU 带来了相当多的库开销。

如果您购买带有硬件 FPU 的处理器,那么您就不必担心精度*、可重入行为等。继续使用它们!

不过有几点想法:

  • 您可能会认为处理器可以在不使用时关闭(大型)FPU,因此请检查运行您的 FP 例程是否比在软件中执行它节省了您的功率(如果您关心的话)。

  • 根据实现的不同,FPU 也可能有不同的内核寄存器——有时编译器可以巧妙地利用这些寄存器。

  • 不要将 FPU 用作不良固件设计的拐杖。例如,你可以用定点做同样的事情,而用普通的核心来代替吗?

(* FPU 应符合给定的标准实现,因此请注意由此产生的任何限制。)

一些担忧仍然存在。

  • 浮点运算本质上比整数计算密集。但是对于浮点单元,您可能不会再注意到这一点,可能会增加一些额外的 cpu 周期或更多的功耗。
  • 操作是原子的,所以这种担忧消失了。
  • 精度/舍入/比较问题仍然存在,与软件计算中的数量完全相同。

尤其是后者可能会导致非常讨厌的问题,并迫使您编写非直观的代码,例如总是与范围进行比较,从不测试与固定值的相等性。

请记住,单精度浮点数只有 23 位分辨率,因此您可能需要用双精度浮点数替换 32 位整数。

如果你有 FPU,计算通常很好,而且权衡很容易理解。

但请注意输出。如果你有类似 C 库之类的东西,你会惊讶于printf("%0.6g", x); 我见过的malloc()内部使用的库所固有的复杂性printf(),而这不是你在微控制器中想要的那种东西。