優雅的設計CNN並行架構-軟硬協同之位寬設定(2)
前言:既然涉及到計算,那麼浮點數定點數的選擇和位寬的選擇是逃不開的。一般來說,定點數和低位寬的組合是低功耗和低資源消耗的,也就是硬體友好型的。
首先簡單的說明一下浮點數和定點數的區別。
1。 浮點數的表示
以float32為例,按照 IEEE 754標準的浮點數格式為:
其中s表示符號位,0為正1為負;M表示尾數;E表示階碼。在float32中,符號位佔1位,尾數佔23位,階碼佔8位。
這種指數形式的格式可以表示的範圍更大,但同時小數點是浮動的,分佈是不均勻的。與整數的均勻分佈相比,浮點數越靠近0分佈越密,表示的精度越高;越遠離0分佈越疏,表示的範圍越大,從下圖可以看的很清楚。
舉個栗子吧
s=1, M=4429709/8388608=0。52806, E=130
帶入上面的公式
對了,這個轉換的網站挺好用的
2. 定點數的表示
對於硬體來說,浮點定點中的小數點是看不見的,至於它表示多少,是邏輯層面的設定,需要實現設定好整數的位寬和小數的位寬。
再來舉個栗子吧
若整數位佔4位,小數位佔3位,則其最大精度為0。125,最大值為15。875,而這種分佈就是均勻分佈。
3. FPGA的實現
那麼回到主題,浮點數用的好好的為什麼要用定點數呢?
先放兩張16bit定點數和浮點數的乘法器的消耗DSP比較:
定點數實現消耗1個DSP48
浮點數實現消耗2個DSP48
節省資源的以獲取更大並行度的初衷使得我們趨向選擇定點數計算。另外也可以看出浮點數和定點數的轉換是一種對映,這種對映在vivado的ip中可以很輕鬆的找到。
4。 定點數的截斷和擴充
無論是乘法器還是加法器,在計算過程中都會涉及位寬擴充的問題,這樣在卷積網路重複計算的過程中會導致位寬越來越大。
乘法器
加法器
這時就需要對定點小數進行適當的位寬截斷來滿足計算過程中的位寬不變的需求,而同時不對計算結果造成影響。
首先是如何進行截斷和擴充,當然對於有符號的定點小數,都要保證符號位不變。
截斷:整數部分從次高位開始去掉若干位,小數部分從最低位開始去掉若干位。截斷可能會造成數值的改變。
擴充:當小數為非負數時:整數部分在次高位之前擴充若干個0,小數部分在最低位之後擴充若干個0。擴充不會造成數值的改變;當小數為負數時:整數部分在次高位之前擴充若干個1,小數部分在最低位之後擴充若干個0。擴充不會造成數值的改變。
然後是如何確定整數部分的位寬和小數部分的位寬。當然你可能都想要,但是你資源又不夠,因此最好的方法就是pc上的模擬。以模型計算過程中的最大值來確定整數部分的位寬,最後拿全部位寬減去整數位寬就得到了小數位寬。
over~~~