標籤:tlb mmu cache
MMU中TLB的作用:
從虛擬位址到物理地址的轉換過程可知:使用一級頁表進行地址轉換時,每次讀/寫資料需要訪問兩次記憶體,第一次訪問一級頁表獲得物理地址,第二次才是真正的讀/寫資料;使用兩級頁表時,每次讀/寫資料需要訪問三次記憶體,訪問兩次頁表(一級頁表和二級頁表)獲得物理地址,第三次才是真正的讀/寫資料。
上述的地址轉換過程打打降低了CPU的效能,有沒有辦法改進呢?程式執行過程中,所用到的指令、資料的地址往往集中在一個很小的範圍內,其中的地址、資料經常多次使用,這稱為程式訪問的局部性。由此,通過使用一個高速、容量相對較小的儲存空間來儲存近期用到的頁表條目(段/大頁/小頁/極小頁描述符),以避免每次地址轉換時都到主存去尋找,這樣可以大幅度地提高效能。這個儲存空間用來協助快速地進行地址轉換,稱為“轉譯尋找緩衝”(TLB)。
當CPU發出一個虛擬位址時,MMU首先訪問TLB,如果TLB中含有能轉換這個虛擬位址的描述符,則直接利用此描述符進行地址轉換和許可權檢查;否則MMU訪問頁表找到描述符後再進行地址轉換和許可權檢查,並將這個描述符填入TLB中(如果TLB已滿,則利用round-robin演算法找到一個條目,然後覆蓋它),下次再使用這個虛擬位址時就可以直接使用TLB中的地址描述符了。
Cache和MMU:
按照工作原理來分,cache有physical index physical tagged, virtual index virtual tagged, physical index virtual tagged等幾種工作方式。
Physical index physical tagged是一種最容易理解的操作方式,cache針對物理地址進行操作,簡單粗暴,而且不會有歧義。但是這種方式的缺陷也很明顯,在多進程作業系統中,每個進程擁有自己獨立的地址空間,指令和代碼都是以虛擬位址的方式存在,cpu發出的memory access的指令都是以虛擬位址的方式發出,這樣的話,對於每一個memory access的操作,都要先等待MMU將虛擬位址翻譯為物理地址,這是一種串列的方式,效率較低。
Virtual index virtual tagged是純粹用虛擬位址來定址,這種方式帶來了更多的問題,每一行資料在原有tag的基礎上都要將進程標識加上以區分多個進程之間的相同地址,而在處理共用記憶體時也比較麻煩,共用記憶體在不同的進程中的虛擬位址不相同,如何同步是個問題。
virtual index physical tagged方式現在使用的比較多,virtual index的含義是當cpu發出一個地址請求之後,低位地址去和cache中的index匹配(因為低位一般都是頁內位移地址,不影響頁的選擇), physical tagged是指虛擬位址的高位地址去和mmu中的頁表匹配以拿到頁的物理地址,這樣保證了Cache和MMU並行工作。然後用從mmu中取到的頁物理地址作為tag(或者tag的一部分)去和cache line的tag位匹配,這樣既保證了同一地址在cache中的唯一性(有個例外,cache alias)又能將mmu和cache並行工作,提高了效率。這種方式帶來的唯一問題就是cache alias,當cache alias在cache大小同記憶體頁框大小不一致時,比如說每路cache的大小是8k,而現在較為常用的頁框大小是4k,這兩個數字說明的問題分別是這樣的:
頁框大小為4k意味著mmu在劃分虛擬空間時是以4k為粒度,每一個4k對齊的記憶體地區作為記憶體配置的最小單位,於是就有了這樣的結果,虛擬位址和物理地址的低12位是相同的,因為低12位地址是作為其在4k頁框內的位移,不管它的虛擬位址是什麼,它在4k頁面內的位移是一定的。
Cache大小為8k,意味著cache index是用依據13位地址來運算的,而如果以虛擬位址來定址cache,低13位中就包含了一位虛擬位址,所以這種方式稱為virtual index。問題出現了,一個物理地址當它被不同進程使用時,由於mmu分頁機制僅能保證其低12位相同,那麼第13位很有可能是不同的,這樣就造成了一個物理地址在cache中有兩個副本,可能會造成同步問題。
針對於cache alias問題,目前的方案是由作業系統來保證,對於同一物理地址在不同進程空間的虛擬位址,他們的虛擬位址的差一定是cache大小的整數倍,也就是說他們的第13位一定是相同的。同時已經有些cpu廠商在開發監視模組,試圖在硬體層面解決類似的同步問題。
MMU(TLB)與Cache的工作方式