定點化

談到這個話題,有必要先介紹下“浮點數”和“定點數”這兩個名詞的概念。

1.25 + (-2.75) = ?                                                                (1)
上面這個算式我們心算就能輕鬆得出結果,同樣的算式,交給單片機來完成,它要大致分解爲下面三個計算步驟:
1)加載操作數(也就是1.25和2.75);
2)做加法運算;
3)返回結果。

對於真實的單片機世界而言,它只有0和1組成的bits。整數好辦,直接將十進制數轉化爲二進制數形式進行運算就好,但面對小數,該如何來表示數中的小數點呢?這便引出了數的浮點和定點表示。

對於一個“有符號數”而言,它的浮點表示由三部分組成,如圖1,一個32位的浮點數示例:

圖1 32bit有符號數浮點組成示例

• 符號位:0表示正數,1表示負數。
• 指數部分:類似於科學技術法中的M*10^N中的N,只不過這裏是以2爲底數而不是10。
• 基數部分:浮點數具體數值的實際表示,類似於科學計數法中的M。
詳細瞭解數的浮點表示細節,可查看參考資料【1】。

對於同樣一個數,它的定點表示也由三部分組成:

圖2 32bit有符號數浮點組成示例

• 符號位:0表示正數,1表示負數。
• 整數部分:小數點左邊的數。
• 小數部分:小數點右邊的數。

但計算機它並不直接區分定點數的整數和小數部分,需要程序設計者進行“人爲”的定標(這裏的“人爲”實際上不靠任何真實操作,你可以理解爲靠意念)。

對於不同的數,定標可以不一樣,通常用Q來表示定標值,如圖2的定標爲Q23。同樣,我們也可以把一個數定標爲Q22、Q12等等。


“浮點”與“定點”之於單片機
根據自身硬件的不同,有些單片機支持浮點數運算,有些則只支持定點數運算。市面上大部分的單片機都是定點單片機,只有一些對數據處理要求比較高的單片機纔會集成浮點處理單元。

一般而言:
浮點單片機便於浮點編程,省去了人爲定標的麻煩,而且同樣的位數,浮點可以表示更大範圍內的數。但浮點單片機硬件複雜、功耗更大,價格也會相應高些;

定點單片機的定點運算處理效率比浮點運算要高,但因爲需要人爲地給各個數據定標,也帶來了程序設計中的“定點化”問題。

定點化編程
在工程實踐中,開發信號處理算法一般遵循下面的流程:


圖3 工程中算法開發流程

程序定點化之後,由於定點數據的精度限制,會存在定點誤差,其運算結果可能會與Matlab的仿真結果產生一定的偏差。選擇合適的定標值,以確保運算結果在符合應用要求的範圍之內,這是定點化過程中最重要也是最難的一個問題。

據AccelChip 公司所做的一次調查顯示,53% 的回答者認爲浮點定點轉換是在FPGA上實現算法時最困難的地方。而實際上我認爲,定點化充其量只是過程顯得繁瑣一些,其中的規律還是比較簡單的。下面還是以最開始的那個算式爲例,來解釋定點化過程中會面臨的一些問題。

1. 選取合適的定標值(加載操作數)
定標的大小,影響着整數部分和小數部分的位數,定標的過程其實是在操作數動態範圍和精度之間做權衡的過程。

設一個變量可能出現的最大絕對值爲|max|,n爲正整數,滿足2^(n-1) < |max| < 2^n,則定標Q按如下規則選取最合適:

Q = 有效數據位 – n

對於32位的有符號數,數據有效位=31。如|max| = 2.75,選Q = 31 – 2 =29是最合適的。

2. 定點數之間的運算
兩個定點數進行運算,它們的定標可能相同也可能不同,那該遵循怎樣的規則來進行加減乘除等基本運算呢?

網上有些資料通過分別舉加、減、乘、除實際運算的例子來說明這一問題,雖然很詳細,但還是不夠直觀。

來看一看,平時我們用十進制做兩個數的加減和乘除是怎麼弄的。

加減法:先對位,後加減;
乘除法:先乘除,後取小數點。

而定點數之間的加減乘除,撇開符號位不談,其過程是一樣一樣的:

加減法:先對標,後加減;
乘除法:先乘除,後定標。

大家可以仔細體會下這裏的意思,然後再找具體的例子對照感受下,看是不是覺得簡單多了呢。

3. 結果重新定標(返回結果)
兩個定點數運算完成之後,所得結果的定標、動態範圍、精度要求等都可能發生了變化,因此可能需要進行重新定標。

比如Q15*Q15 -> Q30,但我們依然希望得到一個Q15的數怎麼辦?其實只需做一個簡單的右移15位操作就好,其它情況同理。

另一些探討
• 浮點芯片均能支持定點運算,只是在一般定點芯片的基礎上添加了額外的浮點處理硬件單元和指令,使得芯片得以支持快速的浮點運算。

• 定點芯片支持浮點運算嗎?答案也是肯定的!我記得在本科的時候用STM32進行編程時,當時還沒有對定點編程的概念,直接在程序中就用float來表示小數並進行運算了,結果也是正確的,但它確實是定點芯片呀?真實的情況是,很多編譯器都爲定點芯片提供了相應的浮點處理庫,通過軟件的方式同樣來支持float型變量的操作。但這樣做會使計算變得很低效,在實時性要求高的情況下,定點化依然是必不可少的一環。

參考文獻/資料
【1】你應該知道的浮點數基礎知識--盧鈞軼的博客
【2】DSP芯片的定點運算 -- 新浪愛問
【3】DSP編程技巧之22---詳解浮點運算的定點編程

·END·
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章