架構知識點(一)

江左子固發表於2024-07-24

執行階段(Execution Stage)

執行階段是 CPU 流水線中的一個步驟,通常發生在取指階段(Instruction Fetch, IF)和解碼階段(Instruction Decode, ID)之後。在執行階段,CPU 會進行以下操作:

  1. 執行算術或邏輯操作:根據指令型別,ALU 會執行加法、減法、邏輯運算等操作。
  2. 處理移位操作:如果指令需要,執行邏輯或算術移位。
  3. 生成結果:算術邏輯操作的結果會被生成並暫存,等待後續使用。
  4. 更新狀態標誌:根據操作結果,更新 CPU 的狀態暫存器,如零標誌(Zero Flag)、進位標誌(Carry Flag)、溢位標誌(Overflow Flag)等。
  5. 控制指令的執行:對於控制流指令(如跳轉、分支等),執行階段會計算新的程式計數器(PC)值。

訪存階段(Memory Access Stage)

訪存階段通常在執行階段之後,其目的是與記憶體互動,進行資料的讀取或寫入。以下是訪存階段的一般操作:

  1. 生成記憶體地址:使用 ALU 的結果或其他方式生成記憶體訪問的地址。
  2. 讀取記憶體:執行從記憶體中讀取資料的操作,讀取的資料可能用於後續的指令執行或寫回暫存器。
  3. 寫入記憶體:如果指令需要,將資料寫入到記憶體指定的地址。
  4. 處理記憶體延遲:由於記憶體訪問可能涉及較長的延遲,CPU 需要處理這種情況,可能透過流水線暫停(stall)、資料轉發(forwarding)或使用快取等技術。
  5. 更新資料:將從記憶體讀取的資料或將要寫入的資料更新到 CPU 的相應部件,如暫存器或執行單元。

在流水線處理器中,執行階段和訪存階段可能與其他階段(如取指、解碼、寫回等)並行處理,以提高指令的吞吐量。然而,如果執行階段的操作結果需要用於訪存階段的地址計算,或者訪存階段的資料需要被執行階段使用,就可能需要特別的處理來避免資料冒險和控制冒險,例如透過資料轉發、流水線暫停或更復雜的排程技術。

訪存階段可以形象地比作一個繁忙的圖書館中的圖書檢索和借閱過程:

  1. 確定圖書位置(地址生成)

    • 就像讀者進入圖書館,需要知道圖書的索引號或書架位置一樣,在訪存階段,CPU 需要確定它要訪問的資料在記憶體中的具體位置。這通常涉及到根據基地址和偏移量計算出記憶體地址。
  2. 查詢圖書(傳送讀請求)

    • 讀者根據索引找到圖書管理員,請求檢索圖書。類似地,在 CPU 中,一旦確定了記憶體地址,就會向記憶體傳送讀取資料的請求。
  3. 等待圖書管理員響應(等待記憶體響應)

    • 圖書管理員需要時間來找到圖書並將其交給讀者。同樣,在 CPU 訪存階段,記憶體訪問可能會有延遲,因為記憶體需要時間來定位並返回資料。
  4. 閱讀圖書(資料讀取)

    • 讀者拿到圖書後會閱讀其中的內容。在 CPU 中,一旦記憶體響應了讀請求,資料就會被載入到 CPU 的暫存器中,供進一步的處理或執行使用。
  5. 歸還圖書或續借(資料寫回)

    • 如果讀者需要修改圖書的內容(儘管在現實中這不被允許),他們可以將其寫入自己的筆記本。在 CPU 中,如果執行的是寫操作,那麼資料會從 CPU 暫存器寫回到記憶體中的指定位置。
  6. 處理圖書逾期(處理記憶體訪問延遲)

    • 如果圖書管理員處理請求的時間較長,讀者可能需要等待。在 CPU 中,如果記憶體訪問延遲較長,可能會引入流水線停頓或使用其他技術(如資料轉發)來避免影響 CPU 的執行效率。
  7. 更新圖書館目錄(更新快取)

    • 圖書館可能會更新其目錄,以反映借閱和歸還的狀態。在 CPU 中,訪問的資料可能會被快取,以加快後續訪問速度。
  8. 遵守圖書館規則(確保資料一致性)

    • 讀者在圖書館必須遵守規則,比如不能同時借閱同一本書的多個副本。在 CPU 中,必須確保資料的一致性,避免由於併發訪問導致的資料衝突。

透過這個形象化的比喻,我們可以理解訪存階段在 CPU 執行過程中的重要性:
它是 CPU 與記憶體之間互動的橋樑,負責資料的讀取和寫入,同時處理可能的延遲和資料一致性問題。

執行階段可以形象地比作一個工廠的生產流程,其中每個指令就像是一道生產訂單,需要經過多個工序來完成:

  1. 接收生產訂單(指令取值)

    • 想象工廠收到一份生產訂單,上面列明瞭需要生產的產品規格和要求。在執行階段開始時,CPU 從指令流水線中獲取待執行的指令。
  2. 解析訂單細節(指令解碼)

    • 生產前需要詳細解讀訂單,明確生產步驟。CPU 需要解碼指令,確定它是一個加法、減法還是其他操作。
  3. 準備原材料(讀取運算元)

    • 根據訂單要求,從倉庫(暫存器堆或記憶體)中取出所需的原材料(運算元)。
  4. 設定生產線(配置 ALU)

    • 生產前要調整生產線的設定,以匹配訂單需求。CPU 的 ALU(算術邏輯單元)根據指令型別配置為執行特定的算術或邏輯操作。
  5. 生產加工(執行操作)

    • 在生產線上,原材料經過加工變成成品。在 CPU 中,運算元在 ALU 中進行計算,執行加法、減法或其他邏輯操作。
  6. 質量檢查(更新狀態標誌)

    • 生產後的產品需要經過質量檢查。CPU 在執行操作後,會更新一些狀態標誌,如零標誌(結果是否為零)、進位標誌(是否有高位溢位)、溢位標誌(是否超出表示範圍)等。
  7. 包裝成品(準備寫回結果)

    • 合格的產品需要被妥善包裝,準備發貨。在執行階段結束時,計算結果會被暫存,準備在下一個流水線階段寫回到暫存器或記憶體。
  8. 處理異常(異常和中斷)

    • 如果生產過程中出現異常(如裝置故障或原材料問題),需要立即處理。在 CPU 中,如果執行過程中出現異常情況(如除零錯誤或非法操作),會觸發異常處理流程。
  9. 最佳化生產(執行最佳化)

    • 為了提高生產效率,可能採用一些最佳化措施,如流水線作業、預取原材料等。CPU 執行階段也可能採用各種最佳化技術,如指令級並行(ILP)、亂序執行等。
  10. 記錄生產日誌(更新暫存器)

    • 生產結束後,需要記錄生產日誌,包括生產的產品數量、質量等資訊。在 CPU 中,執行結果最終會寫回到暫存器或記憶體,更新 CPU 的狀態。

透過這個形象化的比喻,我們可以更直觀地理解執行階段在 CPU 指令處理中的作用:它是指令實際進行計算和邏輯操作的地方,涉及到指令的詳細解讀、操作的執行、結果的生成和狀態的更新。

形象地解釋執行階段和訪存階段的關係,我們可以將它們比作餐廳廚房和顧客就餐區的互動:

  1. 執行階段(廚房)

    • 執行階段就像廚房,是準備“菜品”(指令結果)的地方。廚師(ALU)根據選單(指令)來決定如何烹飪食材(運算元)。這個階段是指令執行的“後臺”,在這裡進行所有的計算和邏輯操作。
  2. 訪存階段(就餐區)

    • 訪存階段可以比作顧客就餐區,是顧客(指令)實際享用“菜品”(資料)的地方。服務員(記憶體控制器)負責將廚房準備好的“菜品”送到顧客面前,同時也會收集顧客的新訂單(讀取資料請求)。
  3. 從執行到訪存的流程

    • 當廚師完成一道菜的烹飪後(執行階段結束),服務員需要將這道菜送到顧客那裡(開始訪存階段)。這個過程可能需要一些時間,因為服務員要確保將正確的菜品送到正確的顧客手中(資料的正確讀取和寫入)。
  4. 等待和響應

    • 如果顧客正在等待一道特別的菜品,服務員可能需要從廚房獲取最新的烹飪狀態(執行階段的輸出)。一旦菜品準備好,服務員迅速將菜品送到顧客面前(訪存階段的記憶體響應)。
  5. 互動和依賴

    • 廚房的工作速度可能受到顧客需求的影響,如果顧客的訂單很複雜(複雜的計算指令),廚師可能需要更多時間來準備。同樣,如果顧客(指令)需要等待某些特殊食材(記憶體中的資料),服務員可能需要在廚房和就餐區之間多次往返。
  6. 效率和最佳化

    • 餐廳經理(CPU 控制單元)會不斷尋找提高服務效率的方法,比如透過最佳化廚房工作流程(執行階段的最佳化),或者改進服務員的送餐路線(訪存階段的記憶體訪問最佳化)。
  7. 處理特殊需求

    • 有時顧客可能需要特別定製的菜品(特殊訪存指令),這要求廚師和服務員之間有更緊密的合作,確保顧客的特殊需求得到滿足。

透過這個比喻,我們可以理解執行階段和訪存階段是 CPU 流水線中密切相關的兩個部分,它們協同工作以確保指令能夠高效、準確地執行。執行階段負責生成指令的結果,而訪存階段負責將這些結果寫入記憶體或從記憶體中讀取資料。兩者之間的有效協調對於整個 CPU 的效能至關重要。

資料冒險的產生可以形象地比喻為:

  • 廚師與服務員想象一個忙碌的餐廳,廚師(先行指令)正在準備一道菜(執行操作),而服務員(CPU控制單元)已經接到了另一位顧客(後繼指令)的訂單,要求立即上菜。如果服務員在廚師完成菜品之前就去取菜,就會一無所獲,因為菜品還未準備好。

為了避免資料冒險,CPU採用了多種策略,包括:

  • 資料轉發(Forwarding):允許資料直接從執行單元轉發到需要它的指令,而不需要透過暫存器。
  • 流水線暫停(Stall):在檢測到資料冒險時,暫停流水線的執行,直到所需的資料被寫回暫存器。
  • 動態排程(Dynamic Scheduling):在亂序執行的CPU中,透過動態地重新排序指令來避免資料冒險。
  • 靜態指令排程(Static Scheduling):在編譯時或指令編碼時,透過合理安排指令順序來減少資料冒險的風險。

資料冒險的處理是CPU設計中的一個關鍵問題,需要仔細考慮以確保指令的正確執行和效能的最最佳化。

相關文章