嵌入式系统/浮点运算单元
浮点数是....
与所有信息一样,浮点数用位表示。
早期的计算机使用各种浮点格式。每个格式都需要略微不同的子程序来进行加、减和其他运算。
由于一些计算机应用程序大量使用浮点数,英特尔对一种特定格式进行了标准化,并设计了浮点硬件,其计算速度远远快于软件子程序。80186 配备了一个名为 80187 的浮点协处理器。80187 是一个浮点数学单元,它处理浮点算术函数。在更新的处理器中,浮点单元 (FPU) 已直接集成到微处理器中。
然而,许多小型嵌入式系统没有 FPU(内部或外部)。因此,它们在必要时以旧的方式处理浮点数。它们使用软件子程序,通常称为“浮点仿真库”。
然而,在许多嵌入式系统中,浮点数并不是必需的。许多嵌入式系统程序员试图从程序中消除浮点数,[1] 而是使用 定点运算。这些程序占用更少的空间(定点子程序库远小于浮点库,尤其是在系统中只包含一两个例程时)。在没有浮点单元的微处理器上,定点版本的程序通常比浮点版本运行速度更快。但是,这些嵌入式系统程序员必须准确计算特定应用程序需要多少精度,并确保他们的定点例程至少保持这种精度。
(在这个维基教科书中是否有更好的位置来讨论这个话题?它甚至没有提到浮点数。)
低端嵌入式微控制器通常甚至没有整数乘法指令集。[2] 所以在低端 CPU 上,你必须使用从更简单的步骤综合基本的数学运算符(乘法、除法、平方根等)的例程。实际上所有微处理器都有这样的例程,由其制造商或其他用户发布在互联网上 ("Multiplication and Division Made Easy" by Robert Ashby, "Novel Methods of Integer Multiplication and Division", "efficient bit twiddling methods",等等)。
遵循被称为 "Make It Work Make It Right Make It Fast" 和 "Make It Work Make It Small Make It Fast" 的建议,许多人选择一个或两个足够处理程序中处理的最大和最精确的数据类型的数字分辨率,并对所有内容使用该分辨率。对于台式机,32 位整数和 64 位“双精度浮点数”通常绰绰有余。对于嵌入式系统,24 位整数和 24 位“定点数”通常绰绰有余。如果软件适合微控制器,并且速度足够快,那么试图进一步“优化”它就是浪费宝贵的人力时间。
唉,有时软件不适合微控制器。
- 如果你内存不足,有时你只需要 2 字节、1 字节、4 位或 1 位来存储一个特定的变量。
- 如果你时间不足,有时你可以添加低精度数学例程,它们可以快速计算内部循环所需的结果,即使代码的其他部分可能需要更高精度的数学例程。
- 如果你 ROM 不足,有时你可以用时间来换取 ROM 空间。与其使用一组组的数学例程,每个例程都针对略微不同的宽度进行定制,不如使用一组可以处理最大可能宽度的数学例程。如果你有一些变量小于该宽度(以节省内存),那么你通常会将变量符号扩展到一个完整的寄存器或全局缓冲区,在那里进行全宽度计算,然后截断并将结果存储到较小的尺寸。
一些嵌入式微处理器可能有一个外部单元用于执行浮点运算 (FPU),但大多数低端嵌入式系统没有 FPU。大多数 C 编译器将提供软件浮点支持,但这比硬件 FPU 慢得多。因此,许多嵌入式项目强制其程序员遵循无浮点的规则。[3][4][5][6][7] 这与 PC 形成鲜明对比,在 PC 中,FPU 已集成到所有主要微处理器中,程序员理所当然地认为浮点数计算速度很快。许多 DSP 也没有 FPU,需要定点运算才能获得可接受的性能。[8]
一种常用的避免使用浮点数的技术是更改存储在变量中的数据的幅度,这样你就可以利用定点数学。例如,如果你要添加英寸,并且只需要精确到百分之一英寸,你可以将数据存储为百分之一英寸而不是英寸。这样你就可以使用正常的定点算术。只要你提前知道要添加的数据的幅度,并知道你需要存储数据的精度,这种技术就可以奏效。
人们使用许多技巧和技术来加速傅里叶变换计算。快速傅里叶变换 (FFT) 是最大的加速,但除此之外还有其他一些技巧,每个技巧都可以带来两倍的改进。[9][10]
许多人使用定点运算来进行 FFT。[11][12][13][14][15][16]
快速哈特利变换是一种替代方案,它比 FFT 需要更少的资源。[17]
DTMF 解码器通常使用 Goertzel 算法,因为当只需要分析几个频率时,它比 FFT 算法快得多。
... 这里还有更多技巧和提示 ...
- ↑ 避免在 iPhone 上进行浮点运算
- ↑ Robert Ashby。 "简化公式"。2006 年。引用:"我们仍然需要找到方法来简化复杂的问题,然后才能将它们放入我们 50 美分的微型处理器中。在 1.50 美元以下的硬件乘法很少见…… 这让我们将目标定为将所有内容简化为加法、减法、位移和比较。"
- ↑ "停止使用浮点数!"。引用:"请学习使用定点算术。"
- ↑ "编写高效的 JavaScript (HTML)" 引用:"尽可能使用整数算术。"
- ↑ Erich Styger。 "为 S08 项目添加/删除浮点格式"。引用:"通常我在我的项目中 *不* 使用浮点数。"
- ↑ "避免浮点数学"。
- ↑ "在哈希表实现中避免浮点数。"
- ↑ Boris Lerner。 "定点与浮点:一个令人惊讶的艰难选择"。
- ↑ Douglas L. Jones。 "时间抽取 (DIT) 基 2 FFT"。OpenStax-CNX。2006 年 9 月 15 日。
- ↑ Douglas L. Jones。 "高效的 FFT 算法和编程技巧"。OpenStax-CNX。2007 年 2 月 24 日。
- ↑
- "在低功耗 MCU 上开发 FFT 应用程序" 作者:Paul Holden 2005
- ↑
- ↑
- ↑
- ↑
- EE-18:为 ADSP-21xx 选择和使用 FFT (定点 DSP)
- ↑
- Kiss FFT 库,可以使用定点或浮点数据类型。
- ↑ Simon Inns。 "用于 AVR 微控制器的快速 Hartley 变换库"。
- 浮点/定点数字
- AN660:Microchip PICmicro 的浮点例程
- AN617:Microchip PICmicro 的定点例程
- "算法 - ArcTan 尽可能快 - AN2341" Cypress PSoC 的定点例程
- "浮点近似" 由 Ganssle Group 收集,提供代码和测试用例。(假设您已经拥有浮点加、减、乘和除,并给出三角函数、根、对数和指数的公式…… 各种公式,在精度、速度和范围之间具有不同的权衡)。
- AVRfix: 用于 s15.16、s7.24 和 s7.8 格式定点计算的库,完全用 ANSI C 编写,用于嵌入式软件(主要针对 Atmel AVR 平台)。
- Microchip AN575:符合 IEEE 754 标准的浮点例程 "以修改后的 IEEE 754 32 位格式,以及 24 位简化格式的版本。"…… "浮点数到整数转换、整数到浮点数转换、规范化、加/减、乘、除。"
- PICFLOAT 用于中档 PICmicro 处理器的开源 IEEE 32 位(“单精度”)浮点库。包含大多数常见的 C 浮点数学函数。完整的库加上测试代码都适合 2 KB 内。
- "定点" SourceForge 上的库。