1. 程式人生 > >計算機組成.就是它在運算.處理器CPU

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

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

處理器的組成與功能

先給一張處理器的概念圖,未必很嚴謹,而且各種處理器的實現方式也不盡相同,但基本的原理其實都在圖裡可以體現

處理器

組成

  • 大規模積體電路技術的發展,使得晶片的密集程度越來越高,處理器內部的各個結構甚至可以整合到一個半導體晶片上,體積那麼小所以稱為“微處理器”
  • 微處理器外觀上CPU有著密密麻麻的“針腳”,這些針腳就是用來資料傳輸的,一般一個針腳傳送1位的資料,大概是根據有電沒電來判斷1或0?

CPU

  • 內部是矽晶片,上面有數以百萬計的電晶體。由電晶體就可以構成基本的閘電路結構,進一步構成ALU等等基本的元件,再進一步就組成了CPU。
  • 針腳
    • 電源針腳VCC和接地針腳GND,除此之外的針腳都用於訊號傳輸
    • 資料匯流排DB(Data Bus)針腳,用於傳輸資料
    • 地址匯流排AD(Address Bus)針腳,用於傳輸地址
      • 也有通過匯流排複用技術,讓資料和地址共用一套匯流排,也就是這些針腳既可以傳輸資料也可以傳輸地址,用時序訊號來控制當前的是資料還是地址
    • 控制匯流排CB(Control Bus)針腳,用於傳輸各種控制訊號,常見的有
      • 時鐘訊號CLK
      • 復位Reset
      • 匯流排請求HRQ
      • 匯流排允許HLDA
      • 讀RD
      • 寫WR
      • ……
  • 根據馮諾依曼的模型,計算機的基本組成是
    • CU控制單元、ALU運算器、儲存器、輸入單元、輸出單元
  • 在實現的時候通常把CU和ALU整合在一起構成PU(Processing Unit),PU也被稱為“處理器”(Processo)
    • 通常計算機只擁有一個PU,而PU又作為計算機的核心部件,所以又被稱為CPU(Central Processing Unit)中央處理器
    • PU由ALU、CU以及一些暫存單元暫存器Register組成
    • ALU的內部有不同的電路可以完成不同的運算
      • 加法器完成算數運算
      • 邏輯運算器完成邏輯運算
      • 移位器完成移位運算
      • 求補器完成取反運算
    • CU是控制單元,作用是接受指令並進行譯碼,生成微程式來控制CPU內的各個部件那個需要工作那個不需要工作,來完成指令的執行;其實就是一個能讀懂指令並可以指揮處理器的各個部件來完成這條指令的指揮重心。基本組成如下
      • 程式計數器PC,用於存放下一跳指令的地址
      • 當前指令暫存器IR
      • 指令譯碼器ID
      • 控制訊號發生器CSG
    • 暫存器Register一般分為
      • 存放資料的資料暫存器
      • 存放地址的地址暫存器
      • 存放各種標誌的標誌暫存器FR(Flag Register)
        • 零標誌ZF(Zero Flag),1表示運算結果為零
        • 符號表示SF(Sign Flag),1表示運算結果為負
        • 奇偶標誌PF(Parity Flag),1表示運算結果中1的個數為偶
        • 進位標誌CF(Carry Flag)
        • 溢位標誌OF(Overflow Flag)
        • ……
  • 然而暫存器只能儲存很少量的資料用來輔助處理器的運算,真正的資料都存在主存裡,主存對應馮諾依曼模型中的儲存器,所以處理器與主存之間的資料交換是十分頻繁的。
    • 處理器訪問一次主存,無論是從主存讀取資料還是往主存寫入資料,都稱為一次“訪存”
    • 訪存地址暫存器MAR(Memory Access Register)
    • 交換資料暫存器MDR(Memory Access Register),也有稱為MBR(Memory Buffer Register),大概是覺得的MAR和MBR比較順口吧…
      • 讀取:把主存地址寫入MAR,啟動讀命令,目標資料就會從主存的相應位置傳輸到MDR中
      • 寫入:把主存地址寫入MAR,把資料寫入MDR,啟動寫命令,目標資料就會從MDR寫入到主存的相應位置
    • 注意MAR和MDR是“使用者(彙編程式設計師)透明的暫存器”,也就是沒有一條指令可以讀寫MAR。實際上你寫一條從主存取資料的指令,就需要主存地址作為運算元,而這條指令的執行就需要把主存的地址寫入MAR中才能完成訪存操作。這都隱藏在指令中而不需要我們去操心

基本功能

  • 說起計算機來就是“算數”,好聽點叫運算,運算的中心又在CPU。而運算其實也會涉及到很多方面,資料從哪來、怎麼算、結果有哪些特性、算的二進位制是資料還是地址、結果存到哪裡去、運算有什麼含義、如何通過訊號來控制裝置……
    • 這一切都交給了指令的設計,即設計的指令需實現各種各樣功能的要求,之後由指令編寫的程式才可以真正的實現我們想要的功能
    • 指令一般只涉及一些可以有硬體直接來完成的最基本最基礎的功能,其餘更復雜的功能都是由若干指令來實現的,當然也可以設計一條指令處理複雜的功能,這也就加大了硬體的複雜度和難度。由此就有兩個指令集設計的方向,即精簡指令集RISC和複雜指令集CISC。之後會講
    • 處理器的功能就是不斷的執行一條條的指令,對於每一條指令,處理器一般分以下幾步
      • 取指令:根據PC的地址取出指令放入IR中,然後PC自加1
      • 分析指令,也叫指令譯碼:將IR的操作碼部分的取出送入指令譯碼器ID進行移碼,譯碼的結果就是發出相應的控制訊號來控制各個部件工作
      • 取運算元,即這條指令所用到的資料 :根據運算元的地址來獲取源運算元
      • 處理運算元 :運算元送入運算器並根據ID的譯碼結果進行相應的運算
      • 寫入資料,即處理好的結果存放到相應的位置:將結果寫入到指定的地址(可以是暫存器也可以是主存)
    • 以上五步不一定每條指令都需要執行,比如一個簡單的 mov ax,bx 只是將 bx暫存器 的資料送入 ax 而並不需要運算,也就不需要處理運算元

綜合視角

  • 處理器中的控制單元負責取指令並進行譯碼,以控制處理器中的各個部件來進行相應的操作,以完成指令的功能
  • 暫存器可以暫存各種資料,以幫助指令實現功能,且暫存器的讀取是最快的,要比每次都從主存取資料快得多
  • 運算器負責進行運算,即處理相應的運算元
  • MAR和MBR實現處理器與主存之間資料的交換,對彙編程式設計師透明,即我們不用管
  • 其他的元件
    • 中斷單元負責中斷的控制,中斷是提高處理器效率的手段之一
    • 再其他的我就不知道了,真正的處理器在設計的時候基本的這些器件都需要有,當然你有別的方法可以代替也不是不可以;而其他的器件也可以往上新增,以實現更多的功能。

處理器的指令集

什麼是指令

  • 簡言之就是人為設計的一種特殊的語言和計算機交流,計算機可以理解這種語言,人們用指令來指揮計算機完成人們希望完成的工作
  • 為什麼這種語言計算機可以理解呢?因為這是一種“人為的設計”,粗糙的講就是規定好了每一條指令下計算機應該做那些事,這樣不就相當於理解了嗎
  • 計算機指令Instruction
  • 實際上一條指令更像一個函式,有的指令需要傳入運算元,有的指令不需要運算元,根據運算元的數值、種類等等這條指令有會有一些不同的動作
  • 所有的指令的集合稱為“指令集”(Instruction Set)或“指令集體系結構”(Instruction Set Architecture,ISA)。

    • 一種處理器肯定是聽不懂其他不同種處理器的指令,所以指令集的概念也對應著某種指令集,比如經典的8086處理器的指令集,通常作為組合語言的入門
    • 這也就是說,組合語言在不同的處理器上是不同的
  • 這樣,指令集其實就是這臺計算機的邏輯表示,簡單說就是指令集指明瞭這臺計算機所有的功能

    • 指令功能直接反應了計算機的功能
      • 如果一個計算機不支援浮點數運算,那麼你即使按照浮點數的格式儲存了也沒用,因為ALU的運算的邏輯電路根本沒法實現浮點數的運算
    • 指令功能決定了計算機的可程式設計性
      • 像乘除這種複雜的操作,如果有一條乘指令那麼對於程式設計就很容易了,否則恐怕就需要用移位、加減來實現,此時最好就是作為子程式來實現了
    • 指令包含的操作,直接決定(體現)了ALU的規模與組成
      • 也好比乘除,如果直接用硬體實現了乘除法,也就是ALU中有一個乘法器、除法器,那麼指令也就可以有一條指令來實現乘除運算;如果想用一條指令實現乘除法,那麼ALU中也應當設有用來進行乘除運算的乘法器、除法器

指令的基本格式與功能

  • 指令的格式通常為“指令操作碼”(Operation Code)加“指令運算元”(Operand)

指令的一般格式

  • 指令操作碼是一個二進位制的碼點,不同的二進位制也就是不同的01串就代表著不同的指令,對應著不同的功能。

    • 所以01串的操作碼又叫“機器碼”,因為只有機器才能直接識別二進位制,而我們雖然設計了“機器碼”,但01串本身並不包含指令的意思,對於我們來講還只是一串01而已,儘管我們可以通過對應關係來找到某串01的操作碼是何種功能
    • 而組合語言這種指令對人來說更好理解,因為已經是英文字母了,而且通常是某個單詞的簡寫,但機器是無法直接識別字母的。所以組合語言還需要進一步被翻譯成機器碼
  • 運算元就是這條指令所需要處理的資料,可以沒有,也可以多個,這要看指令集是如何設計的

    • 指令的格式主要涉及到
    • 操作碼的長度
    • 地址制和定址方式
    • 指令的長度
  • 操作碼的長度
    • 定長:簡化譯碼的實現,但指令的數量受限較大
    • 不定長:常用指令設計得比較短,不常用的設計的長,一般採用擴充套件操作碼的方式來實現,比如
      • 最短操作碼為4位,則對只對0000至1110設定為指令
      • 1111則表示,當前操作碼不止前4位,若再擴充套件4位,則有更長一級的操作碼分別是1111 0000 到 1111 1111
      • 以此類推
  • 地址制
    • 即一條指令中要處理多少個運算元
      • 對於不定長操作碼,操作碼越短,可處理的運算元越多,或者容納單個運算元的位數越多(當作為地址也就意味著定址範圍越大)
  • 定址方式
    • 同一條指令比如mov,機器要如何判斷所給的運算元是代表地址還是立即數還是暫存器呢?
    • 一般書寫的時候都有格式的規定,比如立即數就是數值,地址就要放在”[]”中
    • 編譯的時候根據運算元的定址方式的不同,即使是相同的指令比如都是mov,也會譯成不同的二進位制程式碼,從而區分資料的定址方式
  • 指令的長度
    • 一般都是位元組的整數倍,按位算的話就是8的整數倍,這樣方便計算機處理。
    • 且在設計的時候儘量避免跨位元組的設計,比如一個運算元的前n位在位於一個位元組的後n位,而運算元的後m位就位於下一個位元組的前m位了,這樣一個運算元跨了兩個位元組,硬體處理起來會比較麻煩

定址方式

  • 定址分為指令定址和資料定址。首先要從記憶體中獲取指令,之後再根據每條指令需要用到哪些運算元,再去考慮如何獲取運算元

指令定址

  • 指令定址比較簡單

    • 順序定址:通常一段程式由順序儲存的指令組成,一條指令和下一條指令的實體地址是連續的,那麼只要在根據PC(程式計數器,儲存下一條指令的地址)獲取了下條指令後,PC要自加以指向下一條指令
    • 跳躍定址:通常一段程式又不完全是連續的,比如分支指令下就會跳過某些指令,呼叫子程式的話就需要轉到子程式所在的實體地址,這都是根據跳轉指令來修改PC的內容,使PC指向相應地址的指令來實現跳轉。
  • 資料定址就是說,如何去獲取指令所需要的資料,因為如果資料是存在主存那麼就需要主存的地址,如果是存在暫存器那就需要指明是那個暫存器

    • 立即數定址:即我的運算元就是我要處理的資料,那麼就不需要到別的地方去取了
    • 直接定址:即我的運算元是資料所在的主存地址,這就需要根據主存地址去訪問主存才能得到資料,但這種方式使得給出的主存地址的長度收到指令長度的限制
    • 間接定址:即我的運算元是一個主存地址,這個地址對應的資料是另外一個地址,而此時這個地址下的資料才是我要處理的資料,類似於指標的概念,這樣就擺脫了直接定址的長度限制,因為我資料所在的主存地址是存在主存裡面的
    • 暫存器定址:即我的運算元存在暫存器裡面,也就是已經在CPU裡面了,只不過還需要進一步確認是那個暫存器,所以需要對CPU裡的暫存器進行編址,比如32個暫存器就需要5位的二進位制來編址
    • 暫存器間接定址:即我的運算元的主存地址存在暫存器裡,還是需要訪存才能獲取真正的資料,但是可以修改暫存器的內容,這樣用相同的指令(還是那個暫存器嘛)就可以處理不同的資料(但是暫存器的內容變了)
    • 基址定址:涉及到“邏輯地址”和“實體地址”的概念
      • 邏輯地址:即程式段/資料段都是從零開始編址的,以程式段為例,對於一行行的指令所組成的程式,每一條指令對應的地址都是相對於程式起始位置的距離,比如第一條指令的邏輯地址為0000,第二條指令邏輯地址為0001等等。即使是不同的兩段程式,其程式的邏輯地址也都是從零開始
      • 實體地址:是我的每一條指令存在主存裡時,我這條指令在主存的儲存位置(也就是相對於主存第一個儲存單元的位置),對於不同的兩段程式,其肯定是儲存在主存的不同的位置,實體地址必然不同
      • 那麼我們要訪存自然就需要的是主存地址也就是實體地址,通過邏輯地址的概念我們可以知道,以程式段為例,如果我們知道了程式段的起始實體地址,那麼對於每條指令而言,其實體地址就等於起始地址加邏輯地址,起始地址也成為基地址,即基址
      • 通常我們用暫存器把基址存下來,即基址暫存器,在指令中只給出邏輯地址,執行的時候需要把邏輯地址和基址相加得出實體地址才能訪問來獲得資料。
      • 優點就是資料的邏輯地址的計算很方便,對於編譯器實現起來也要簡單得多
    • 變址定址:通常對於陣列、向量等資料結構我們習慣通過下標來訪問,就像在C語言中陣列名錶示陣列的首地址一樣,我們在指令中就把陣列名顯式地給出,把下標存到一個特定的暫存器——變址暫存器中,指令執行的時候就把陣列名所代表的陣列首地址和變址暫存器的下標相加得到實體地址來獲取資料。只需要改變變址暫存器的內容就可以輕易的遍歷陣列或實現隨機訪問
      • 堆疊定址:前提是處理器支援堆疊資料結構,即有一個堆疊是由處理器自身來維護的,並配有“堆疊指標暫存器SP”指向棧頂。堆疊的操作一般就是“PUSH A”表示把儲存單元A的內容入棧,SP邏輯上增1;“POP A”則是將棧頂內容出棧到儲存單元A中,SP邏輯上減1。
        • 之所以說SP“邏輯”上的增減,是由於棧的實現由兩種,不過一般都是基於主存實現的棧,即棧的內容是儲存到主存的,只不過這部分的資料只能通過PUSH和POP才能訪問到
        • 遞增堆疊,即入棧導致SP內容(地址)增加,棧底的地址最小
        • 遞減堆疊,即入棧導致SP內容(地址)減小,棧底的地址最大

指令集的設計

綜合分析計算機的功能,指令集的設計一般要實現一下五大部分的功能

  • 算數/邏輯/移位指令,簡稱算邏指令(難聽的簡稱)
    • 算數
      • 定點加ADD、減SUB、乘MUL、除DIV
      • 浮點加ADDF、減SUBF、乘MULF、除DIVF
      • 自增1指令INC、自減1指令DEC
      • 比較CMP
      • ……
    • 邏輯
      • 與AND、或OR、非NOT、異或XOR
      • 有的還有“位測試”、“位清除”、“位求反”
      • ……
    • 移位
      • 算術移位
      • 邏輯移位
      • 迴圈移位
      • ……
    • 注意各種運算的結果會對標誌暫存器的標誌位產生影響,如溢位標誌OF會在運算結果有溢位的情況下被置為1否則置為0,進位標誌CF會在運算結果有進位產生的情況下置為1否則置為0,等等其他標誌位,
    • 通過這些標誌位可以方便的判斷運算的情況,比如零標誌位ZF通常用於比較兩個數是否相等,即讓兩數相減看結果是否為零,也就是看ZF是否為1
  • 資料傳送指令,簡稱數傳指令(有過之而無不及的難聽)
    • 一般傳送指令,如mov,實現資料的複製,有些計算機採用LOAD/STORE風格的指令來實現資料的傳送,這種風格會給指令集的設計帶來別樣的好處
    • 堆疊傳送指令,即PUSH和POP,用於維護堆疊
    • 資料交換指令,即交換兩個儲存單元的資料,一般需要第三方的介入作為暫存,執行時間也會因此比較長,其實完全可以由以上兩種指令來實現資料的交換,不過資料交換用的比較多,設計成為一條指令來實現顯然是收益大於損失的
  • 控制轉移指令
    • 跳轉JUMP,直接改變PC的值實現跳轉
    • 分支指令BRANCH,根據條件來決定程式的走向,即類似“ if 語句1 else 語句2”的邏輯,是繼續順序執行(即語句1)還是要做跳轉(語句2)。
      • 條件往往是上一次運算的結果,也就是標誌位
      • 為0轉移指令,不為零轉移指令等等等等,指令內部其實就是根據標誌位來判斷是否要轉移,比如為0轉移指令就看標誌位ZF是不是1這樣
    • 子程式呼叫指令 “CALL 子程式名”
      • 第一步把PC的值儲存到堆疊中,因為還要返回嘛
      • 第二步根據子程式名來求得子程式的入口地址
      • 第三步把入口地址寫入PC,繼續執行的話下條指令也就是從獲取的子程式的指令了
        • 子程式在結束的時候會有一個返回的指令,作用是從堆疊中取出棧頂(PC)的值恢復到PC中,這樣也就是返回了
        • 子程式內部如果有對堆疊的操作,則一定要保證子程式返回的時候棧頂的值是最初進入子程式前壓入的PC的值,這樣才能正確返回,否則程式就會崩潰掉
  • 輸入/輸出指令
    • 主要是為了完成主存與外設之前資訊交換的操作
      • 啟動I/O裝置
      • 停止I/O裝置
      • 測試I/O裝置
      • 資料的I/O傳輸
  • 處理器控制及除錯指令
    • 除錯指令、停機指令、特權指令、各種置/清除標誌位指令…
    • 對於面向多使用者系統的處理器,處理器的狀態又被分為“核心態”和“使用者態”,即作業系統核心提供一些功能讓使用者程式可以呼叫,使用者程式若要使用這些功能則需要“訪管指令”來把處理器交給作業系統來實現相應的功能
      • 一方面防止使用者程式進行非法的操作如修改系統檔案,這類操作都是有作業系統維護;
      • 另一方面利用作業系統提供的功能也給程式的編寫帶來了便利
    • 此外還有空操作NOP,等待指令WAIT

CISC與RISC

  • 複雜指令集計算機CISC(Complex Instruction Set Computer)
    • 即在指令集的設計的時候不斷新增新的功能複雜的指令,使得一條指令可以實現原先複雜的功能,同時這也對處理器的設計提出了更高的要求,硬體的複雜度越來越高,但對編譯器的開發卻十分有利。
    • 至今只有Intel及其相容CPU還在使用CISC
  • 精簡指令集計算機RISC(Reduced Instruction Set Computer)
    • 即在指令集的設計的時候不斷去除功能複雜的指令,複雜的功能通過最基礎的指令來編寫成子程式來實現,對硬體要求不高,但對編譯器有很高的要求
    • CISC中雖然有著眾多的指令,但實際上一個典型程式用到的80%的指令,只佔指令集的20%,這樣眾多功能複雜的指令並沒有很高的使用頻率,卻不得不加大了硬體設計的複雜度,似乎有點得不償失了
    • 典型如Apple公司的Macintosh是基於RISC體系結構
  • 進一步區別
    • CISC由於指令數目的眾多,必然是不等長指令集,處理器相應起來的速度就相對於 RISC的等長指令集 要慢
    • RISC處理器製造工藝簡單,成本低,次品率也低
    • CISC則執行著Dos、Windows這種家喻戶曉的作業系統,擁有大量的應用程式,龐大的市場,65%以上的軟體廠商都在為CISC體系的PC服務,Microsoft就是其中之一
    • 相對來說RISC則顯得有些勢力單薄
    • 不過最優的方案往往是兩種極端的融合,目前也正逐漸呈現這種趨勢,一般核心是基於RISC,而遇到CISC的指令又可以將其分解成為RISC的指令來處理

流水線技術

流水線原理

  • 十分類似工廠裡的流水線生產,對於一條指令,我們至少可以劃分為“取指令”、“分析指令”和“執行指令”三部分,那麼指令的處理也就可以按流水線的方式來進行
  • 當然這種重疊進行的要求是,每個小部分之間的資源不衝突,或者有足夠的資源來分配
    • 假如兩個部分都需要用到ALU的話,而且若ALU只有一個,那麼很顯然這兩部分是不可能同時進行的
  • 流水線的方式實際上也就實現了指令的重疊

基本流水線

  • 這就要去對於指令的劃分,要同時執行的兩個部分的時間就需要控制成相等的時間,這也就需要一個同步的問題,通常執行時間會比較長,即使指令i+1的分析部分和指令i+2的取指部分已經執行完了,但仍然需要等待指令i的執行部分結束後,才可以進一步進行
  • 設一條完整的指令執行完畢所需要的時間為 T
    • 則對於指令的每個部分來說就要花費的時間為 t = (1/3)*T
    • 從流水線的角度來看,也就是每隔 t 時間就可以執行完一條指令
    • 若不採用流水線,則需要每隔 3t = T 的時間才可以執行完一條指令
      • 當然由於同步的需要,每部分的執行時間原本不同,比如取指需要時間為 n,分析需要 n,而執行通常花費時間比較長,設為 2n的話
        • 若不採用流水線,則是每隔 4n 的時間完成一條指令
        • 若採用流水線,由於同步的需求,取指和分析也需要花費 2n 的時間,但從流水線上來看,便是每隔 2n 的時間就完成一條指令,獲得的效益很明顯
    • 也就是說,流水線的效率與指令的細分相關
  • 一個很顯然的優化策略就是,進一步細分每條指令
    • 如執行部分可進一步分為“取運算元”和“執行”兩部分,那麼相對來說就是降低了“最大花費時間”的部分的花費時間
      • 若取運算元和執行分別只需要 n 的時間
      • 流水線上就會每隔 n 的時間完成了一條指令
  • 流水線的原理除了可以應用在指令上,也可以應用在運算上
    • 如浮點數加法,運算過程自然的分為了“求階差”、“對階”、“尾數相加”、“規格化”四部分
    • 這四部分可以分別由獨立的部件完成,以保證不會衝突而可以並行
    • 如此稱為“浮點數加法流水線”
    • 流水線也常用時空圖來描述

浮點加法流水線

浮點加法流水線時空圖

流水線的分類

  • 不太想講、簡單一說吧、沒什麼意思
  • 瞭解基本原理的基礎上、自然也可以進一步的有多種變化與實現形式

功能分類

  • 單功能流水線:只為某種特定的功能而設計,只設計到這種功能所需要的部件,也只能對這種特定的操作進行流水線化處理
  • 多功能流水線:即其涉及到眾多的部件,對於某種功能而言,就只利用其中的某些部件來對其進行流水線處理,眾多的部件也使得其可以滿足多種功能的流水化

連線方式分類

  • 靜態流水線:即在某一時段內,只能按照一種功能的流水化操作進行。儘管可能這種功能只涉及到了部分的部件,而其餘的部件仍可以滿足另外一種功能的流水化,也必須等到前者退出流水線後,後者才能進去。也就是所謂的靜態
  • 動態流水線:即在同時一段內,如果兩種功能設計的部件不重疊的話,那麼就可以同時進行流水化的處理。但其控制變得極為複雜,這使得這種方式代價太大,因此大多數流水線都是靜態流水線

其他

  • 部件級流水線:也叫運算操作流水線,即對算術邏輯運算進行流水化,比如浮點加法
  • 處理器級流水線:也叫指令流水線,也就是之前分析的對指令進行細分以流水化處理的方式
  • 處理器間流水線:也叫巨集流水線,即由多個處理器串聯來流水化作業

  • 標量流水和向量流水

  • 線性流水和非線性流水

效能評價

  • 以五個流水段為例

流水線的效能評價

  • 建立時間 Te:第一個任務從進入到完成的時間,經過 Te 後才能達到完全流水化
    • Te = 5 * ∆ t
  • 排空時間 Td:最後一個任務從進入(完成第一部分才叫進入)到完成的時間,經過 Td 後流水線才能排空,進入空閒狀態
    • Td = 4 * ∆ t
  • 總時間T:就是總時間
    • T= Te + (N-1) * ∆ t = Td + N * ∆ t = N * ∆ t + ( M - 1) * ∆ t
  • 加速比Sp:序列處理的話所花費的時間與流水化處理所花費時間的比率,意味著我們的流水線技術可以提高的效率
    • Sp = N * M * ∆ t / T = N * M * ∆ t / ( N * ∆ t + (M-1) * ∆ t )
    • Sp = M / [ 1+(M-1)/N ]
  • 吞吐量Tp:單位時間流水線完成的任務數量
    • Tp = N / T = 1 / { ∆ t * [ 1+(M-1)/N ] }
    • Tp = (1/∆ t) / [1 + (M-1)/N]
  • 最大吞吐率Tp_max:即在完全流水化的狀態下的吞吐率,此時每隔∆ t就有一個任務完成
    • Tp_max = 1 / ∆ t
  • 效率E:指流水線的裝置利用率,從時空圖上看。即在總時間T內,N個任務所佔用的區域與總的區域的比值。
    • 顯然空出來的區域就是用在建立和排空上,因為在這兩部分時間裡流水線並不是所有的裝置都在使用
    • E = (M * N * ∆ t) / (M * T) = N / [ N+(M-1) ]
    • E = Tp * ∆ t

指令間的相關

  • 之前有提到,流水線的基礎就是,細分指令的每個部分之間互相獨立,互不相關
  • 但是這麼苛刻的條件顯然是不可能達到的,指令的條數眾多,實現的功能眾多,很難保證所有的指令之間都不相關
  • 最最基本的方法就是“暫停流水線”,即如果產生相關則暫停後續指令的執行,直到相關性消失之後再繼續流水化作業。

    • 當然這是我們最不喜歡的解決方案,因為這是從 “根本”上來解決,因為衝突是由於流水而引起,暫停流水也就消除了衝突,但也就意味著暫停期間流水是不起作用的,無法得到效率的提高
  • 結構相關:即對硬體資源的需求衝突,可能是競爭同一個資源,也可能是資源不夠分配。主要表現是訪問主存,以取指的訪存與其他訪存衝突為例

    • 交叉訪問儲存器、哈佛結構儲存器、多埠儲存器
      • 從儲存器本身上下手,解決衝突問題,具體可百度
    • 處理器內設“先行指令預取緩衝佇列”
      • 即把指令先都取到一個緩衝佇列裡,之後的取指都從佇列裡去,也就不必訪問主存,就避免了衝突
    • 定長指令集、指令和資料在儲存器中“對齊”存放
      • 這都是方便了訪存,以保證取指可以在一個儲存週期內完成
    • Load/Store 風格
      • 這個風格還記得嗎?在這種風格中,只有Load和Store指令可以訪存,其餘的都是針對暫存器而無須訪存,這樣就降低了衝突概率
  • 資料相關:後一條指令需要用到前一條指令的結果,那麼在流水線中就有可能產生無法重疊執行的情況,即我後一條指令需要取運算元,但因為前一條指令還沒有執行完,結果還沒算出來,這就十分尷尬了
    • 通常可以暫停執行,或有硬體實現,或有編譯器插入空操作指令來實現,保證指令取運算元的時候都能取到
    • 另外也有“資料旁路”的方法,基本思想就是一旦ALU算出了結果,就通過一條專用的傳輸線直接送到後續指令處;從ALU的角度來看,就是從運算結果SUM直接回到了輸入緩衝A或B中
    • 資料旁路
  • 控制相關:當流水線遇到分支指令的時候,,,,,,分支的結果是要選擇下一條要執行那條指令,,,,,,既然分支結果還沒出來,那麼我怎麼知道並行執行的下一條指令是不是正確的指令呢??尷尬尷尬
    • 肯定也可以暫停知道分支結果出來知乎,再繼續流水正確的指令唄
    • 再就是猜嘍,猜對最好,猜錯的話就需要撤銷之前的操作,並按照猜測結果去取正確的指令
      • 轉移成功就是需要跳轉,不成功就是不需要跳轉
      • 不同的猜測邏輯也有影響,因為轉移的成功與否的分佈於實際的程式有關,而不完全是隨機分佈的,比如迴圈的時候,迴圈操作內會“轉移成功”,而只有退出迴圈的時候才會“轉移不成功”
    • 再就是硬體加速,讓分支指令的結果可以儘早生成

指令級並行

何為指令的並行

  • 所謂指令級的並行,就是“如果指令之間不相關,那麼在流水線中就可以並行執行”
  • 流水線的思想應用到指令上就是指令級並行;不過流水線只是一種思想,不僅僅可以用在指令上,還可以用在運算上等等
  • 指令級並行Instruction-level parallelism,ILP

指令相關的進一步分析

  • 資料相關
    • 定義比較狹窄,僅指“先寫後讀”,即前一條指令寫入的內容後一條指令需要讀取
  • 名相關
    • 稱指令用到的暫存器或儲存器為“名”
    • “先讀後寫”:前一條指令需要讀取某個“名”中的資料,後一條指令需要向此“名”中寫入,則這兩條指令的順序必須保證
    • “先寫後寫”:即兩條指令都往同一個“名”中寫入資料,其順序也是不能改變的
    • 稱之為“名相關“,就是因為這種衝突是由於使用了相同的“名”,而實際上兩條指令之間可以不用相同“名”而同樣可以完成操作
      • 如先讀後寫中,改變後一條指令的名,讓它寫入別的地方就可以了啊,再往後的指令如果需要後一條指令的資料的話,那它的讀取的名也跟著更改就是了
  • 控制相關
    • 依舊是分支指令惹的禍
    • 兩條原則
      • 與控制相關的指令不能移到分支之前:因為這些指令需要分支的結果來判斷選擇那條進行
      • 與控制無關的指令不能移到分支之後:因為分支會導致某些指令不需要執行,而與它無關的指令本應當不受分支指令的約束的

如此一來,在考慮指令並行的時候,處理器的CPI(平均指令週期數)就等於理想的CPI加上各種相關導致的停頓

CPI=CPI+CPI+CPI+CPI+CPI+CPI

並行相關技術

根據公式,提高每一項都可以提高最終的CPI流水線

  • 基本流水線排程
    • 如資料旁路就可以解決部分的資料相關
    • 基本的暫停方法確實可以避免相關,但同時也降低了並行性
  • 迴圈展開
    • 講多次的迴圈展開成顯示的指令形式,以開發迴圈體的並行性,減少暫停的時間
    • 解決控制相關
  • 暫存器換名
    • 解決名相關
  • 指令的動態排程
    • 這個比較複雜,不過可以解決各種相關的停頓
  • 前瞻
    • 在未判斷指令是否可以執行之前,就執行,允許指令亂序,但順序必須確認,同時把前瞻執行的指令、結果都標記為“未確認”,只有真正確認過的結果才算最終的結果
  • 多指令流出
    • 提高理想的CPI

指令的動態排程演算法

  • 首先說靜態排程,就是編譯器確認並分離出相關的指令,然後進行指令的排程,來消除或減少處理器的空轉
  • 所謂動態排程,就是通過硬體重新安排指令的執行順序,來調整相關的指令在執行時的關係,減少暫停的發生,並且可以處理編譯時未發現的相關

原理

  • 通常流水線內一條指令未處理完,則後續的相關指令會被阻塞,其後的所有指令也都無法進行
  • 動態排程將指令分為“取指”“譯碼”“取運算元”“執行”幾步
    • 譯碼:檢查是否存在結構相關
    • 取運算元:只要沒有資料相關,就可以讀取
      • 意味著允許指令的亂序執行
  • 所有指令在“譯碼”階段都屬順序的執行的,而在“取運算元”則允許亂序執行
  • 基本的演算法有
    • 記分牌演算法
    • Tomasulo演算法:結合記分牌與換名技術,關鍵概念“保留站”
  • 本質都是通過記錄的各個部件的資訊、指令執行的狀態等資訊,與部件之間通訊,來控制指令執行的每一步
    • 因為允許了指令亂序執行,所以可以很大程度減少處理器的暫停
    • 同時所有的狀態都在嚴密監控之下,各種約束條件保證了指令執行的結果是正確無誤的
  • 亂七八糟的內容,,,算是勉勉強強看過一遍吧,然近期還有很多別的事要處理

相關推薦

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

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

計算機組成原理(5)——中央處理器

處理器 序列 工作 5.1 編寫程序 控制器 操作 cache alt 五、中央處理器 5.1 cpu的功能和基本結構 5.1.1 cpu器的功能 當用計算機解決某個問題時我們首先必須為它編寫程序。程序是一個指令序列。這個序列明確告訴計算機應該執行什麽操作,唉什麽時

計算機組成與設計(4)-----處理器

思維導圖     前兩章中簡要概述了指令的形式及其作用,處理器的主要功能就是在規定的時間內處理指令.     處理器是如何處理指令的呢?從硬體結構上講,處理器有資料通路和控制器構成.其中,資料通路的主要功能是根據指令處理資料的流通,在此過程之中,會讀取或者寫入資料,也

計算機組成與設計3——處理器概述

處理器概述1資料通路:1.1概念:指令在執行過程中,資料所經過的路徑(包括路徑中的部件),是指令的執行部件。是由操作元件(組合邏輯單元)和儲存單元(狀態元件)通過匯流排方式或分散方式連線而成的進行資料儲存、處理、傳送的路徑。1.2資料通路的組成:1.2.1組合邏輯元件:加法器

計算機組成原理】流水線處理器

前言 流水線的想法源自於傳統工廠生產產品的方式,通過這種方式大大提高了生產效率,反應在CPU上就是提高了指令的吞吐率。 上篇文章介紹了單週期處理器,姑且算是揭開了CPU那層神祕的面紗。現在我們來深入瞭解一下,一個超標量流水線處理器是什麼樣的。 流水線的設計

程式設計必備基礎知識|計算機組成原理篇(09):CPU的控制器和運算器

計算機基礎方面的知識,對於一些非科班出身的同學來講,一直是他們心中的痛,而對於科班出身的同學,很多同學在工作之後,也意識到自身所學知識的不足與欠缺,想回頭補補基礎知識。關於計算機基礎的課程很多,內容繁雜,但無論是相關書籍還是大學課程,都有點脫離工作。特別地,計算機基礎知識體系龐雜,想要從零學習或者複習都耗時耗

計算機組成原理第五章之中央處理器CPU

中央處理器CPU 整個計算器所有部件都由控制器所控制,CPU集成了控制器和運算器。 資料和指令進出CPU都要先經過緩衝暫存器。指令暫存器用來存放當前正在執行的指令。PC用來存放下一條要執行的指令,地址暫存器存放CPU當前需要訪問的記憶體的地址。 程式執行之前,所有的指令都要先放入儲存器,

計算機組成原理--64位CPU裝載32位作業系統,的定址能力還是4GB嗎?

藉由這個問題,今天我們就把 32 位 CPU、64 位 CPU、32 位作業系統、64 位作業系統之間的區別與聯絡徹底搞清楚。對於這個問題,博主也是一知半解了好長時間啊~ 基本概念 32位的CPU與64位CPU 以下內容摘自維基百科: 64

計算機組成原理(4)-中央處理器CPU-時序訊號

時序產生器和控制方式 時序訊號:一個用來確定時段執行哪些微操作的標誌。就好比我們每天按時吃飯按時上學的時間的規定。 1.組成計算機硬體的器件特性決定了時序訊號最基本的體制是電位-脈衝制。 2.取指週期和執行週期發生了什麼? 從時間上來說,取指令事件發生在指令週期的第一

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

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

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

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

計算機組成CPU、內存、硬盤三者之間的關系

獨立 mage mat 截屏 大腦 -h 發送 被人 class 電腦之父——馮·諾伊曼 提出了組成計算機的五大部件:輸入設備、輸出設備、存儲器、運算器和控制器。 來看一下現在我們電腦的:鍵盤鼠標、顯示器、機箱、音響等等。 這裏顯示

計算機組成原理——匯流排補充:地址匯流排、資料匯流排、定址能力、字長及cpu位數等概念之間的關係

地址匯流排決定了CPU的定址能力;資料匯流排的寬度與字長及CPU位數一致。 詳細解釋見下文: 1.地址匯流排與定址能力 要存取資料或指令就要知道資料或指令存放的位置,地址暫存器儲存的就是CPU當前要存取的資料或指令的地址,該地址是由地址匯流排傳輸到地址暫存器上的。

計算機組成原理實驗2---單週期CPU

實驗目的 實驗內容 設計一個單週期CPU,該CPU至少能實現以下指令功能操作。 必須寫一段測試用的彙編程式,而且必須包含所要求的所有指令,slti指令必須檢查兩種情況:“小於”和“大於等於”;beq、bne:“不等”和“等”。這段彙編程式必須儘量優化且出現在實驗報告中,同時,給出每條指令

易學筆記-計算機底層-第1章:計算機系統漫遊/1.4 處理器處理記憶體中的指令/1.4.1 系統的硬體組成

系統的硬體組成 示意圖: 匯流排: 第6章 系統配置與效能評價/6.3 輸入輸出系統/6.3.2 匯流排 概念:電晶體,負責在各個部件間傳遞資訊 被設計成傳遞定長的位元組快,比如4個位元組或者8個位元組,也就是32位或者64位 I

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

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

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

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

計算機組成與設計(九)—— 流水線處理器

明顯 取出 pan -a decode mage 變量 事先 並行 流水線的基本原理 指令的主要執行步驟 這個是之前設計的單周期寄存器,它已經能正確的執行MIPS指令。 而MIPS的指令可以分成如下5個階段: 取指(Fetch)::從存儲器取指令,並更新P