流水線設計


20世紀80年代,流水線技術成為RISC處理器設計方法中最基本的技術之一,RISC的設計多以高流水為目標設計。

而后流水線技術也被應用到CISC處理器

 

在流水線的發展史上主要有兩種流水線,算術流水線和指令流水線。

首先通過算術流水線的例子,介紹流水線理想假設。

 

流水線意味着將系統分割為許多段,段與段之間增加合適的緩沖,這樣每隔D/K個時間單位就可以啟動新的任務,而不是每隔D個時間單位。

流水線並不能被無限制的增加下去,因為時鍾的限制(setup time/clock uncertainty),流水線的划分有一個物理局限。

流水線深度的權衡:

一個k級流水線的價格:C = G + k *L,原來非流水的價格+流水線段數×增加一級流水價格;

流水系統的性能:1/(T/k + S),T非流水系統的延時,S引入流水新加的延時,k級流水。

通過微分求解:可以得到一個流水線的最佳深度

                       

K<Kopt:不夠完全流水化,可以進一步增加流水,性能的提升比價格的提高更明顯;

K>Kopt:過度流水化,增加流水,價格的提升比性能的提升更明顯;

 

流水線操作中的硬件要求:

1):每一段進行控制和完成數據操作的邏輯;

2):支持多個流水段同時訪問的寄存器文件接口;

3):支持多個流水段訪問的存儲器接口;

隨着流水線深度的增加,流水線的硬件資源會顯著的增加,最突出的是寄存器文件和存儲器端口數目的增加。

目前流水線處理器的設計趨勢是向着更高的流水程度和更深的流水深度發展,這樣流水線級顆粒更小,時鍾頻率更高,目前超過10級的流水線很常見,

還有一個趨勢是多條級數不等的流水線。

 

流水化的理想假設:只有在理想情況下,流水線的吞吐量才能得到K倍;

1):一致的運算分量,要完成的整個運算量均勻的分成延遲一致的若干分量。

由於流水線的時鍾周期取決於延遲最長的那一段,所以各個流水段最好做平,來減少”內部碎片”,

並且,流水段之間的緩沖不會帶來額外的延遲(setup time),時鍾也不會引入額外的延遲(clock uncertainty)

2):重復的運算,輸入數據有大量相同的,重復的運算。

不同的功能流水段中,可能不需要一些特定的流水段,這些空閑的流水段”外部碎片”

各個流水段只有完全流水階段,不存在流水線填充階段。

3):獨立的運算,所有相同的運算之間沒有相關性。

后面的運算可能會用到之前運算的結果,當這兩條命令都在流水線中時,會產生等待狀態,”流水線停頓(pipeline stall)”

 

指令流水化設計:

一條指令的處理過程,流水化的運算,被划分為多個一致的子運算,獲得盡可能均衡的流水線。

處理一條指令的時間延遲:

指令周期-------體系結構原語,由指令集體系結構定義。

機器周期-------流水線的時鍾周期,機器原語,由處理器的微體系結構定義。

 

指令流水線設計的主要任務,將邏輯指令周期映射到物理機器周期,將指令周期合理的分割為一個子運算的序列,需要考慮:

1):一致的運算分量,量化流水段,盡可能的減少內部碎片,流水線越均衡,內部碎片越少。

2):重復的運算,指令流水線天生就是多功能流水線,對應的子運算序列不同,硬件資源不同,

            連接或者整合不同指令類型對不同資源的需求。盡量減少無效或者空閑的機器周期。

3):獨立的運算,盡量減少流水線停頓。

 

指令集體系結構對流水線的影響:

1):一致的運算分量,在流水線設計中,關鍵分量是對存儲器的訪問,采用cache訪問。典型6級流水設計

2):重復的計算,RISC體系結構的主要目的之一,降低指令類型的復雜性和多樣性,可以降低整理不同指令類型的難度。主要分為三種指令類型

3):寄存器相關比較容易檢測,可以由編譯器靜態完成,或者運行時硬件動態完成,存儲器相關比較難判斷。

 

保持流水段均衡:

一個典型的指令周期,可以划分為:

1):取指(IF,Instruction Fetch)

2):譯碼(ID,Instruction Decode)

3):取操作數(OF,Operand Fetch)

4):執行(EX,Instruction execution)

5):存儲(OS,Operand Store)

分割指令周期的很自然的方法是按5個基本運算分量來划分,得到一個5級指令流水線,稱為基本指令流水線GNR(generic)流水線。

其中邏輯指令周期映射到5個物理機器周期中,這個值反映了流水化的程度和顆粒。

 

在量化流水線中,可以根據實際分量的大小,進行合並和再分解。從而增大流水度和減小流水度。或者可以將合並與分解結合使用。

不管在哪種情況下,目的都是為了減小內部碎片。

 

統一指令類型:

指令流水線需要滿足不同的需求,必須提供所有指令類型所需要的所有運算分量。

對於單獨一種指令類型,不需要的流水段將成為某種形式的失效和開銷,稱為外部碎片。

要完成一次運算,計算機必須完成三個基本任務:

1):算術操作,ALU部分,執行算術和邏輯運算

2):數據移動,將操作數和結果在存儲地址之間進行移動

3):指令定序,由指令自身來確定

CISC指令集多采用,一條指令都能完成一條以上的基本任務。

在現代RISC體系結構中,指令集采用一種專門的指令類型來完成三個基本任務中的一個,定長正交指令,load/store體系結構和簡單尋址模式。

其中指令可以分為三種類型:(包括無條件跳轉指令和條件跳轉指令,定點指令和浮點指令)

ALU:算術和邏輯運算

Load/Store:數據在寄存器和存儲器間移動,選擇簡單尋址模式,帶偏移的寄存器間接尋址模式。

分支指令:控制指令執行的順序,尋址模式支持PC相對尋址。

Load/Store之間也有微小區別:load指令,OF可以新分為讀寄存器得基址,有效地址生成,存儲器訪問

                           Store指令,OS可以分為有效地址生成,寄存器操作數寫入存儲器

 

資源需求的整合:

盡量提高流水線中所有資源的利用率,合理分配各個流水段的資源,減少各個指令類型帶來的空閑周期。

針對四種指令(ALU, Load/Store, jump)進行功能划分:

1):所有四種指令有相同的IF和ID分量,完成取指和譯碼操作;

2):所有四種指令的OF分量都要讀寄存器文件,ALU訪問寄存器操作數,load得到基地址,store得到操作數和基地址,jump訪問PC寄存器

RD段從寄存器文件中讀取最多兩個寄存器操作數,所以寄存器文件在每個時鍾都必須支持兩個獨立的並行讀操作。

3):ALU完成算術邏輯運算,load/store/jump完成有效地址生成。

4):Load/store訪問存儲器,流水線第五段,MEM

5):ALU和load都要向寄存器文件寫入結果,為了統一,在ALU執行完后,不直接向寄存器寫入,和load一樣在流水線第六段寫入。

ALU在MEM段后,產生一個空閑周期,外部碎片

6):對於條件分支指令,必須在更新程序計數器之前,確定分支條件,所以最早能用分支目標地址更新程序計數器的段是MEM

 

以上是一個TYP的指令流水線,ALU有一個空閑周期(MEM),store和jump沒有WB段,只有load指令用了其中6個流水段,這是一條效率比較高的流水線了。

在這個指令流水線的實現過程中,每個時鍾周期最多有6條指令會駐留在流水線中,所以一個機器時鍾,I-Cache需要支持一次讀操作,D-cache需要支持一次讀操作

和一次寫操作。

 

減少流水線停頓。

兩條指令之間的關系可以分為:數據相關和控制相關,數據相關分為;

數據相關即可以發生在存儲器中也可以發生在寄存器中。

1):先寫后讀,(RAW,read after write),后一指令的操作數是該指令的結果。該指令的結果被后指令使用。真相關。

2):先讀后寫,(WAR,write after read),反相關,防止后一指令的結果對上一指令的操作數產生影響。

3):寫后寫,(WAW,write after write),兩條指令的順序不能改變。輸出相關。

4):讀后讀,(RAR,read after read),無影響。

在以上的TYP的6級流水線中,可以發生的數據相關,是RAW相關。

要化解RAW相關,就要阻止后續的指令進入讀相關寄存器的流水段中。知道前面的指令通過了相關寄存器的流水段。

除了停止執行發生相關的指令,還有一些更加有效的方法:

1):采用定向路徑。前面的指令i與后面的指令j存在相關,對於RAW相關,指令j需要指令i的結果,則在指令i結束ALU之后,

ALU的輸出可以通過一段物理的定向路徑(Forwarding path)到達ALU的輸入端,這樣j指令執行時,可以直接使用,而不用等到i指令到達WB。

              如果指令i是load指令,指令j需要的數據需要在MEM段,也可以再增加一條定向路徑。

 

ALU指令引起的RAW相關,稱為ALU開銷。Load指令的開銷稱為load開銷。從MEM段和WB段到ALU的輸入的路徑稱為定向路徑。

2):流水線互鎖實現。檢測出所有的流水線相關,並保證所有的相關得到滿足。包括停止流水線的某一段,以及,數據在定向路徑中的傳輸控制。

RAW相關的檢測是通過比較器,連續比較連續兩條指令的寄存器標識來實現的。如果檢測到數據的相關性,則使能相關的定向路徑。

如果沒有相關的定向路徑,則停止流水線的某段。

流水線的互鎖硬件還必須處理控制相關引起的流水線相關。

 

流水線處理器性能的主要障礙是指令相關引起的流水線停頓,其中控制相關引起的分支開銷是最重要的部分。

動態分支預測能減少這一部分的開銷,預測成功時,流水線沒有停頓。在檢測到預測失敗時,必須清空流水線。

減少從取指段到完成分支指令段的距離也可以減少分支指令引起的開銷。

 

在流水線處理器設計中,不僅僅數據通道被流水化了,連控制通道也被流水化了,傳統的數據通道和控制通道被合並到同一條流水線。

 

標量流水線的局限性:

1):標量流水線的最大吞吐率不會超過每周期一條指令。

2):將不同類型的指令放在同一條流水線中處理,效率低下。

3):為了保證流水線的步調一致而插入停頓,使流水線產生很多氣泡。

 

為了提高處理器的IPC,需要同一周期啟動多條指令執行的方案,需要增加流水線的寬度,稱為並行流水線

在典型的TYP6級流水中,IF,ID,RD執行相同的指令,但是ALU和MEM端卻不盡相同。如浮點指令和部分定點指令,訪存指令的延時等,

不同指令需要的資源和硬件性能都不同,使得流水線的執行階段更難統一,為了解決這一局限性,在流水線的執行階段,為不同的指令提供了不同的執行部件,

這樣的流水線叫做多配置流水線

標量流水線是嚴格按順序執行的,所有指令同步流動,且不會打斷指令的原始順序,某段的停頓會導致它之后所有段的停頓。如果多條指令可以繞過停頓的流水段,

則可以減少多個周期的開銷,這種允許后續指令繞過停頓指令的技術稱為指令的亂序執行。支持指令亂序的並行流水線稱為動態流水線

 

並行流水線,同一時刻可以同時處理的最大指令數來衡量,程度相同的時間並行和空間並行理論上可以獲得相同的加速比,

但是時間並行更加節省硬件,空間並行需要重復配置多個處理單元。如下的流水線,需要雙端口的寄存器,雙端口的cache,兩套ALU。

多配置流水線,並行流水線在執行段配置了多個功能部件,並形成了多條流水線。多配置流水線,每條流水線只執行一種指令,

進行專門的優化設計並采用高效的硬件,來提高流水線效率,在進入分派之前就可以解決所有不同類型的指令相關,

這樣可以把相關控制的復雜度控制在各條流水線中。

超標量流水線,如增加浮點流水線,乘法,除法,圖形圖像,信號處理的操作。

 

動態流水線

如圖是一個發射寬度是3的動態多配置並行流水線,執行部分的4個流水化功能部件,前后各有一個再定序多記錄緩沖。第一個緩沖稱為分派緩沖,指令進入是順序的,

流出是亂序的。后一個再定序緩沖,按程序的原始順序將指令提交給寫回段。

 

TEM模板的超標量流水線結構,TEM的6級流水線是指取指(Fetch),譯碼(Decode),分派(Dispatch),執行(Execution),完成(Complete),提交(Retire)

取指段:設計目標,增大取指段的寬度。取指段能夠維持的吞吐率直接影響整個超標量流水線的吞吐率。

            主要障礙,讀取的S條指令沒有對齊,和指令cache的物理組織有關。

                          每個時鍾周期,取指段用PC索引,將PC指向的指令連同后續的s-1條指令,一同取出。如果S條指令在一個cache的存儲陣列中,

                          該行可以一次取出。如果S條指令跨越了陣列邊界,S條指令就不能在一個周期內讀出。

            解決方法:編譯時的靜態技術,將指令合理的放置在存儲器中,保證每個分支目標的指令都放在Cache一行開始的位置。

                          硬件保證,即使指令跨越了陣列邊界,也能一個周期內讀出。

指令譯碼段:包括指令的識別以及指令之間相關性的檢測。譯碼的復雜度,主要由ISA(指令體系結構)和並行流水線的寬度來決定。

            同時譯碼多條RISC指令,並確定指令間的相關性,以及確定分支指令的分支方向,譯碼段常成為超標量流水線中的關鍵路徑。CISC會更加復雜。

指令分派:在指令譯碼和執行之間,還需要對指令進行臨時的緩沖,某些操作數還沒有准備好的指令可以放入一個單獨的緩沖區內。在所有的操作數都就緒后,

              從緩沖區中讀取指令到功能部件執行。這個臨時的指令緩沖稱為保留站。保留站將指令譯碼和執行加以分離,消除了譯碼段不必要的停頓。

              分派段后使用一個統一的緩沖,稱為集中保留站。分派段后使用分離的緩沖,稱為分布保留站。

指令執行:當前超標量設計的趨勢是向着大規模並行和多條流水線的方向發展,配置了越來越多,越來越專用的功能部件。在超標量流水線中,

          各種部件的數量比例也是一個有趣的問題,一般由應用領域來決定,40%ALU指令,20%分支指令以及40%load/store指令。

          在實際的超標量流水線設計中,功能部件的數量大於並行流水線的寬度。由於超標量流水線的寬度是由每周期取指,譯碼,已完成的指令數來確定的,

          每次發射的指令類型都不同,不一定和功能部件類型匹配。同時為了避免結構相關帶來的停頓,功能部件的數目必須大於流水線的寬度,

          才不會使執行段稱為流水段的瓶頸。

中斷和異常,經常會打斷程序的執行,動態流水線的超標量處理器存在指令的亂序執行,所以在發生中斷或異常時,

                 一種實現方案是停止取指段讀取新指令,完成當前流水線中執行的執行,記錄機器當前的狀態,中斷處理后,恢復機器狀態,程序繼續執行。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM