MIPS中的分支延遲槽

買了本SEE MIPS RUN LINUX 的中文版,翻譯的句子狗屁不通,什麼玩意兒。第一章就看不下去,越到關鍵的地方越讀不通。

http://hi.baidu.com/comcat/blog/item/c6f4f909cf551bc53ac76359.html

1. 概述

分支延遲槽 (Branch delay slot),簡單地說就是位於分支指令後面的一條指令,不管分支發生與否其總是被執行,而且位於分支延遲槽中的指令先於分支指令提交 (commit)。

看這個代碼片段 (MIPS Linux kernel 2.6.17):

801ea9d4: 02202021 move a0,s1
801ea9d8: 27a50014 addiu a1,sp,20
801ea9dc: 0c0ce551 jal 80339544 <pcibios_resource_to_bus>
801ea9e0: 02403021 move a2,s2
801ea9e4: 8e240010 lw a0,16(s1)

MIPS ABI 規定,a0, a1, a2, a3 用於過程調用的前四個參數,則 move a2, s2 是置第 3 個參數,但是其位於函數調用指令 jal 80339544(分支指令)之後,這個 move a2, s2 所在地即爲一個分支延遲槽。

分支延遲槽在 DSP 和歷史較悠久的 RISC 上比較常見,如 MIPS, SPARC 等。PowerPC 和 ARM 上則沒有這個概念。x86 亦沒有。

2. 緣起

引入分支延遲槽的目的主要是爲了提高流水線的效率。

流水線中,分支指令執行時因爲確定下一條指令的目標地址(緊隨其後 or 跳轉目標處?)一般要到第 2 級以後,在目標確定前流水線的取指級是不能工作的,即整個流水線就“浪費”(阻塞)了一個時間片,爲了利用這個時間片,在體系結構的層面上規定跳轉指令後面的一個時間片爲分支延遲槽(branch delay slot)。位於分支延遲槽中的指令總是被執行,與分支發生與否沒有關係。這樣就有效利用了一個時間片,消除了流水線的一個“氣泡”。

這種技術手段主要用在早期沒有分支預測的流水線 RISC 上,現代 RISC 實現早就可以在流水線的第 2 級利用分支預測確定跳轉的目標,分支延遲槽也就失去了原來的價值,但爲了軟件上的兼容性 MIPS 和 PowerPC 還是作了保留。

===============================

Q2:爲什麼延遲槽異常返回地址是上一條指令的地址
A2:
簡單說,一般CPU的分支跳轉指令流是:分支跳轉指令->目標跳轉地址的指令。
但MIPS的分支跳轉指令流是:分支跳轉指令 -> 延時槽指令 -> 目標跳轉地址的指令,在中間操作插入了延時槽指令。
如果PC在延時槽地址中斷後,中斷返回時返回延時槽指令地址的話,重新執行的指令流爲:延時槽指令 -> (延時槽指令地址 + 4)地址的指令,沒有跳轉了!
這樣完全不是原來被打斷的指令流,爲了恢復原來的指令流需要將延時槽前面的跳轉指令重新裝入流水線。
所以在延時槽中斷後返回的地址是前面跳轉指令的地址。

Q4:ASID是否真的全部有效,虛擬地址是如何進行地址翻譯的
A4:
1) 當G位爲1時,不再檢查ASID字段即是ASID字段無效。進程間共享內存實現應該是靠這個G位。
2) 虛擬地址翻譯過程:
將虛地址頁號和進程的ASID給MMU
MMU查找所有TLB項是否有匹配項,匹配過程如下(假設PageMark):
先匹配EntryHi,若VPN2相等而且ASID相等或G位爲1,匹配則根據頁表的最低位取出EntryL0(LSB位爲0)或EntryL1(LSB位爲1),不匹配則拋出TLB缺失異常。
接着匹配EntryLx,如果v位爲零拋出TLB無效異常,如果d位爲零而且是寫操作則拋出TLB修改異常,OS應該是利用這個實現寫是拷貝。
最後將EntryLx中的PFN和虛地址的頁內偏移組合成實際的物理地址。

Q5:如何把虛擬地址連續但物理地址不連續的兩個頁放到到同一個TLB項中
A5:
當進程申請兩個連續的虛擬頁時,其對應的物理頁可能是連續的也可能是不連續的。同時在內存中新建一個頁表項。
當在有這段虛擬地址範圍的地址需要翻譯時,將該頁表項從內存調入TLB中。
對於Linux kenerl由於採用寫時拷貝策略,申請虛擬頁面時並沒有即可分配對應的物理頁面,如前面QA4所述。

Q6:TLB項中的C字段有什麼作用
A6:
根據See MIPS Run 2nd的描述,應該是用於處理多處理器Cache同步問題,原文如下
A 3-bit field originally defined for cache-coherent multiprocessor
systems to set the “cache algorithm”

Q7:影子寄存器堆作用
A7:
一般的CPU在中斷處理程序開始之前需要保存CPU的上下文及CPU的寄存器。
MIPS提供了硬件的寄存器組堆棧,可以設置CPU在進入中斷時使用新的寄存器組,節省了一般CPU將寄存器組保存在軟件堆棧的過程,縮短中斷處理程序的時間。

Q8:EXL和ERL的不同
A8:
個人理解,EXL主要是邏輯上引起的,比如:各種TLB異常等。
ERL主要是物理錯誤引起的,比如cache檢驗錯誤等。

發佈了1 篇原創文章 · 獲贊 3 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章