流水技術


流水線的基本概念

什么是流水線

  1. 工業生成流水線

  2. 流水線技術:把一個重復的過程分解為若干個子過程,每個子過程由專門的功能部件來實現;把多個處理過程在時間上錯開,依次通過各功能段,這樣,每個子過程就可以與其它的子過程並行進行。

  3. 流水線中的每個子過程及其功能部件稱為流水線的級或段,段與段相互連接形成流水線。流水線的段數稱為流水線的深度。

  4. 指令流水線:把指令的解釋過程分解為分析和執行兩個子過程,並讓這兩個子過程分別用獨立的分析部件和執行部件來實現。理想情況下速度提高一倍

    4段指令流水線示意圖:

  5. 浮點加法流水線:把流水線技術應用於運算的執行過程,就形成了運算操作流水線,也稱為部件級流水線;把浮點加法的全過程分解為求階差對階尾數相加規格化四個子過程。理想情況下速度提高3倍。

  6. 時-空圖:時-空圖從時間和空間兩個方面描述了流水線的工作過程。同一時-空圖中,橫坐標代表時間,縱坐標代表流水線的各個段,下給出浮點加法流水線的時空圖。

  7. 流水技術的特點:

    • 流水線把一個處理過程分解為若干個子過程(段),每個子過程由一個專門的功能部件來實現;
    • 流水線中各段的時間應盡可能相等,否則將引起流水線堵塞、斷流,時間最長的段將成為流水線的瓶頸;
    • 流水線每一個段的后面都要有一個緩沖寄存器(鎖存器),稱為流水寄存器,其作用是在相鄰的兩段之間傳送數據,以保證提供后面要用到的信息,並把各段的處理工作相互隔離。
    • 流水技術適合與大量重復的時序過程,只有在輸入端不斷地提供任務,才能充分發揮流水線的效率。
    • 流水線需要有通過時間和排空時間:通過時間:第一個任務從進入流水線到流出結果所需要的時間;排空時間:最后一個任務從進入流水線到流出結果所需的時間。

流水線的分類

  1. 部件級、處理機級及處理機間流水線——按照流水技術用於計算機系統的等級不同

    • 部件級流水線(運算操作流水線):把處理機中的部件分段,再把這些分段相互連接起來,使得各種類型的運算操作能夠按流水方式進行。
    • 處理機級流水線(指令流水線):把指令的執行過程按照流水方式處理。把一條指令的執行過程分解為若干個子過程,每個子過程在獨立的功能部件中執行。
    • 系統級流水線(宏流水線):把多台處理機串行連接起來,對同一數據流進行處理,每個處理機完成整個任務中的一部分。
  2. 單功能流水線與多功能流水線——按照流水線所完成的功能來分類

    • 單功能流水線:只能完成一種固定功能的流水線。
    • 多功能流水線:流水線的各階段可以進行不同的連接,以實現不同的功能。
  3. 靜態流水線與動態流水線——按照同一時間內各段之間的連接方式對多功能流水線作進一步的分類

    • 靜態流水線:在同一時間內,多功能流水線中的各段只能按同一種功能的連接方式工作。對於靜態流水線來說,只有當輸入的是一串相同的運算任務時,流水的效率才能得到充分的發揮。

    • 動態流水線:在同一時間內,多功能流水線中的各段可以按照不同的方式連接,同時執行多種功能。優點:靈活,能夠提高流水線各段的使用率,從而提高處理速度。缺點:控制復雜。

  4. 線性流水線與非線性流水線——按照流水線中是否有反饋回路來進行分類

    • 線性流水線:流水線的各段串行連接,沒有反饋回路。數據通過流水線中的各段時,每一個段最多只流過一次。

    • 非線性流水線:流水線中除了有串行的連接外,還有反饋回路。

  5. 順序流水線與亂序流水線——根據任務流水和流出順序是否相同來進行分類

    • 順序流水線:流水線輸出端任務流出的順序與輸入端任務流入的順序完全相同。每一個任務在流水線的各段中是一個跟着一個順序流動的。
    • 亂序流水線:流水線輸出端任務流出順序與輸入端任務流入的順序可以不同,允許后進入流水線的任務先完成。也稱為無序流水線、錯序流水線、異步流水線。
  6. 標量處理機與向量流水處理機

    • 把指令執行部件中采用了流水線的處理機稱為流水線處理機
    • 標量處理機:處理機不具有向量數據表示和向量指令,僅對標量數據進行流水處理。
    • 向量流水處理機:具有向量數據表示和向量指令的處理機。向量數據表示和流水技術的結合。

流水線的性能指標

吞吐率

吞吐率:在單位時間內流水線所完成的任務數量或輸出結果的數量\(TP = \frac{n}{T_k}\),其中\(n\)表示任務數量;\(T_k\)表示處理完\(n\)個任務所用的時間。

各段時間均相等的流水線

  • 各段時間均相等的流水線時空圖

  • 流水線完成\(n\)個連續任務所需要的總時間為(假設是一條\(k\)段線性流水線):

    \[T_k = k\Delta t + (n - 1)\Delta t = (k + n - 1)\Delta t \]

  • 流水線的實際吞吐率:

    \[TP = \frac{n}{(k + n - 1)\Delta t} \]

  • 最大吞吐率:

    \[TP_{max} = \lim\limits_{n \to \infin} \frac{n}{(k + n - 1)\Delta t} = \frac{1}{\Delta t} \]

  • 最大吞吐率與實際吞吐率的關系:

    \[TP = \frac{n}{k + n - 1}TP_{max} \]

    流水線的實際吞吐率小於最大吞吐率,它除了與每個段的時間有關外,還與流水線的段數\(k\)以及輸入到流水線中的任務數\(n\)等有關。只有當\(n \gg k\)時,才有\(TP \approx TP_{max}\)

各段時間不完全相等的流水線

  • 各段時間不等的流水線及其時空圖

    • 舉例1如下;一條4段的流水線;\(S_1\)\(S_2\)\(S_3\)各段的時間為\(\Delta t\);\(S_2\)的時間為\(3\Delta t\)(瓶頸段);流水線中這種時間最長的段稱為流水線的瓶頸段。

    • 舉例2\(S_1\)\(S_2\)\(S_3\)\(S_5\)各段的時間為\(\Delta t\)\(S_4\)的時間為\(3\Delta t\)(瓶頸段)

  • 各段時間不等的流水線的實際吞吐率為(\(\Delta t_i\)表示第\(i\)段的時間,共\(k\)個段):

    \[TP = \frac{n}{\sum\limits_{i = 1}^{k}\Delta t_i + (n - 1)\mathop{max}(\Delta t_1 , \Delta t_2 , ... , \Delta t_k)} \]

  • 流水線的最大吞吐率為:

    \[TP_{max} = \frac{1}{\mathop{max}(\Delta t_1 , \Delta t_2 , ... , \Delta t_k)} \]

    對於前面舉例2中的5段流水線,其最大吞吐率為\(TP_{max} = \frac{1}{3\Delta t}\)

解決流水線瓶頸問題的常用方法

  • 細分瓶頸段

    例如:對於舉例2中的5段流水線,把瓶頸段\(S_4\)細分為3個字流水線段:\(S_{4-1}\)\(S_{4-2}\)\(S_{4-3}\),改進后的流水線的吞吐率為:\(TP_{max} = \frac{1}{\Delta t}\)

  • 重復設置瓶頸段(缺點:控制邏輯比較復雜,所需的硬件增加了)

    例如:對於舉例2中的5段流水線,重復設置瓶頸段\(S_4\)\(S_{4a}\)\(S_{4b}\)\(S_{4c}\),其示意圖和時空圖如下:

流水線的加速比

加速比:完成同樣的一批任務,不使用流水線所用的時間與使用流水線所用的時間之比。假設:不使用流水線(即順序執行)所用的時間為\(T_s\),使用流水線后所用的時間為\(T_k\),則該流水線的加速比為:

\[S = \frac{T_s}{T_k} \]

流水線各段時間相等

都是\(\Delta t\)

  • 一條\(k\)段流水線完成\(n\)個連續任務所需的時間為:

    \[T_k = (k + n - 1)\Delta t \]

  • 順序執行\(n\)個任務所需要的時間為:

    \[T_s = nk\Delta t \]

  • 流水線的實際加速比為:

    \[S = \frac{nk}{k + n - 1} \]

  • 最大加速比:

    \[S_{max} = \lim\limits_{n \to \infin} \frac{nk}{k + n - 1} = k \]

    即當\(n \gg k\)時,\(S \approx k\)

流水線的各段時間不完全相等時

  • 一條\(k\)段流水線完成\(n\)個連續任務的實際加速比為:

    \[S = \frac{n\sum\limits_{i = 1}^{k}\Delta t_i}{\sum\limits_{i = 1}^{k}\Delta t_i + (n - 1)\mathop{max}(\Delta t_1 , \Delta t_2 , ...,\Delta t_k)} \]

流水線的效率

定義:流水線中的設備實際使用時間與整個運行時間的比值,即流水線設備的利用率。

由於流水線有通過時間和排空時間,所以在連續完成\(n\)個任務的時間內,各段並不是滿負荷地工作。

各段時間相等

  • 各段的效率\(e_i\)相同:

    \[e_1 = e_2 = ...=e_k = \frac{n\Delta t}{T_k} = \frac{n}{k + n - 1} \]

  • 整條流水線的效率為:

    \[E = \frac{e_1 + e_2 + ... + e_k}{k} = \frac{ke_1}{k} = \frac{kn\Delta t}{kT_k} = \frac{n}{n + k - 1} \]

  • 最高效率為:

    \[E_{max} = \lim\limits_{n \to \infin}\frac{n}{k + n - 1} = 1 \]

    \(n \gg k\)時,\(E \approx 1\)

  • 當流水線各段時間相等時,流水線的效率與吞吐率成正比:

    \[E = TP \times \Delta t \]

流水線的效率是流水線的實際加速比\(S\)與它的最大加速比\(k\)的比值,即:

\[E = \frac{S}{k} \]

\(E = 1\)時,\(S = k\),實際加速比達到最大。

從時空圖上看,效率就是\(n\)個任務占用的時空面積和\(k\)個段總的時空面積之比。即:

\[E = \frac{n個任務實際占用的時空區}{k個段總的時空區} \]

  • 當各段時間不相等時:

    \[E = \frac{n\sum\limits_{i = 1}^{k}\Delta t_i}{k[\sum\limits_{i = 1}^{k}\Delta t_i + (n - 1)\mathop{max}(\Delta t_1 , \Delta t_2 , ... , \Delta t_k)]} \]

流水線的性能分析舉例

例3.1 設在下圖所示的靜態流水線上計算:\(\prod\limits_{i = 1}^{4}(A_i + B_i)\)。流水線的輸出可以直接返回輸入端或暫存於相應的流水寄存器中,試計算其吞吐率、加速比和效率。(每段的時間都為\(\Delta t\)

  1. 選擇適合與流水線工作的算法:

    • 先計算\(A_1 + B_1\)\(A_2 + B_2\)\(A_3 + B_3\)\(A_4 + B_4\)
    • 再計算 \((A_1 + B_1) \times (A_2 + B_2)\)\((A_3 + B_3) \times (A_4 + B_4)\)
    • 最后再計算總的乘積結果
  2. 畫出時空圖

  3. 計算性能

    • \(18\)\(\Delta t\)時間中,給出了\(7\)個結果,吞吐率為:

      \[TP = \frac{7}{18\Delta t} \]

    • 不同流水線,由於一次求和需\(6\Delta t\),一次求積需要\(4\Delta t\),則產生上述\(7\)個結果共需要\((4 \times 6 + 3 \times 4)\Delta t = 36 \Delta t\),則加速比為:

      \[S = \frac{36\Delta t}{18\Delta t} = 2 \]

    • 流水線的效率為:

      \[E = \frac{4 \times 6 + 3 \times 4}{8 \times 18} = 0.25 \]

  4. 題后分析

    可以看出,在求解此問題時,該流水線的效率不高,主要原因如下:

    • 多功能流水線在做某一種運算時,總有一些段是空閑的;
    • 靜態流水線在進行功能切換時,要等前一種運算全部流出流水線后才能進行后面的運算;
    • 運算之間存在關聯,后面有些運算要用到前面運算的結果;
    • 流水線的工作過程有建立與排空部分。

例3.2 有一條動態多功能流水線由5段組成,加法用1,3,4,5段,乘法用\(1,2,5\),第\(4\)段的時間為\(2 \Delta t\),其余各段的時間均為\(\Delta t\),而且流水線的輸出可以直接返回輸入端或暫存於相應的流水寄存器中。若在該流水線上計算\(\sum\limits_{i = 1}^{4}(A_i \times B_i)\)。試計算其吞吐率、加速比和效率。

  1. 選擇適合於流水線工作的算法

    • 應先計算\(A_1 \times B_1\)\(A_2 \times B_2\)\(A_3 \times B_3\)\(A_4 \times B_4\)
    • 再計算\((A_1 \times B_1) + (A_2 \times B_2)\)\((A_3 \times B_3) + (A_4 \times B_4)\)
    • 再計算總的累加結果
  2. 畫出時空圖

  3. 計算性能

    • 吞吐率:

      \[TP = \frac{7}{16\Delta t} \]

    • 加速比:

      \[S = \frac{27\Delta t}{16\Delta t} \approx 1.69 \]

    • 效率:

      \[E = \frac{4 \times 3 + 3 \times 5}{5 \times 16} \approx 0.338 \]

流水線設計中的若干問題

  • 瓶頸問題
    • 理想情況下流水線在工作時,其中的任務是同步地每一個時鍾周期往前流動一段。
    • 當流水線各段不均勻時,機器的時鍾周期取決於瓶頸段的延遲時間。
    • 在設計流水線時,要盡可能使各段時間相等。
  • 流水線的額外開銷:流水寄存器延遲和時鍾偏移開銷
    • 流水寄存器需要建立時間和傳輸延遲:建立時間:在觸發寫操作的時鍾信號到達之前,寄存器輸入必須保持穩定的時間。傳輸延遲:時鍾信號到達后到寄存器輸出可用的時間。
    • 時鍾偏移開銷:流水線中,時鍾到達各流水寄存器的最大差值時間(時鍾到達各流水寄存器的時間不是完全相同的)。
    • 其他問題
      • 流水線並不能減少(而且一般是增加)單條指令的執行時間,但卻能提高吞吐率;
      • 增加流水線的深度(段數)可以提高流水線的性能;
      • 流水線的深度受限與流水線的額外開銷;
      • 當時鍾周期小到與額外開銷相同時,流水已沒意義。因為這時在每一個時鍾周期中已沒有時間來做有用的工作。
  • 沖突問題

非線性流水線的調度

在非線性流水線中,存在反饋回路,當一個任務在流水線中流過時,可能要多次經過某些段。

流水線調度要解決的問題是:應該按照什么樣的時間間隔向流水線輸入新任務,才能既不發生功能段使用沖突,又能使流水線有較高的吞吐率和效率。

單功能非線性流水線的最優調度

  • 向一條非線性流水線的輸入端連續輸入兩個任務之間的時間間隔稱為非線性流水線的啟動距離。

  • 會引起非線性流水線功能段使用沖突的啟動距離稱為禁用啟動距離。

  • 啟動距離和禁用啟動距離一般都用時鍾周期數來表示,是一個正整數。

  • 預約表:橫向(向右):時間,一般用時鍾周期表示;縱向(向下):流水線的段

    例:一個5功能段非線性流水線的預約表

    1 2 3 4 5 6 7 8 9
    \(S_1\)
    \(S_2\)
    \(S_3\)
    \(S_4\)
    \(S_5\)

    如果在第\(n\)個時鍾周期使用第\(k\)段,則在第\(k\)行和第\(n\)列的交叉處的格子里有一個

    如果在第\(k\)行和第\(n\)列的交叉處的格子里面有一個,則表示在第\(n\)個時鍾周期要使用第\(k\)段。

根據預約表寫出禁止表F

定義:一個由禁用啟動距離構成的集合。

具體方法:對於預約表的每一行的任何一對,用它們所在的列號相減,列出各種可能的差值,然后刪除相同的,剩下的就是禁止表的元素。

在上例中:

  • 第一行的差值有:\(8\)
  • 第二行的差值為:\(1 , 5 , 6\)
  • 第三行只有一個,沒有差值
  • 第四和第五行的差值都為:\(1\)
  • 最終的禁止表\(F = \{1 , 5 , 6 , 8\}\)

根據禁止表F寫出初始沖突向量\(C_0\)

進行從一個集合到一個二進制位串的變換。

定義:沖突向量\(C\)是一個\(n\)位的二進制位串。

\(C_0 = (c_nc_{n - 1}...c_1)\),則:

\[\begin{align} c_i = \begin{cases} 1 & i \in F\\ 0 & i \notin F \end{cases} \end{align} \]

  • \(c_0\):表示允許間隔\(i\)個時鍾周期后送入后續任務
  • \(c_1\):表示不允許間隔\(i\)個時鍾周期后送入后續任務

對於上述例子:

\[\begin{align} F &= \{1 , 5 , 6 , 8\}\\ C_0 &= (10110001) \end{align} \]

根據初始沖突向量\(C_0\)畫出狀態轉換圖

當第一個任務流入流水線后,初始沖突向量\(C_0\)決定了下一個任務需間隔多少個時鍾周期才可以流入。

當第二個任務流入后,新的沖突向量是怎么樣的呢?

  • 假設第二個任務是與第一個任務間隔\(j\)個時鍾周期流入,由於第一個任務已經在流水線中前進了\(j\)個時鍾周期,其相應的禁止表中各元素的值都應該減去\(j\),並丟棄小於等於\(0\)的值。

  • 對沖突向量來說,就是邏輯右移\(j\)位,左邊補\(0\)

  • 在沖突向量上,就是對他們的沖突向量進行或運算

    \[SHR^{(j)} (C_0) \or C_0 \]

    其中\(SHR^{(j)}\)表示邏輯右移\(j\)位。

擴展到更一般的情況:假設\(C_k\)表示當前的沖突向量,\(j\)表示允許的時間間隔,則新的沖突向量為:

\[SHR^{(j)}(C_k) \or C_0 \]

對於所有允許的時間間隔都按上述步驟求出其新的沖突變量,並且把新的沖突向量作為當前沖突向量,反復使用上述步驟,直到不再產生新的沖突向量為止。

從初始沖突向量\(C_0\)出發,反復應用上述步驟,可以求得所有的沖突向量以及產生這些向量對應的時間間隔,由此可以畫出用沖突向量表示的流水線狀態轉移圖。

  • 有向弧:表示狀態轉移的方向
  • 弧上的數字:表示引入后續任務(從而產生新的沖突向量)所用的時間間隔(時鍾周期數)

對於上面的例子而言:

  1. \(C_0 = (10110001)\)

    引入后續任務可用的時間間隔為:\(2 , 3 , 4 , 7\)個時鍾周期,分別采用\(2,3,4,7\),則新的沖突向量為:

    \[\begin{align} (00101100) \or (10110001) &= (10111101)\\ (00010110) \or (10110001) &= (10110111)\\ (00001011) \or (10110001) &= (10111011)\\ (00000001) \or (10110001) &= (10110001) \end{align} \]

  2. 對於新向量\((10111101)\),其可用時間間隔\(2,7\),用類似上述的方法,可以求出其他后續的沖突向量分別為:\((10111101)\)\((10110001)\)

  3. 其他依次類推

  4. 在此基礎上,畫出狀態轉移示意圖:

根據狀態轉換圖寫出最優調度方案

  • 根據狀態轉換圖,由初始狀態出發,任何一個閉合回路即為一種調度方案。

  • 列出所有可能的調度方案,計算出每種方案的平均時間間隔,從中找出其中最小者,即為最優調度方案。

  • 在上述例子中,各種調度方案機器平均間隔時間表如下:

    調度策略 平均延遲拍數
    \((2 , 7)\) \(4.5\)
    \((2 , 2 , 7)\) \(3.67\)
    \((3 , 7)\) \(5\)
    \((3 , 4)\) \(3.5\)
    \((3 , 4 , 3 , 7)\) \(4.25\)
    \((3 , 4 , 7)\) \(4.67\)
    \((4 , 3 , 7)\) \(4.67\)
    \((4 , 7)\) \(5.5\)
    \((7)\) \(7\)

    最優調度方案為\((3 , 4)\),平均間隔時間為\(3.5\)個時鍾周期,吞吐率最高

  • 方案\((3 , 4)\)是一種不等時間間隔的調度方案,與等間隔的調度方案相比,在控制上要復雜得多,為了簡化控制,也可以采用等間隔時間的調度方案,但吞吐率和效率往往會下降不少。在上述例子中,等時間間隔的方案只有一個:\((7)\),其吞吐率下降了一半。

流水線的相關與沖突

一條經典的5段流水線

一條指令的執行過程分為一下5個周期:

  • 取指令周期(IF):

    • 以程序計數器PC中的內容作為地址,從存儲器中取出指令並放入指令寄存器IR
    • 同時PC值加4(假設每條指令占4個字節),指向順序的下一條指令。
  • 指令譯碼、讀寄存器周期(ID)

    對指令進行譯碼,並用IR中的寄存器地址去訪問通用寄存器組,讀出所需的操作數。

  • 執行、有效地址計算周期(EX)

    • loadstore指令:ALU把指令中所指定的寄存器的內容與偏移量相加,形成訪存有效地址。
    • 寄存器-寄存器ALU指令:ALU按照操作碼指定的操作對從通用寄存器組中讀出的數據進行運算。
    • 寄存器-立即數ALU指令:ALU按照操作碼指定的操作對從通用寄存器組中讀出的操作數和指令中給出的立即數進行運算。
    • 分支指令:ALU把指令中給出的偏移量與PC值相加,形成轉移目標的地址。同時對在前一個周期讀出的操作數進行判斷,確定分支是否成功。
  • 存儲器訪問、分支完成周期(MEM):

    該周期處理的指令只有loadstore和分支指令。其他類型的指令在此周期不做任何操作。

    • load指令:用上一個周期計算出來的有效地址從存儲器重讀出相應的數據;
    • store指令:把指定的數據寫入這個有效地址所指出的存儲器單元。
    • 分支指令:分支成功就把轉移目標地址送入PC,分支指令執行完成。
  • 寫回周期(WB):ALU運算值和load指令在這個周期把結果數據寫入通用寄存器組。

    • ALU運算指令:結果數據來自ALU
    • load指令:結果數據來自存儲器
  • 在這個實現方案中:

    • 分支指令需要4個時鍾周期(如果把分支指令的執行提前到ID周期,則只需要2個周期);
    • store指令需要4個周期
    • 其它指令需要5個周期才能完成

將上述實現方案修改為流水線實現:

  • 一條經典的5段流水線

    • 每一個周期作為一個流水段;

    • 在各段之間加上鎖存器(流水寄存器)

采用流水線方式實現時,應解決好以下幾個問題:

  • 要保證不會在同一時鍾周期要求同一個功能段做兩件不同的工作。例如:不能要求ALU同時做有效地址計算和算術運算。
  • 避免IF段的訪存(取指令)與MEM段的訪存發生沖突。
    • 可以采用分離的指令存儲器和數據存儲器。
    • 一般采用分離的指令cache和數據cache
  • ID段和WB段都要訪問同一寄存器文件

如何解決對同一寄存器的訪問沖突?

答:把寫操作安排在時鍾周期的前半拍完成,把讀操作安排在后半拍完成。

考慮PC的問題

  • 流水線為了能夠每個時鍾周期啟動一條新的指令,就必須在每個時鍾周期進行PC值加4操作,並保留新的PC值。這種操作必須在IF段完成,以便為取下一條指令做好准備。
  • 但分支指令也可能改變PC的值,而且是在MEM段進行,這會導致沖突。

5段流水線的兩種描述方式

  • 第一種描述 類似於時空圖

  • 第二種描述 按時間錯開的數據通路序列

相關與流水線沖突

相關

相關:兩條指令之間存在某種依賴關系。如果兩條指令相關,則它們就有可能不能在流水線中重疊執行或者只能部分重疊執行。

數據相關

  • 對於兩條指令i(在前,下同)和j(在后, 下同),如果下述條件之一成立, 則稱指令j與指令i數據相關:
    • 指令j使用指令i產生的結果;
    • 指令j與指令k數據相關,而指令k又與指令i數據相關。
  • 數據相關具有傳遞性
  • 數據相關反映了數據的流動關系,即如何從其產生者流動到其消費者。
  • 當數據的流動是經過寄存器時,相關的檢測比較直觀和容易。
  • 當數據的流動是經過存儲器時,檢測比較復雜
    • 相同形式的地址其有效地址未必相同;
    • 形式不同的地址其有效地址卻可能相同。

名相關

  • :指令所訪問的寄存器或存儲器單元的名稱。
  • 如果兩條指令使用相同的名,但他們之間並沒有數據流動,則稱這兩條指令存在名相關
  • 指令j和指令i之間的名相關有兩種:
    • 反相關:如果指令j寫的名與指令i讀的名相同,則稱指令i和指令j發生了反相關。指令j寫的名= 指令i讀的名
    • 輸出相關:如果指令j和指令i寫相同的名,則稱指令i和指令j發生了輸出相關。指令j寫的名= 指令i寫的名。
  • 名相關的兩條指令之間並沒有數據的傳送
  • 如果一條指令中的名改變了,並不影響另外一條指令的執行
  • 換名技術:
    • 定義:通過改變指令中操作數的名來消除名相關
    • 對於寄存器操作數進行換名稱為寄存器換名,既可以用編譯器靜態實現,也可以用硬件動態完成。

控制相關

  • 定義:由分支指令引起的相關。
  • 為了保證程序應有的執行順序,必須嚴格按控制相關確定的順序執行。
  • 典型的程序結構是if-then結構。
  • 控制相關帶來了以下兩個限制:
    • 與一條分支指令控制相關的指令不能被移到該分支之前。否則這些指令就不受該分支控制了。
    • 如果一條指令與某分支指令不存在控制相關,就不能把改指令移到該分支之后。

流水線沖突

定義:流水線沖突是指對於具體的流水線來說,由於相關的存在,使得指令流中的下一條指令不能在指定的時鍾周期執行。

流水線沖突的3種類型:

  • 結構沖突:因硬件資源滿足不了指令重疊執行的要求而發生的沖突。
  • 數據沖突:當指令在流水線中重疊執行時,因需要用到前面指令的執行結果而發生的沖突。
  • 控制沖突:流水線遇到分支指令和其它會改變PC值的指令所引起的沖突。

帶來的幾個問題:

  • 導致錯誤的執行結果
  • 流水線可能會出現停頓,從而降低流水線的效率和實際的加速比。
  • 我們約定:當一條指令被暫停時,在該暫停指令之后流出的所有指令都要被暫停,而在該暫停指令之前流出的指令則繼續進行(否則就永遠無法消除沖突)。

結構沖突

  • 在流水線處理機中,為了能夠使各種組合的指令都能順利地重疊執行,需要對功能部件進行流水或重復設置資源。

  • 如果某種指令組合因為資源沖突而不能正常執行,則稱該處理機有結構沖突。

  • 常見的導致結構沖突的原因:

    • 功能部件不是完全流水
    • 資源份數不夠
  • 結構沖突舉例:訪存沖突

    有些流水線處理機只有一個存儲器,將數據和指令放在一起,訪存指令會導致訪存沖突。

    • 解決方法一:插入暫停周期(流水線氣泡)
    • 解決方法二:設置相互獨立的指令存儲器和數據存儲器或設置相互獨立的指令cache和數據cache
  • 有時流水線設計者允許結構沖突的存在

    主要原因:減少硬件成本,如果把流水線中的所有功能單元完全流水化,或者重復設置足夠份數,那么所花費的成本將相當高。

數據沖突

當相關的指令靠得足夠近時,它們在流水線中的重疊執行或者重新排序會改變指令讀/寫操作數的順序,使之不同於它們串行執行時的順序,則發生了數據沖突

  • 根據指令讀訪問和寫訪問的順序,可以將數據沖突分為3種類型。

    考慮兩條指令ij,且ij之前進入流水線,可能發生的數據沖突有:

    • 寫后讀沖突(RAW):在i寫入之前,j先去讀。j讀出的內容是錯誤的。這是最常見的一種數據沖突,它對應於真數據相關。

    • 寫后寫沖突(WAW):在i寫入之前,j先寫。最后寫入的結果是i的。這種沖突對應於輸出相關。

      寫后寫沖突僅發生在這樣的流水線中:

      • 流水線中不只一個段可以進行寫操作;
      • 指令被重新排序了。

      前面介紹的5段流水線不會發生寫后寫沖突,因為只在WB段寫寄存器。

    • 讀后寫沖突(WAR):在i讀之前,j先寫。i讀出的內容是錯誤的!由反相關引起。

      這種沖突僅發生在這樣的情況下:

      • 有些指令的寫結果操作提前了,而且有些指令的讀操作滯后了;
      • 指令被重新排序了。
  • 通過定向技術減少數據沖突引起的停頓

    定向技術也稱旁路或短路

    • 關鍵思路:在計算結果尚未出來之前,后面等待使用該結果的指令並不真正立即需要該計算結果,如果能夠將該計算結果從其產生的地方直接送到其它指令需要它的地方,那么就可以避免停頓。
    • 定向的實現:EX段和MEM段之間的流水寄存器中保存的ALU運算結果總是回送到ALU的入口。當定向硬件檢測到前一個ALU運算結構寫入的寄存器就是當前ALU操作的源寄存器時,那么控制邏輯就選擇定向的數據作為ALU的輸入,而不采用從通用寄存器組讀出來的數據。
    • 結果數據不僅可以從某一功能部件的輸出定向到其自身的輸入,而且還可以定向到其它功能部件的輸入。
  • 需要停頓的數據沖突

    • 並不是所有的數據沖突都可以用重定向技術來解決
    • 增加流水線互鎖機制,插入暫停;作用:檢測發現數據沖突,並使流水線停頓,直至沖突消失。
  • 依靠編譯器解決數據沖突

    讓編譯器重新組織指令順序來消除沖突,這種技術稱為指令調度或流水線調度。

控制沖突

  • 執行分支指令的結果有兩種:

    • 分支成功:PC值改變為分支轉移的目標地址。在條件判定和轉移地址計算都完成后,才改變PC值。
    • 不成功或失敗:PC的值保持正常遞增,指向順序的下一條指令。
  • 處理分支指令最簡單的方法:凍結或者排空流水線。

    • 優點:簡單,前述5段流水線中,改變PC值是在MEM段進行的。給流水線帶來了3個時鍾周期的延遲。
  • 把由分支指令引起的延遲稱為分支延遲。

  • 分支指令在目標代碼中出現的頻度:每\(3\sim 4\)條指令就有一條是分支指令。假設分支指令出現的頻度是30%,流水線理想CPI = 1,則流水線的實際CPI = 1.9

  • 可以采取兩種措施來減少分支延遲

    • 在流水線中盡早判斷出分支轉移是否成功
    • 盡早計算出分支目標地址。
  • 3種通過軟件來減少分支延遲的方法

    • 共同點

      • 對分支的處理方法在程序的執行過程中始終是不變的,是靜態的。
      • 要么總是預測分支成功,要么總是預測分支失敗。
    • 預測分支失敗

      • 允許分支指令后的指令繼續在流水線中流動,就好像什么都沒發送一樣;
      • 若確定分支失敗,將分支指令看作是一條普通指令,流水線正常流動。
      • 若確定分支成功,流水線就把在分支指令之后取出的所有指令轉化成空操作,並按分支目地重新取指令執行。

      要保證:分支結果出來之前不能改變處理機的狀態,以便一旦猜錯時,處理機能夠回退到原先的狀態。

    • 預測分支成功

      假設分支轉移成功,並從分支目標地址處取指令執行。起作用的前提:先知道分支目標地址,后知道分支是否成功。前述5段流水線中,這種方法沒有任何好處。

    • 延遲分支

      主要思想:從邏輯上延長分支指令的執行時間,把延遲分支看成是由原來的分支指令和若干個延遲槽構成,不管分支是否成功,都要按照順序執行延遲槽中的指令。

      分支延遲指令的調度:在延遲槽中放入有用的指令。由編譯器完成。能否帶來好處取決於編譯器能否把有用的指令調度到延遲槽中。

      三種調度方法:

      • 從前調度
      • 從目標處調度
      • 從失敗出調度

      三種方法的要求和效果

      調度策略 對調度的要求 什么情況下起作用
      從前調度 被調度的指令必須與分支無關 任何情況
      從目標處調度 必須保證再分支失敗時執行被調度的指令不會導致錯誤。有可能需要復制指令。 分支成功時(但由於復制指令,有可能會增大程序空間)
      從失敗處調度 必須保證在分支成功時執行被調度的指令不會導致錯誤 分支失敗時

      分支延遲受到兩個方面的限制:

      • 可以被放入延遲槽中的指令要滿足一定的條件;
      • 編譯器預測分支轉移方向的能力。

      進一步改進:分支取消機制

      ​ 當分支的實際執行方向和事先所預測的一樣時,執行分支延遲槽中的指令,否則就將分支延遲槽中的指令轉化成一個空操作。

流水線的實現

MIPS的一種簡單實現

實現MIPS指令子集的一種簡單數據通路。

  • 該數據通路的操作分為5個時鍾周期

    • 取指令
    • 指令譯碼、讀寄存器
    • 執行、有效地址計算
    • 存儲器訪問、分支完成
    • 寫回
  • 只討論整數指令的實現

  • 設置了一些臨時寄存器。其作用如下:

    • PC:程序計數器,存放當前指令的地址。
    • NPC:下一條程序計數器,存放下一條指令的地址。
    • IR:指令寄存器,存放當前正在處理的指令。
    • A:第一操作數寄存器,存放從通用寄存器組讀出來的操作數。
    • B:第二操作數寄存器,存放從通用寄存器組讀出來的另一個操作數。
    • Imm:存放符號擴展后的立即數操作數。
    • Cond:存放符號擴展后的立即數操作數。
    • ALUo:存放ALU的運算結果。
    • LMD:存放load指令從存儲器讀出的數據。

一條MIPS指令最多需要以下5個時鍾周期:

  • 取指周期(IF
  • 指令譯碼、讀寄存器周期(ID
  • 執行、有效地址計算周期(EX
  • 存儲器訪問、分支完成周期(MEM)
  • 寫回周期(WB

基本的MIPS流水線

每一個時鍾周期完成的工作看作是流水線的一段,每個時鍾周期啟動一條新的指令。

  • 流水實現的數據通路

    • 設置了流水寄存器

      • 段與段之間設置流水寄存器

      • 流水寄存器的名稱用其相鄰的兩個段的名稱拼合而成,如ID/EX表示ID段和EX段之間的流水寄存器。

      • 每個流水寄存器是由若干個寄存器構成的

      • 寄存器的命名形式為:x , y

      • 所包含的字段的命名形式為:x , y[s],其中x表示流水寄存器的名稱,y表示具體寄存器名稱,s是字段名。例如:ID/EX IR:流水寄存器ID/EX中的子寄存器IRID/EX IR[op]表示該寄存器的op字段。

      • 流水寄存器的作用:將各段的工作隔開,使得它們不會相互干擾;保存相應段的處理結果。

    • 增加了向后傳遞IR和從MEM/WB.IR回送到通用寄存器組的連接。

    • 將對PC的修改移到了IF段,以使PC能及時地加4,為取下一條指令做好准備。


免責聲明!

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



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