5.7 除法器的優化

計算機組成

5 乘法器和除法器

5.7 除法器的優化

屏幕快照 2018-07-09 11.25.51

咱們如今的這個除法器已經能夠正常的工做了。可是距離實用還有至關大的距離,必需要通過優化,不過除法的優化就比較複雜。所以,在這一節,咱們只是對它的優化方法和優化的方向作一個很是基本的探討。性能優化

屏幕快照 2018-07-09 11.26.00

這是咱們已經有了的這一版除法器,咱們不妨稱之爲初版的實現。在這個除法器當中,有一個64位的餘數寄存器;一個64位的除數寄存器;一個32位的商寄存器和一個64位的ALU。框架

屏幕快照 2018-07-09 11.26.09

那咱們首先來考慮面積方面的優化,咱們先來看看在哪些地方存在着浪費。性能

首先,咱們的除數是隻有32位的,而咱們的除數寄存器使用了64位的,實際只使用了其中的一半,這是第一個能夠優化的點。優化

第二,商寄存器在初始化的時候是空的,每執行完一輪會產生移位,從右向左逐位填滿。因此,這裏也存在着浪費的狀況。spa

第三,餘數寄存器初始時是滿的,也就是最開始的被除數。可是,在不斷進行和除數的減法以後這個餘數會變得愈來愈小,它有實際意義的位從左往右在逐漸地減小。因此,越日後,餘數寄存器當中浪費的位就會越多。blog

那咱們就嘗試從這三個方面進行面積上的優化。圖片

屏幕快照 2018-07-09 11.26.20

那咱們把通過面積優化的除法器稱爲第二版,咱們就來看一看第二版的除法器是什麼樣的。爲了方便對比,咱們把優化方案和原來結構的描述放在一塊兒。工作流

首先,原先有一個64位的除數寄存器,如今咱們將除數寄存器縮小爲32位,由於除數原本就是32位的,因此這樣除數寄存器就沒有了浪費的狀況。可是咱們要注意,除數寄存器是在整個運算過程當中一直要使用的,它的移位只是爲了和餘數寄存器進行對齊,以方便運算。因此,原先才準備了一個64位的寄存器,以便於除數在移位的過程當中也不會丟失。那如今將它縮小爲32位了,就不能再有移位的功能,不然其中有效位就會丟失了。所以,這個除數寄存器也就不用再支持移位功能。那麼在運算中須要將除數和餘數進行對齊的這項功能,就得放到別的地方來完成了。class

第二,咱們知道原來有一個32位的商寄存器,它一開始是空的,在運算的過程當中逐位填滿。那既然它一開始沒有用,因此咱們乾脆先取消這個寄存器,再看一看可不能夠在別的地方實現相似的功能。並行

第三,原來有一個64位的ALU。而咱們知道,實際參與運算的其中一個操做數是除數,另外一個操做數則是餘數寄存器當中和除數對應的一些位,實際上只有32位。因此,咱們就將這個64位的ALU縮小爲32位,也就是說只要讓其中有效位數參與運算。

那麼對於餘數寄存器,或者說一開始是被除數的這個寄存器,它在和除數進行減法運算時,最開始只有最高的32位參與運算,以後才逐次地往低位移動。因此,咱們先規定這個餘數寄存器只有高32位參與這個加減法運算,咱們也在這個餘數寄存器當中畫一條半透明的線做爲標記,而整個餘數寄存器仍然保留爲64位,其中的高32位被鏈接到ALU的一個輸入,而ALU的輸出也鏈接到了餘數寄存器的高32位。

可是,原來除數寄存器是帶有右移的功能,從而實現了餘數寄存器中參與運算的數逐漸向低位移動這樣一個狀況,那如今除數寄存器已經不能右移了。與之相對,餘數寄存器那就得支持一個左移的功能,並且咱們再去回顧除法的運算過程能夠發現,餘數或者說被除數的高位一旦退出了運算,就再也不會有機會從新參與運算了。因此,把餘數寄存器的高位向左移位,並將移出的位丟棄,是不會對運算的過程形成影響的。因此,咱們將餘數寄存器加上左移的功能。而實際上咱們發現,如今這個餘數寄存器不只支持左移,還支持右移的功能。爲何支持左移?剛纔我已經介紹了;而爲何支持右移呢?就留給你們本身來思考。

固然,何時進行移位須要由控制邏輯進行控制。因此,在餘數寄存器上也須要有相應的控制輸入。那如今咱們要注意的是,餘數寄存器的浪費問題仍然沒有解決。隨着運算的進行,每一輪餘數寄存器都會向左移位一次,它的右邊則會多空出一位來,並且空出的位會愈來愈多。那麼咱們回頭來看一看,其中咱們還須要一個32位的商寄存器,並且這個商在運算的一開始是不須要佔據任何空間的,只須要每一輪採用左移的方式,給它多分配一個比特就能夠了。那就正好是餘數寄存器如今所浪費的狀況,咱們就能夠很天然地將商寄存器合併到餘數寄存器當中。讓每一輪產生的商,從餘數寄存器的右端逐個移入。這樣當運算結束時,商就佔據了餘數寄存器的低32位,而餘數寄存器的高32位,則是最後真正的餘數。這樣再連上對應的控制邏輯以後,咱們就有了一個通過面積優化的除法器。

那麼在實現了面積優化以後,咱們就要考慮在性能上是否能夠進行優化。

屏幕快照 2018-07-09 11.26.30

想進行除法器的性能優化,咱們就要先來回顧乘法是如何進行優化的。其實如今的乘法器能夠作到很是好的優化,這和乘法運算自身的特色是分不開的。

咱們來看以前提到過的例子,仔細分析就能夠發現,雖然乘法和除法都要產生不少中間的結果,也都須要經過移位等操做進行對齊,再進行最後的運算。可是很大的不一樣在於,乘法的每個中間結果都是獨立的,每個中間結果,要麼和被乘數相等,要麼是0,並且它到底是哪種?只由乘數當中固定的一位決定,不受其它位的影響。因此,若是咱們人工進行乘法的計算,當咱們有了被乘數和乘數以後,能夠交給不少人來協做運算。每一個人只計算其中一箇中間結果,而後再由一些人將這些中間結果加起來,這樣就能夠經過並行的計算大幅度地提升性能。

屏幕快照 2018-07-09 11.26.40

而咱們來看除法的這個工做流程,中間有一個檢查餘數的工做,並且當餘數小於0時,還須要回退第一步的操做。這實際上就是由於除法的這些中間結果並非各個獨立的。那咱們可能會想到,乘法的那個流程圖當中,不也有一個要進行檢查的分支操做嗎?看上去和除法這個流程圖是很是類似的。那麼,不妨把乘法的這個流程圖找出來仔細地看一看。

屏幕快照 2018-07-09 11.26.50

的確。在開始的這個地方確實有一個檢查乘數寄存器的最低位的操做,而且根據檢查結果的不一樣會走向兩個不一樣的分支。可是,咱們仔細分析就會發現,這個分支其實是不存在的。由於當最低位爲1時,會執行將被乘數寄存器和乘積寄存器相加,這樣一個操做。那麼咱們不妨能夠理解爲,將被乘數寄存器的內容和乘數寄存器的最低位進行一個」與操做「,而後再和乘積寄存器相加,由於如今乘數寄存器的最低位是1,任何數和1進行」與操做「,結果仍是這個數自己,因此,這樣的改動並不會影響這裏的操做;而對於這一邊,當最低位爲0時,若是咱們也作一樣的操做,也就是將乘數寄存器的最低位和被乘數寄存器先進行」與操做「,而後再和乘積寄存器相加,由於任何數和0進行」與操做「,結果都是0,0再和乘積寄存器相加,那就至關於沒有執行加法操做,乘積寄存器的內容並無改變。因此,實際上咱們能夠將這個分支取消,在每輪的最開始都直接將乘數寄存器的最低位和被乘數寄存器進行」與操做」,而後和乘積寄存器相加。這樣不管最低位是1,仍是0,都能完成這個工做流程圖所表達的工做。

屏幕快照 2018-07-09 11.27.00

那即便對於這個優化後的工做流程,效果也是同樣的。由於第一步的檢查以後,2和3這兩步操做都會執行,惟一的區別在於1a這個操做。因此,採用剛纔所描述的那種修改(前一個圖片提供的修改方案,引入「與操做」),也能夠達到一樣的效果。所以,對於這個工做流程來講,在實際的實現當中也能夠不存在這個分支的操做。

屏幕快照 2018-07-09 11.27.10

然而對於除法的這個工做流程,這一次減法的運算結果是事先沒法預知的。所以,沒法預知下一步將執行哪個分支,並且其中一種分支還須要將這個減法操做進行回退。因此,也沒有辦法將兩個分支進行合併。所以,在這個除法運算流程的大框架之下,是很難進行進一步的性能優化了。

屏幕快照 2018-07-09 11.27.19

正是因爲除法的優化很是的困難,於是也引來了不少人對除法進行深刻的研究,也產生了不少頗有趣的,快速除法的實現方法。若是你對此有興趣,能夠進一步深刻地探索。

相關文章
相關標籤/搜索