【梳理】計算機組成與設計 第4章 處理器 第3節 異常(內附文檔高清截圖)

配套教材:
Computer Organization and Design: The Hardware / Software Interface (5th Edition)
建議先修課程:數字邏輯電路、C / C++、彙編語言。
這是專業必修課《計算機組成原理》的複習指引。建議將本複習指導與博客中的《簡明操作系統原理》配合複習。
在本文的最後附有複習指導的高清截圖。需要掌握的概念在文檔截圖中以藍色標識,並用可讀性更好的字體顯示 Linux 命令和代碼。代碼部分語法高亮。
計算機組成原理不是語言課,本複習指導對用到的編程語言的語法的講解也不會很細緻。如果不知道代碼中的一些關鍵字、指令或函數的具體用法,你應該自行查找相關資料。


第三節 異常

26、異常(exception)有時也稱中斷(interrupt),是指除了分支和跳轉以外的改變正常指令流的指令執行過程。最初,異常的設計是爲了處理意外事件,例如算術溢出。後來,這個機制被用於處理IO設備(見第5章)與CPU的通信。
Intel x86統一將內中斷和外中斷稱爲中斷,但按照MIPS的傳統,內部和外部中斷統稱異常,而外部中斷稱中斷。
以下是5種常見異常的來源及其對應的MIPS術語:

27、MIPS處理器包含一個異常程序計數器(EPC)。當產生異常時,引發異常的指令地址會被記錄於此,然後控制權被移交至操作系統。然後操作系統再繼續處理:可以爲用戶程序提供相應服務,執行一些預定義的動作,或者停止異常程序並報錯。動作完畢後,可以選擇結束程序或繼續執行。

28、MIPS使用一個狀態寄存器(status register,或稱原因寄存器(cause register)),來保存引發異常的原因。
另一種方法是向量化中斷(vectored interrupts)。每個中斷被分配一個唯一的編碼(中斷類型碼)。當設備發生中斷時,把編碼發送給CPU,通知CPU應該調用哪一個中斷處理程序(interrupt handler / interrupt service routine)。中斷向量中保存了每個中斷處理程序的入口地址。CPU根據中斷碼獲得相應的中斷向量號,然後根據中斷向量表(interrupt vector table)所在的地址和中斷向量號去查找中斷向量表獲得相應中斷號的中斷程序地址,進一步執行對應的中斷處理程序。

29、一個流水線化的CPU將異常當作另一種控制衝突。例如:當一個加法指令產生了算術溢出時,把跟在加法指令後面的指令清除掉,然後在新的位置重新取指令。這個方法也是分支預測失敗時的處理方法。
指令會不會產生異常,一般是在執行完畢後纔可以判斷的。所以產生異常以後要給出相應的控制信號,不要讓計算結果傳入下一級。
如下圖,控制單元中給出三個信號IF.Flush、ID.Flush、EX.Flush,用於產生異常後阻止數據繼續傳輸給接下來的硬件單元。在PC之前多了一個MUX,用於決定輸入正常的指令地址還是異常處理程序的地址。
當然,產生異常的指令的下一條指令要保存下來,以便在決定繼續執行時能回到正確的位置。

30、現代CPU一般可以在同一週期同時執行多條指令,因此在同一個時鐘週期內,可以有多條指令同時發生異常。這時候,要爲不同的異常設置優先級。當不同優先級的異常同時發生時,總是處理優先級最高的異常。
異常程序計數器會存儲引發中斷的指令的地址,MIPS原因寄存器記錄一個週期內的所有異常。異常處理軟件必須把異常與引發異常的指令對應起來。具體來說,有的異常,例如未定義指令(undefined instruction)異常,在譯碼階段就會產生,並在執行階段時交由操作系統處理異常;算術指令通常在執行階段纔會產生異常。根據產生異常的階段不同可以幫助區分一個異常是由流水線上的哪條指令引起。

31、異常處理必須由硬件和操作系統配合。硬件阻止異常指令,清除該指令之後的指令,而使該指令之前的指令正常完成,並設置寄存器來標示異常原因,保存異常指令的地址,並跳至事先編排好的異常處理程序。操作系統查看異常原因並相應處理。對於未定義指令、硬件失敗或計算溢出,OS一般結束進程並返回出錯原因(C / C++編寫的程序在計算溢出時不做任何動作)。如果IO設備請求系統服務,OS需要保存現場,處理相應的請求,然後恢復現場,令程序繼續執行。如果程序正在進行IO,OS要將其阻塞(block),待IO結束後再繼續。

32、現代CPU一般具有多級流水線,而一個指令進入流水線後不能馬上判定異常,所以當異常被探測到後,PC已經指向異常所在的位置之後。使用非精確異常(imprecise exception)機制的處理器在檢測到異常後,傳遞的EPC的值並不指向發生異常的那一條指令。
非精確異常的硬件比較簡單。一種實現方案是:允許已進入流水線中的指令執行完畢再轉去執行中斷處理。無論在指令的哪一流水段上發生異常,都不再允許後繼指令進入流水線,斷點爲最後進入流水線的那條指令的地址(非精確)。不同的流水線階段發生異常時,EPC的值與異常指令的實際地址的差不同。
如果等待已經進入流水線的指令執行結束再暫停程序並處理異常,而不是一旦發現異常就立即暫停程序運行並轉至異常處理程序,可能會導致程序出錯:

另一種實現方案是:將異常指令的後續指令排空。步驟如下:
·暫停指令流中導致異常的指令
·執行完異常指令之前的所有指令
·清除異常指令之後的所有指令
·記錄異常原因
·保存斷點
·轉異常處理程序
在探測到異常後,該方法不允許後續指令繼續執行,直到異常處理完畢。
這兩種實現方法的共同缺點也是非精確異常的缺點:異常響應時間較長、程序調試不便(程序員在某條指令設置斷點,但程序不能準確中斷在所設置的斷點處)。
要實現精確異常(precise exception),硬件開銷就比較大:因爲需要安全暫停流水線,也就是說要完整保存當前的狀態,在異常處理完畢後必須得以恢復該狀態並繼續執行。這需要大量後援寄存器保存流水線中各指令的現場(包括寄存器堆、PSW(程序狀態字)、流水段寄存器(含各段的控制寄存器))。
MIPS採用提交點技術實現精確異常。提交點爲內存訪問段。由流水線中最深的指令引起的異常,優先級最高,因爲指令在流水線中越深的階段,表示該指令越早執行(即使晚執行的指令先發生異常,也需要先處理更早進入流水線的指令的異常)。先發生的異常並不立即處理,只是被標記。保持流水線的異常標記直到提交點(M段)。
在分支預測中,當預測分支中出現了異常,而後由於預測錯誤而取消該指令時,需要取消異常。
無論是非精確異常還是精確異常,發生異常後,異常指令之前的指令都可以執行完畢。

33、異常亦可分爲可恢復異常和不可恢復異常。可恢復異常在處理完畢後令程序繼續執行,不可恢復異常處理後,程序被終止。

34、MIPS的異常一覽:

35、MIPS的幾乎所有異常的處理程序入口都爲0x80000180h,不過也有例外。例如TLB(翻譯後備緩衝)未命中(TLB-miss)的異常處理程序的入口地址就在0x80000000。這樣的設計是出於提升性能的考慮。
在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章