嵌入式系統/浮點運算單元
浮點數是....
與所有資訊一樣,浮點數用位表示。
早期的計算機使用各種浮點格式。每個格式都需要略微不同的子程式來進行加、減和其他運算。
由於一些計算機應用程式大量使用浮點數,英特爾對一種特定格式進行了標準化,並設計了浮點硬體,其計算速度遠遠快於軟體子程式。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 上的庫。