1. 程式人生 > >計算機組成.計算機在計算啥.運算與ALU

計算機組成.計算機在計算啥.運算與ALU

  • 一身冷汗
  • 原本打算在iPad上寫下一篇“處理器”。上一次用iPad寫的這篇在開啟瀏覽器後還儲存著,我就直接刪掉重寫了。結果把原本的我的這篇給覆蓋了……
  • 幸虧我有備份……
  • 不過格式還是得再MarkDown上重新調整……心好累
  • 突然發現在iPad的網頁上也可以寫部落格哎,,這樣就不用揹著厚重的筆記本了
  • 寫了兩句就發現,在輸入狀態下文字編輯視窗只能保持在最高,,,這樣就被虛擬鍵盤擋住了,,,體驗-1
  • 再寫兩句發現又好了,,,體驗+1

  • 我所認為的計算機的運算,無非就是“算數”,除了傳統的加減乘除外,在二進位制的表示下,還有邏輯運算與移位運算。

  • 而計算機真正的魅力在於,可以算得很快,所以承受得住我們去對每一個運算所賦予的詳細含義,在各種含義下的運算互相碰撞著,也就幹成了各種各樣的事情。
  • 移位運算實際上是一種受限的乘除,即只能擴大縮小一定的倍數。
    • 比如1000右移一位成0100也就縮小了2倍,再移一位成0010又縮小了2倍,相對於最初縮小了4倍。
    • 那我想縮小三倍怎麼辦?這就是乘法和除法要做的事,其很大程度上依賴了移位運算。

定點數的運算

  • 二進位制的特點是,只有1和0,也就可以把“1”對應為“邏輯真”,“0”對應為“邏輯假”
  • 真真假假與或非,假假真真閘電路
  • 簡單的認識一下的話,計算機內把每一位也就是每個bit用一個電位體現,當這個電位有電錶示1,沒電錶示0
  • 所以說計算機為什麼非要採用二進位制而不用十進位制或其他進位制呢?
    • 這是因為資料中的每一位需要用一位表示的話,一個電位要表示0到9的十種狀態,就要有十個電壓等級,這無疑是很複雜的。
    • 而且一位表示的資訊越多,其處理起來也越複雜,而二進位制只有1和0,處理起來極為簡單,當二進位制儲存的位也多,其處理的複雜在於多個位之間的聯絡。

閘電路

  • 閘電路幹啥的?
    • 還記得1和0是用“有電”和“沒電”來表示的嗎,而閘電路就是來根據有電和沒電的狀態來對1和0進行運算
  • 什麼是運算?
    • 我說1+1=2,實際上是輸入了兩個值,分別是1和1,告訴說對著兩個數的運算是“+”,那麼我就可以得到一個輸出的結果2
  • 每種閘電路本身就對應了一種運算形式,最簡單的閘電路就是與“AND”、或“OR”、非“NOT”
    • 一般一個閘電路有兩根電線作為輸入,有一根電線作為輸出
    • 與AND:只有輸入的兩根電線都有電,輸出的電線才有電
    • 或OR:只有輸入的兩根電線都沒電,輸出的電線才沒電
    • 非NOT:只有一個輸入電線,輸入有電則輸出沒電,輸入沒電則輸出有電
    • 有電、沒電、電線都是我臆想的,實現的方法我猜大概是串並聯開關啥的吧,,,作為理解尚可,而具體能否這樣實現我不知道了,,,有時間打算研究一下數位電路

與或非

  • 注意,非門中真正起作用的是那個小圈圈,表示取反,常與其他閘電路結合表示各種更為複雜的電路

其他閘電路

邏輯運算

  • 邏輯非
    • 也就是取反,1變0,0變1 由“非門”電路實現
  • 邏輯加
    • 就是“或”,1+1=1,1+0=1,0+1=1,0+0=0。 由“或門”電路實現
  • 邏輯乘
    • 就是“與”,1·1=1,1·0=0·1=0·0=0。 由“與門”電路實現
  • 邏輯異或
    • “XOR”,其規則是1 XOR 1 = 0 XOR 0 = 0 ,1 XOR 0 = 0 XOR 1 = 1
    • 解釋1:相同輸出0,不同輸出1。只適合兩個數的時候。
    • 解釋2:參與運算的1的個數為偶數輸出0,為奇數輸出1。 適合多個數進行XOR運算時候,比如1 XOR 0 XOR 1 = 0。
    • 異或運算有很多很好的特性,沒法講,活久見

移位運算

  • 移位運算就是按位平移,有的位會移到外面,那麼就丟棄,有的位會空出來 ,那麼就補0,這個絕對的“補0”是對於原碼而言的。
  • 還是4 bit為例,二進位制數“1000”
    • 每位起個名字,最高位w3為1,依次w2為0,w1為0,w0為0
    • 右移一位,就是讓w0取w1的值,w1取w2的值,w2取w3的值,w3沒地方取,就補0,變成了“0100”,視覺上就是“右移了一位”
    • 機器總是需要一個符號位來表示有符號數,而顯然符號位在移位的時候並不參與,那麼
  • 對於有符號數的移位操作,我們叫“算數移位”
  • 對於無符號數的移位操作,我們叫“邏輯移位”
  • 其實無論算數移位還是邏輯移位,都是一種移位的規則,只不過只有對於各自的運算元才有意義。 顯然符號位的移位並沒有什麼意義,,,,,,當然如果有什麼特殊的手法可以讓符號位的移動產生重要的意義,那麼當然是可以移動的。

  • 算術移位

    • 基本規則:符號位不變,移位的空位補0
    • 細則1:對於正數,無論機器內使用原碼、反碼還是補碼錶示,其都是原碼的形式,因正數的原碼反碼補碼是同樣的表示,所以空位補0
    • 細則2:對於負數,原碼下空位補0,反碼空位補1,補碼左移補0,右移補1
    • 有個表格會好理解一些,依舊是4bit,最高位符號位
數值 原碼 補碼 補碼左移1位 左移後值 補碼右移1位 右移後值
2 0010 0010 0100 4 0001 1
-2 1010 1110 1100 -4 1111 -1
  • 還有一點,就是移位的固有影響

    • 本質上是乘、除的二進位制簡化形式,左移一位即乘2,右移一位即除2
    • 而操作的數又是整數,那麼在不斷乘2(左移)的時候很可能會超過其上限而造成結果出錯,而在不斷除2(右移)的時候很可能有會因為原數為奇數而不能正確的得出其原值*0.5的值,表現就是取整,造成精度損失
    • 從移位的角度來看,移位的時候必然會捨棄一位,而捨棄的一位若含有原數的資訊,就會造成錯誤。
    • 至於原碼反碼補碼分別在左移右移時丟棄1還是0的時候才會出錯,,,不再細究,,,
  • 邏輯移位

    • 基本規則是,無論左移右移,空位補0 無論移丟0還是1,都不影響結果的正確性和精度 沒意思,不寫了

加減

  • 由於計算機引入了補碼,目的就是為了統一了正負數的運算,所以加減乘除也就要在補碼下講,當然在原碼下也同樣可講,,,

  • 對於兩個數值X,Y(我是說數值哦)

    • 加法:[X + Y]補 = [X]補 + [Y]補 (mod 2^n)
    • 減法:[X - Y]補 = [X]補 + [-Y]補 (mod 2^n)
    • 之所以要mod2^n,是因為原本長度為n位,運算之後可能會有進位導致長度變長,而實際上計算機是沒有辦法儲存多出來的那一位(儘管可以採取某種特殊的手段來儲存)所以就捨棄掉了。
    • 對於減法的 [-Y]補 ,其求法為 [Y]補 的每位(包括符號位)取反後+1,即[-Y]補 = [Y]補 +1。當Y為正數時,-Y為負數,負數的補碼也就是對應正數的取反後+1,符合我們所知的轉換規則。而這條規則同樣適用於Y為負數的時候。
    • 慣例列表
X值 [X]補 加法 Y值 [Y]補 結果值 [結果]補
2 0010 + 1 0001 3 0011
-1 1111 + 2 0010 1 0001
X值 [X]補 減法 Y值 [-Y]補 結果值 [結果]補
3 0011 - 1 1111 2 0010
2 0010 - -1 0001 3 0011

乘除

  • 早期的計算機一般只有加法器和移位電路,乘法的實現依賴於加法和移位。
  • 我們知道移位就是一種受限的乘法,左移一位相當於乘2,左移兩位相當於乘4。那麼乘法就是解決中間乘3的問題。很簡單可以想到,乘3就等於原數乘2+原數本身,也就是一次移位和一次加法來實現。
  • 那麼這種思路可不可以形成一種公式來指導任意的乘法運算呢? 當然是有的

原碼一位乘法

  • 先在原碼下考慮,補碼的話其實會有些不同。注意原碼錶示的乘數下,結果也應該是用原碼錶示
  • 先以我自己琢磨的定點整數為例,約定一下按每一位來表示的整數我寫在[ ]裡面,並用空格間隔開每位。
    • 則A=[a3 a2 a1 a0] B=[b3 b2 b1 b0]
    • A*B的每一位用c來表示,則c3 = a3 XOR b3,即符號位可以由兩個乘數的符號位直接得出(異或運算)從而符號位可以不用參與實際的運算過程
      • [c2 c1 c0]
      • = [a2 a1 a0] * [b2 b1 b0]
      • = [a2 a1 a0] * ( [b2 0 0] + [0 b1 0] + [0 0 b0] )
      • = [a2 a1 a0] * [0 0 b0] + [a2 a1 a0] * [0 b1 0] + [a2 a1 a0] * [b2 0 0]
      • = [a2 a1 a0] * b0 * 2^0+ [a2 a1 a0] * b1 * 2^1 + [a2 a1 a0] * b2 * 2^2
    • 注意到:
      • b2 b1 b0實際上就是B的每一位,而且只能是1或0
      • 如果是0,則對應項就不必運算
      • b0所在項需要乘2^0,也就是不需要左移
      • b1所在項需要乘2^1,也就是左移一位,也就是在前一項的基礎上左移一位
      • b2所在項需要乘2^2,也就是左移二位,也就是在前一項的基礎上左移一位
      • 至此其實已經相當明瞭了,就是根據乘數B的每一位,對乘數A進行左移並加上之前的值,我們把之前的值作為部分積的概念引入
        • 取部分積 Z0 = 0,A的絕對值記為|A|
        • Z1 = |A| * b0 * 2^0
        • Z2 = |A| * b1 * 2^1 + Z1
        • Z3 = |A| * b2 * 2^2 + Z2
        • 但是這樣還有個不足之處,那就是我每次進行的移位位數是遞增的,而這很容易改進,從公式就可以簡單的入手
      • 原式
      • = [a2 a1 a0] * b0 * 2^0+ [a2 a1 a0] * b1 * 2^1 + [a2 a1 a0] * b2 * 2^2
      • = [a2 a1 a0] * b0 + 2 * ( [a2 a1 a0] * b1 + 2 * [a2 a1 a0] * b2 )
      • 取部分積 Z0 = |A| * b2
      • Z1 = Z0 * 2 + |A| * b1
      • Z2 = Z1 * 2 + |A| * b0
      • 語言描述下就是:
        • 1、部分積取 |A| * b2
        • 2、部分積左移一位
        • 3、部分積 += |A| * b1
        • 4、部分積左移一位
        • 5、部分積 += |A| * b0 得到結果
  • 再以書上所講的定點小數為例
  • 設A=[a3 . a2 a1 a0],B=[b3 . b2 b1 b0],
    • a3和b3表示符號位
    • 真正的純小數部分為 0. a2 a1 a0 的形式
    • 乘積的符號依舊由 a3 XOR b3 算得
      • A * B
      • = [0. a2 a1 a0] * [0. b2 b1 b0]
      • = [0. a2 a1 a0] * ( [0. b2 0 0] + [0. 0 b1 0] + [0. 0 0 b0] )
      • = [0. a2 a1 a0] * b2 * 2^-1 + [0. a2 a1 a0] * b1 * 2^-2 + [0. a2 a1 a0] * b0 * 2^-3
      • = [0.a2 a1 a0] * b2 * 2^-1 + 2^-2 * ( [0. a2 a1 a0] * b1 + [0. a2 a1 a0] * b0 * 2^-1 )
      • = 2^-1 * ( [0. a2 a1 a0] * b2 + 2^-1 * ( [0. a2 a1 a0] * b1 + [0. a2 a1 a0] * b0 * 2^-1 ) )
      • = 2^-1 * ( |A| * b2 + 2^-1 * ( |A| * b1 + 2^-1 * |A| * b0 ) )
        取部分積Z0 = |A| * b0 Z1 = 2^-1 * Z0 = Z0 右移一位 Z2 = Z1 + |A| * b1 Z3 = 2^-1 * Z2 = Z2 右移一位 Z4 = Z3 + |A| * b2 Z5 = 2^-1 * Z4 = Z4 右移一位
        • 語言描述
          • 部分積取 |A| * b0
          • 部分積右移一位
          • 部分積 += |A| * b1
          • 部分積右移一位
          • 部分積 += |A| * b2
          • 部分積右移一位
        • 注意到 b0 b1 b2 的含義,它們是乘數 B 的每一位,而且值只能是1和0。反映到過程中講就是,如果 B 中有一位為1,那就要在“相應的兩次右移之間”部分積加上一次 |A|,如果該位為 0,部分積就可以連續右移。
  • 小結:
    • 定點整數左移,定點小數右移 乘法被分解成“加上原數和移位一位”的多次重複
    • 結合硬體的佈局也許會更容易理解。
    • 一下是定點小數的硬體佈局

原碼一位乘法

補碼一位乘法

  • 補碼一位乘法又稱為校正法,原因就是有了原碼一位乘法的基礎,補碼一位乘法只需稍作分析和校正即可轉換為原碼一位乘法來運算
  • 以定點小數為例,並給出一張幫助理解的編碼表
編碼 一般意義下的值 視為補碼下的值 視為原碼下的值
0.00 0 0 0
0.01 0.25 0.25 0.25
0.10 0.5 0.5 0.5
0.11 0.75 0.75 0.75
1.00 1 -1 -0
1.01 1.25 -0.75 -0.25
1.10 1.5 -0.5 -0.5
1.11 1.75 -0.25 -0.75
  • 取兩個乘數 X 和 Y均為小數 ,這裡用X和Y表示一般意義下的編碼。
    • 所謂的一般意義就是不用符號位來儲存符號,而是直接用“+”和“-”,就像我們正常寫十進位制的數字的時候,正12就寫成“12”,負11就寫成“-11”。
      |數值 |一般編碼 |原碼 |補碼|
      |0.25 |+0.01 |0.01 | 0.01|
      |-0.25 |-0.01 |1.01 |1.11|

模運算

  • 在這裡我們再講一下模運算
  • 給定一個正整數p,任意一個整數n,一定存在等式n=k?p+r 滿足k為整數,r為整數且 0 <= r < p
  • 我們稱k為商,r為餘數
    • 所謂的模運算,也就是n mod p=r 這種形式,程式設計裡用 % 運算子來表示模運算,即 n % p=r
  • 模運算規律,只介紹我們用到的兩條和我額外新增的輔助理解的簡單規則
    • 一、(a + b)%p = (a%p + b%p) %p
    • 二、(a * b)%p = (a%p * b%p)%p
    • 三、a%p = (p + a)%p
    • 四、a>0時,由上一條,(-a)%p = (p-a)%p,即一個負數模p可以等價轉換成一個正數模p,而這兩個數的絕對值之和為p

正文

  • [X]補 = x0.x1x2x3…xN-1,[Y]補 = y0.y1y2y3…yN-1
  • 當 X 的符號任意,Y為正數的時候
    • [Y]補 = 0.y1y2y3…yN-1 = Y
    • [X]補 = x0.x1x2x3…xN-1 = 2+X = 2^N +X (mod 2)
      • 解釋一下
      • 這裡等號“=”的意義是“編碼後長得相同”
        • 當Y為正數的時候,Y的一般意義下的編碼形式和Y的補碼形式相同,顯然易見。
        • X為任意數,即可正可負。但是X是定點小數,不考慮符號的話一般意義下表示的數字範圍是[0,2),所以對於一個數值X,其加上2後的編碼一樣,因為“2”本身已經超過了編碼的能力,即使加上了也無法被編碼,具體的表現形式就是截斷。外在表現之一就是模運算的運算規律三。
        • 如X的值為0.25,編碼為000.01000,按表格中儲存的位來截斷之後的編碼就是0.01 X+2的值為2.25,編碼為010.01000,截斷後仍是0.01。
      • 進一步分析,如果X為負數怎麼辦。
        • 依舊是舉例說明。
        • X的值為 -0.25 ,
        • 根據表格 X的補碼形式是 “1.11”
        • X+2的值為1.75,一般編碼的形式是“1.11”
        • 也就是說,冥冥之中,有一種特殊的方法規律可以把我們一般意義下的編碼和補碼統一起來,簡單的+2並取模就可以轉換。
        • 這個規律就是:對於任意小數 N,有 [N]補 = 2 + N (mod 2),而這個規律恰又對應上了模運算的規律三,而且其實有種內在的數學聯絡。
    • 進一步的進行數學分析
      • [X]補 * [Y]補
      • = [X]補 * Y
      • = (2^N + X) * Y (mod 2)
      • = ( 2^N * Y (mod 2) + X * Y ( mod 2) ) (mod 2)
      • = ( 2 (mod 2) + X * Y (mod 2) ) (mod 2)
      • = ( 2 + X * Y) ( mod 2)
      • = [X * Y]補
      • 注意到中間加粗部分的轉換,即”2^N * Y (mod 2) = 2 (mod 2)”
        • 2^N * Y 也就是對Y進行左移,還記得 Y 是 0.y1y2y3…yN-1嗎,如果左移N-1位的話,也就變成了 y1 y2 y3 … yN-1.000…0,這本身是一個大於等於1的數(注意到Y是一個正數),所以“原式 = 2 * 一個大等於1的整數 (mod 2) ”也就等於“2 (mod 2)”。其實二者在mod 2的意義下就都是0了嘛。
        • 之所以轉換成2,而不是其他同樣是全0的編碼,是為了對應上文的規律,從而得出 [X * Y]補 這個最終結果
        • 所以最終的結論就是:[X * Y]補 = [X]補 * Y
    • 疑問?從推導過程中可以發現,在最後兩步的等式中,即(2+X?Y) (mod 2)=[X?Y]補
    • 對前者運用模運算的規律的話就可以直接去掉2,從而變成了 (X?Y) (mod 2) = [X?Y]補 了啊,這很奇怪啊。。。
      • 其實這樣的推導很對,確實可以得出這個結果,而且這個結果也確實是對的。
      • 這裡X和Y的意義是“一般編碼”下的形式,分類討論一下的話
        • X為正,Y本為正,則式子顯然成立
        • X為負,Y為正,則 X * Y 其實是一個負值,但這還不是最終的結果,最終[X * Y]補所對應的是 (X * Y)(mod 2),也就是身為負值的 X * Y模2之後的結果。要知道模運算的結果r總是一個大於等於0的數,所以最終[X * Y]補的編碼形式其實也就是和 (2+X*Y)的編碼形式相同。
        • 但我們最終需要的是直接使用[X]補和[Y]補來運算得到[X*Y]補。所以我們留下了“2”,不僅僅是因為這樣做是正確的(見上條的分類討論),同時也是因為我們這樣可以轉換成我們需要的形式。
    • 再說一遍我們的推導結論:[X * Y]補 = [X]補 * Y
    • 這個結論意味著什麼呢?意味著我們最終需要得到的X*Y的補碼形式可以直接由X的補碼和Y的補碼(因為此時Y為正所以[Y]補=Y)形式直接參與運算得到。
    • 具體的運算步驟和原碼的拆分一模一樣,簡單講一下
      • [X * Y]補 = [X]補 * 0. y1 y2 y3 … yN-1
      • 取部分積Z0 = 0,我們最終要得到的結果是[Zn-1]補
        • [Z0]補 = 0
        • [Z1]補 = 2^-1 * (yN-1 * [X]補 + [Z0]補)
        • [Z2]補 = 2^-1 * (yN-2 * [X]補 + [Z1]補)
        • ……
        • [Zn-1]補 = 2^-1 * (y1 * [X]補 + [Zn-2]補) = [X * Y]
  • 當X的符號任意,Y為負數的時候
    • 我不打算推導了,,,真累
    • 結論:[X * Y]補 = [X]補 * 0.y1 y2 y3 … yN-1 +[-X]補
    • 最後需要加上的 [-X]補
    • 也就是補碼一位乘法的校正值,可見校正只需要在Y為負的情況下才需要
  • 所以實際在運算的時候,只有一個乘數是以真正的補碼的形式參與了運算,而Y則需要在判斷了符號之後去掉符號位變成正數來參與運算,Y的符號位做額外判斷是為了判斷最後是否需要加上[-X]補來進行校正
  • 那有沒有兩個乘數都以補碼的形式直接參與運算,最後得出正確的補碼形式呢?額符靠絲

布斯演算法“Booth演算法”

  • [X]補 = x0.x1x2x3…xN-1
  • [Y]補 = y0.y1y2y3…yN-1
  • 按照校正法的結論[X*Y]補 =[X]補 * 0.y1y2y3…yN-1 +y0 * [-X]補
  • 由於在mod 2的意義下,[-X]補 = -[X]補 (mod 2)
    • 證明:證明太晦澀,我可以舉例來解釋一下
    • 取X=0.25,則-X = -0.25。後面幾行都是二進位制的形式
    • 查表:[X]補 = 0.01 ; [-X]補 = 1.11
      • -[X]補 = -0.01
      • -0.01 (mod 2)
      • = (10.00 - 0.01) (mod 2)
      • = 1.11 (mod 2) = 1.11
    • 所以有[-X]補 = -[X]補 (mod 2)
    • 簡單說來就是,mod 2意義下,負值總要通過加2來轉化為正值,之後再談編碼形式 所以最終就有如下的形式
  • [X * Y]補
    • = [X]補 * (0.y1y2y3…yN-1)- y0 * [X]補
    • = [X]補 * (-y0 + y1 * 2^-1 + y2 * 2^-2 + … + yN-1 * 2^-(N-1) )
    • = [X]補 * [ (y1 - y0) + (y2 - y1) * 2^-1 + … + (yN-1 - yN-2) * 2^-(N-2) + (0 - yN-1) * 2^-(N-1) ]
    • = [X]補 * [ (y1 - y0) + (y2 - y1) * 2^-1 + … + (yN-1 - yN-2) * 2^-(N-2) + (yN - yN-1) * 2^-(N-1) ] 式中”yN = 0”
  • 如此再結合部分積
    • 取部分積Z0 = 0
    • Z1 = 2^-1 * {Z0 + (yN - yN-1) * [X]補 }
    • Z2 = 2^-1 * {Z1 + (yN-1 - yN-2) * [X]補 }
    • ……
    • ZN-1 = 2^-1 * { ZN-2 + (y2 - y1) * [X]補 }
    • ZN = ZN-1 + (y1 - y0) * [X]補 = [X * Y]補
  • [X]補直接參與了運算,y0也參與了運算也就意味著Y也是以補碼的形式[Y]補直接參與了運算
  • 特點
    • 首先是X和Y均是以補碼的形態[X]補和[Y]補參與了運算
    • 結果是[X*Y]補
    • 運算期間的邏輯變得複雜了,原先只需要看Y的對應位是1和0,而現在每一步需要用到Y的兩位之間的差,見下面的表格
    • 最後一步是不需要乘2^-1,也就是不需要右移
yi-1 yi yi - yi-1 操作
0 0 0 加上0,然後右移一位
0 1 1 加上[X]補,然後右移一位
1 0 -1 加上[-X]補,然後右移一位
1 1 0 加上0,然後右移一位

除法運算

  • 因為考試不考,,,所以先不細寫了,,簡要講一下我對除法的理解
  • 想象一下十進位制下手算除法的過程,總是要去湊出每一位,使其與除數相乘的結果剛好不大於下面的被除數。
  • 每次湊數的時候都需要乘乘看到底是不是剛好不大於被除數。
  • 那麼在二進位制下也是湊的嗎?不,這可是神奇的二進位制
  • 因為二進位制只有0和1,所以假如在二進位制下模仿十進位制除法的姿態,我們去湊數的時候也只有0和1兩種選擇
    • 如果0是正確的結果,這也就意味著除數大於被除數
    • 如果1是正確的結果,這也就意味著除數小於被除數
    • 也就是說,在二進位制下,我們不需要湊數,只需要比較一下除數和被除數那個大,就可以知道當前數位上是填0還是填1了。
    • 比較好比啊,只需要兩個數減一減就知道誰大誰小了。
    • 再配合上移位操作,除法也就被完美的用減法和移位實現了。
    • 嗯。神奇的二進位制。
  • 具體的方法有
    • 原碼恢復餘數除法
      • 核心思想就是:每次在做減法看誰大誰小來決定填1還是0的時候,我們並不知道到底誰大誰小。
      • 看誰大誰小,就需要看減完的餘數是正還是負
      • 如果餘數為負,就說明我們減過頭了,自然是填0,但是我們還需要再把餘數恢復過來,也就是所謂的“恢復餘數”
    • 原碼加減交替除法
      • 核心思想就是:改進了原碼恢復餘數除法,不需要恢復餘數。
      • 本質上我們不需要死板的看餘數的正負才能判斷誰大誰小,
        在餘數為負的時候,我們可以通過加上除數而不是恢復餘數後再去除數,一樣可以判斷誰打誰小來進一步判斷填1還是0
      • 餘數為正的時候自然就是減去除數
      • 所謂加減交替

ALU

  • 算術邏輯單元(arithmetic and logic unit)
  • 組成:
    • 內部組成:
    • 加法器AU
    • 邏輯運算器
    • 移位器
    • 求補器
  • 外部組成:
    • 兩個輸入緩衝器A和B
    • 輸出緩衝器SUM
    • 進位標誌CF、溢位標誌OF、符號標誌SF、零標誌ZF

ALU

加法器

  • 加法器比較好講,也比較簡單
  • 所以大概這就是被選入教材的原因

序列加法器

  • 考慮我們手算加法的時候,總是
    • 先個位相加,選出結果和進位
    • 再十位相加並加上進位,再算出結果和進位
    • ……
  • 這個就是一個鏈式的過程,每一位(除了第一位)之外其結果的得出都依賴於前一位的進位,並且該位運算完的進位需要提供給下一位才能得出下一位的結果和進位,下一位的進位再……
  • 基本邏輯單元:全加器FA(Full Adder)

FA

  • 介紹
    • 兩個本位加數 Ai 和 Bi
    • 低位進位 Ci-1
    • 本位和 Si
    • 向高位的進位 Ci
    • Si = Ai XOR Bi XOR Ci-1
    • Ci = Ai·Bi + (Ai+Bi)·Ci-1(邏輯加OR 與 邏輯乘AND)
    • 記Gi=Ai·Bi稱為本位進位
    • 記Pi=Ai+Bi稱為傳遞條件,Pi·Ci-1稱為傳遞進位
    • 可見:Ci = Gi + Pi·Ci-1
  • 多個FA串接起來,就組成了序列加法器

並行加法器

  • 我們看到,每一位之間的依賴關係,是“進位值Ci”
  • 如果我們能提前知道了每一位的 Ci,那麼位之間的依賴關係也就不復存在了,也就可以並行進行了,就是同時算所有的數位

  • 有辦法嗎?有的

  • 以四位CRA(Carry Ripple Adder)為例

    • C0 = 0
    • C1 = G1 + P1·C0
    • C2 = G2 + P2·C1
    • C3 = G3 + P3·C2
    • C4 = G4 + P4·C3
  • 進一步變換可得到
    • C0 = 0
    • C1 = G1 + P1·C0
    • C2 = G2 + P2·G1 + P2·P1·C0
    • C3 = G3 + P3·G2 + P3·P2·G1 + P3·P2·P1·C0
    • C4 = G4 + P4·G3 + P4·P3·G2 + P4·P3·P2·G1 + P4·P3·P2·P1·C0
  • 容易看出,雖然邏輯複雜了很多,但是Ci只和G、P、C0有關,而不依賴於Ci-1,而G、P有隻和各自的Ai、Bi有關
  • 這也就意味著,我們一開始就知道的Ai、Bi和C0=0,足以求出C1、C2、C3、C4。這樣不就是“提前把所有的Ci”求出來了嘛
  • 我們就設計了這樣的邏輯電路,輸入是G1、P1、G2、P2、G3、P3、G4、P4、C0,依照公式設計好電路,輸出是C1、C2、C3、C4,分別輸入到對應的全加器FA中。
  • 這就是先行進位加法(Carry Look Ahead, CLA)鏈,也叫超前進位鏈

CLA

  • 四個FA和一個CLA就可以組成一個四位的先行進位加法器,SN74181就是這樣一種ALU晶片

SN74181

  • 至此也就瞭解了基本的並行思想 然而多個SN74181之間仍然需要序列,,嗯哼,我猜你想到了什麼。沒錯,可以用同樣方法來對多個SN74181進行並行化
    • D1 = G4 + P4·G3 + P4·P3·G2 + P4·P3·P2·G1
    • T1 = P4·P3·P2·P1

    • C4 = D1 + T1·C0
    • C8 = D2 + T2·D1 + T2·T1·C0
    • C12 = D3 + T3·D2 + T3·T2·D1 + T3·T2·T1·C0
    • C16 = D4 + T4·D3 + T4·T3·D2 + T4·T3·T2·D1 + T4·T3·T2·T1·C0
  • 和之前很是對稱的形式,只不過D和T是由G和P來生成 ,而G和P是直接由A和B來生成。實際上實現的邏輯電路完全一樣,但是
    • 前者CLA提前生成的是FA之間的進位訊號,我們稱之為組內訊號
    • 而此時提前生成的是SN74181之間的進位訊號 ,稱為組間訊號
    • 我們稱此時實現的邏輯電路為成組先行進位(Block Carry Look Ahead,BCLA)鏈 SN74182就是一個BCLA部件。
  • 注意和SN74181的含義並不對稱
  • 等等我就不畫圖了,基本思路知道就好,按理可以無限的並行下去,但問題是
    • 1)我們不一定需要那麼多位的運算
    • 2)雖然是模組化 設計但避免不了複雜度的提高,不過這種越往上並行所需要的部件就越少,就部件數量來說並不會增加很多。

浮點數運算

  • 這個就很簡單

加減

  • 按部就班的來,不過我想你也應該有思路
    • 1、對階:使兩個運算元 階碼相同
    • 2、尾數求和:對尾數進行加減運算
    • 3、規格化:規格化運算的結果
    • 4、舍入:為保證精度,考慮尾數右移的時候丟失的數值是否需要舍入(相當於十進位制下的四捨五入)
    • 5、溢位判斷:上溢下溢還是沒溢位
  • 列舉一下舍入的策略
    • 截斷法:直接捨棄丟失的數值
    • 0舍1入法:丟失0就直接丟棄,丟失1就置最低位為1(對原碼所言)。補碼下自然應是“1舍0入”了)
    • 恆置1法:也叫“馮·諾依曼舍入法”,無論丟失0或1,永遠置最低位為1。簡單但是誤差大
    • 查表舍入法:用ROM存一張表,以尾數的最低K位和丟失的最高位作為地址,查找出的數值來代替尾數的最低K位。提前設計好。由於讀取ROM要比直接進行加法快,所以速度快。但又增加了硬體。

乘除

  • 自己想象怎麼算。嗯,很簡單吧。
    • 1、階碼相加、減
    • 2、尾數相乘、除
    • 3、規格化
    • 4、舍入處理
    • 5、溢位判斷

相關推薦

計算機組成.計算機計算.運算ALU

一身冷汗 原本打算在iPad上寫下一篇“處理器”。上一次用iPad寫的這篇在開啟瀏覽器後還儲存著,我就直接刪掉重寫了。結果把原本的我的這篇給覆蓋了…… 幸虧我有備份…… 不過格式還是得再MarkDow

計算機組成原理基礎知識-運算方法

移位 配置 減法 一個 乘除 求反 計算 機器數 邏輯 五.計算機的運算方法 --在計算機中參與運算的數有兩大類:無符號數和有符號數   無符號數:沒有符號的數   有符號數     機器數與真值:機器中:0表示正,1表示負     原碼表示法:把真值的正負用01表示   

計算機組成.就是它在運算.處理器CPU

處理器是要好好複習了,畢竟考試重點 主要的內容感覺還是在指令方面,包括指令的格式、指令集的設計、指令流水線、指令級並行。 東西慢慢整理吧,如果一邊在網上搜索的估計會找到很多資料,但是耗費的時間太多了 國內的教材雖然有一定的侷限性,但是tm的要考試啊 我覺得需要

計算機組成原理-實驗三-多功能ALU設計實驗

實驗要求:        本實驗要求設計一個具有8種運算功能的32位ALU,並能夠產生運算結果的表示:結果為零標誌ZF(Zero Flag)、進借位標誌位CF()溢位標誌OF(Overflow Flag)、符號位標誌SF(Sign Flag)和奇偶標誌PF(Parity Fl

計算機組成設計(3)-----算術運算

思維導圖 本文主要包括整數和浮點數的算術運算,他們都是被名為算術邏輯單元的硬體實現 一.整數運算 1.1加法 二進位制數的加法採用從右到左將對應的位同進位依次相加的方式實現 //模擬二進位制5+7的實現(16位) 0000 0000 0000 0101

計算機組成設計:硬體/軟體介面】第三章:計算機的算術運算

【計算機組成與設計:硬體/軟體介面】第三章:計算機的算術運算 標籤(空格分隔):【計算機組成與設計:硬體/軟體介面】 第三章:計算機的算術運算 第三章:計算機的算術運算 3.1 引言 3.2 加法和

計算機組成原理筆記之浮點數運算

http 計算機組成 nbsp 技術 -1 .com alt bsp 筆記 計算機組成原理筆記之浮點數運算

計算機組成原理儲存器的補充——半導體儲存晶片儲存容量資料線和地址線的關係

1、儲存器 Ⅰ Flash ROM: SST39VF1601 資料位寬為16位(16根資料線);20根地址線;2M(1M*16bit)。 Ⅱ SDRAM: HY57V641620HG 資料位寬為16位(16根資料線);12根地址線(行地址選擇線有12根,列地址選擇線有8根(1

計算機組成設計 有意思的句子

前言 我們能體驗的最美好的東西是神祕的事物。他是所有真正藝術和科學的來源。 ——阿爾伯特·愛因斯坦 《我的世界觀》,1930 第1章 計算機概念和技術 增多我們不加思索就能完成的重要工作的數量,文明便是如此進步的。 ——Alfred North Whitehead,An Introducti

系統架構設計師(1)-計算機組成體系結構

一、流水線 將需要處理的工作分為N個階段,最耗時的那一段所消耗的時間。如,使用流水線技術執行100條指令,每條指令取指2ms,分析4ms,執行1ms,那麼,流水線週期是4ms。 流水線執行時間T  =  第一條指令的執行時間 + (N-1)*流水線週期t (2017)

計算機組成原理補充——主存Cache的地址對映

  CPU對儲存器的訪問,通常是一次讀寫一個字單元。當CPU訪Cache不命中時,需將儲存在主存中的字單元連同其後若干個字一同調入Cache中,之所以這樣做,是為了使其後的訪存能在Cache中命中。因此,主存和Cache之間一次交換的資料單位應該是一個數據塊。資料塊的大小是固定的,由若

計算機組成設計(二)——算術邏輯運

 算術運算 計算機結構的簡化模型(模型機)     演示例項一 以add $8,$9,$10(格式被Latex強行改變,不知道怎麼辦555。。。)演示加法運算 1、首先取指令,即得到得到指令的編碼 查指令編碼表知opcode = 0,function =

計算機組成設計(三)—— 門電路的基本原理

http 計算機 都是 計算機組成 tor uri font 同時 get 集體管 現在集成電路中常使用MOS集體管:Metal-Oxide-Semiconductor(金屬-氧化物-半導體) 晶體管有兩種類型:N型和P型,由NMOS和PMOS共同構成的互補型MOS集成

計算機組成設計(四)—— 加法和減法的實現

二進位制加法 半加器(Half Adder) 半加器的功能是將兩個1位二進位制數相加。輸入埠A、B,輸出埠S(輸出),C(進位)。 其有一個很明顯的缺點:不能將低位的進位參與運算。   全加器(Full Adder) 全加器由兩個半加器構成。輸入埠A、B、Cin,輸出埠S(和)、Co

計算機組成設計(五)—— 加法器的優化

4-bit加法器示例 先看一下上一節得到的加法器實現,可以看出改進的地方。 不難發現整個過程是從右至左依次執行,每一個進位需要等前面的運算全完成,可以在一開始得到所有的進位嗎?   行波進位加法器(Ripple-Carry Adder,RCA) 像上面4-bit加法器這樣實現的加法器被

計算機組成設計(六)—— 乘法器

乘法的運算過程 人們日常習慣的乘法是十進位制,但計算機實現起來不方便。首先,需要記錄9x9乘法表,每次相乘去表中找結果;其次,將豎式相加也不方便。 但二進位制卻十分方便,馮·諾伊曼在《關於ENDVAC的報告草案》中說“二進位制可以極大簡化乘法和除法運算。尤其是對於乘法,不再需要十進位制乘法表,也不需要兩輪

計算機組成設計(七)—— 除法器

除法的運算過程 與乘法相比,除法的實現較為複雜,運算過程如下: 過程: 被除數和餘數:將餘數和被除數視為一個,共享一個暫存器,初始值為被除數 除數:可視為不斷右移,並和被除數相減 商:每個bit依次生成,可視為不斷左移   除法器的工作流程   要注

計算機組成設計(八)—— 單週期處理器

處理器的設計步驟 分析指令系統,得出對資料通路的需求 為資料通路選擇合適的元件 連線元件,建立資料通路 分析每條指令的實現,以確定控制訊號 整合控制訊號,完成完整的資料通路   具體設計步驟 (一)分析指令系統 MIPS的所有指令是非常多的,我們只實現其簡化版,包

計算機組成設計(八)—— 單周期處理器

uri 處理器 lec zuche 輸入 style 我們 方式 gis 處理器的設計步驟 分析指令系統,得出對數據通路的需求 為數據通路選擇合適的組件 連接組件,建立數據通路 分析每條指令的實現,以確定控制信號 集成控制信號,完成完整的數據通路