【硬核】MMU是如何完成地址翻譯的
文章目錄

1. 什么是虛擬內存?
2. 虛擬內存的作用
3. 虛擬內存與物理內存
3.1 CPU存取數據
3.2 物理地址常用術語
3.3 虛擬地址常用術語
3.4 頁表常用術語
3.5 頁命中/缺頁
4. 為什么有了高速緩存,還需要TLB呢?
5. MMU是如何完成地址翻譯的?
5.1 準備工作
5.1.1 內存系統的基本條件
5.1.2 TLB
5.1.3 頁表
5.2 產生虛擬地址
5.3 構造物理地址
5.4 遍歷高速緩存
5.5 缺頁處理
6. 總結
虛擬內存是現代操作系統中最偉大的發明之一。它為每個進程提供了一個一致的、私有的地址空間,讓每個進程產生了一種自己在獨享主存的錯覺。
為了講清楚MMU是如何一步一步完成地址翻譯,取出數據的,本篇文章在前4節中講解了虛擬內存中一些重要的概念,比如,虛擬內存的作用,頁命中,缺頁異常處理,為什么需要TLB等等。最后,通過兩個地址翻譯的例子,詳細解釋了MMU地址翻譯的過程。
1. 什么是虛擬內存?
虛擬內存能夠創建一個連續的更大的空間給進程使用,出現的原因是由于主存的空間是有限。
當運行多個進程或者一個進程需要更大的空間進行存儲運行,主存顯然是不夠的,這個時候就需要更大更便宜的磁盤進行保存一部分數據。
對于進程來說,虛擬內存就是一張連續的內存空間,這個空間有些在主存中,有些在磁盤中。
2. 虛擬內存的作用
虛擬內存將主存看成是一個存儲在磁盤上的地址空間的高速緩存,在主存中只保存活動區域,并根據需要在磁盤和主存之間來回傳送數據,通過這種方式,可以高效地使用主存。
虛擬內存為每個進程提供了一致的地址空間,簡化了內存管理。
虛擬內存保護了每個進程的地址空間不被其他進程破壞。
3. 虛擬內存與物理內存
3.1 CPU存取數據
我們先來看下,CPU是如何根據地址取得數據的。
CPU 在這里生成的物理地址為 4,把地址發送給內存,然后內存從該地址獲取其中保存的字,最后將其發送回 CPU。
MMU(Memory Management Unit)叫做內存管理單元,主要用來管理虛擬內存與物理內存的映射,由硬件自動完成。
3.2 物理地址常用術語
這里需要比較燒腦地介紹幾個名詞,后面理解MMU地址翻譯的時候會用到。
物理內存(physical memory),主存RAM,實際能使用的物理空間。
物理頁(physical page),把物理內存按照頁表的大小進行劃分。
物理地址(physical address,PA), 物理內存劃分了根據物理頁劃分為很多塊,通過物理地址進行定位。
物理頁號(physical page number,PPN) ,定位緩存中的數據字。
物理頁號偏移 (physical page offset, PPO),定位緩存中的數據塊。
緩存標記(cache tag,CT),在高速緩存中作為行匹配。
緩存索引(cache index,CI),在高速緩存中作為組索引。
緩存偏移(cache offset,CO),在高速緩存中用作行內偏移來選擇目的數據塊。
物理頁號偏移PPO = 組索引CI + 行內偏移CO。
物理頁號PPN = 行匹配CT。
物理地址 PA = 物理頁號 + 物理頁號偏移 = PPN * page size + ppo。
3.3 虛擬地址常用術語
虛擬內存(virtual memory),每個程序獨有,存放在磁盤上,由多個虛擬頁(VP, virtual page)組成。
虛擬內存的地址編碼稱虛擬地址空間(virtual address space VAS),跟物理內存一樣,但虛擬內存是每個進程獨有的,其大小是根據操作系統的指令集位有關,如32位,64位,32位,每個進程就有4G,64位有個百億的GB。
虛擬頁(virtual page,VP ),把虛擬內存按照頁表的大小進行劃分。
虛擬地址(virtual address),通俗說是計算機進程加載地址的指令,進程給的虛擬地址通過MMU進行獲取地址計算物理地址空間,然后獲取物理地址對應的數據傳送到CPU上。
虛擬頁號(virtual page number ,VPN) ,用于定位頁表的PTE。
虛擬頁號偏移(virtual page offset VPO) ,跟PPO值一樣,定位物理內存的地址。
TLB索引(TLB index,TLBI),在頁表中作為組索引。
TLBT標記(TLB tag,TLBT),在頁表中作為行匹配。
虛擬頁號VPN = TLBT + TLBI。
虛擬地址 VA = 虛擬頁號 + 虛擬頁號偏移 。
3.4 頁表常用術語
頁表(page tables),虛擬地址與物理地址的對應表集合。進程虛擬地址轉換成物理地址,程序需要用到數據放在物理主存或磁盤某個位置,頁表是存儲在主存中。
頁表條目(page table entry PTE),虛擬地址與物理地址具體對應記錄。頁表是由多個頁表條目PTE組成的數組,PTE 由一個有效位 和 n位地址字段組成,如果設置了有效位,那么地址字段就標識DRAM中相應的物理頁的起始位置。
3.5 頁命中/缺頁
處理器產生一個虛擬地址。
MMU生成PTE地址,并從高速緩存/主存請求得到它。
高速緩存/主存向MMU返回PTE。
MMU構造物理地址,并把它傳送給高速緩存/主存。
高速緩存/主存返回所請求的數據字給處理器。
處理器產生一個虛擬地址。
MMU生成PTE地址,并從高速緩存/主存請求得到它。
高速緩存/主存向MMU返回PTE。
PTE中的有效位是零,所以MMU觸發了一次異常,傳遞CPU中的控制到操作系統內核中的缺頁異常處理程序。
缺頁處理程序確定出物理內存中的犧牲頁,如果這個頁面已經被修改了,則把它換出到磁盤。
缺頁處理程序頁面調入新的頁面,并更新內存中的PTE。
缺頁處理程序返回到原來的進程,再次執行導致缺頁的指令。CPU將引起缺頁的虛擬地址重新發送給MMU。因為虛擬頁面現在緩存在物理內存中,所以就會命中,主存就會將所請求字返回給處理器。
4. 為什么有了高速緩存,還需要TLB呢?
局部性原則保證了在任意時刻, 程序將往往在一個較小的活動頁面集合上工作,這個集合叫做工作集或者常駐集。
換句話說, 局部性原則揭示了一個現象:在一段時間內,我們會反復調入或調出同一個或幾個虛擬頁頁面。而且,每次CPU產生一個VA時, MMU就必須查閱PTE,以便將VA翻譯為PA, 注意是每次,所以開銷很大。
解決方法: 為了消除這樣的開銷,在MMU中包括了一個關于PTE的小緩存,稱為翻譯后備緩沖器,TLB(Translation Lookaside Buffer)。
關鍵點: 所有的地址翻譯步驟都是在芯片上的MMU中執行的, 因此執行速度非常快。
說了這么多,下面就是本文的重點,我們看兩個例子,虛擬地址是如何轉換為物理地址的。
5. MMU是如何完成地址翻譯的?
5.1 準備工作
假設我們有一個簡單內存系統,我們做出如下規定:
虛擬地址(VA):14 位
物理地址(PA): 12 位
頁面大小:64 字節
虛擬頁號(VPN):8位
虛擬頁面偏移量(VPO): 6 位(64 = 2^6)
物理頁號(PPN):6位
物理頁偏移量(PPO):6位
假設TLB 有 16 個條目,并且是 4 路組相連的。TLB 緩存的是頁表條目,頁表條目是虛擬頁號的唯一標識。所以,我們只需要用虛擬頁號去訪問 TLB。
我們使用 VPN 的低兩位(2^2=4)作為組索引。剩下的6位作為標記位。然后用不同的值來初始化 TLB。
左邊的紅色區域(第一個列)并不是 TLB 的條目,僅僅是為了方便區分是哪一組。
我們只根據索引來查找組,每一個條目都有一個標記位。一個 TLB 條目如果有效,它就含有一個物理地址。
現在,我們還需要頁表。假設,圖中是我們頁表的前 16 個條目。每一個頁表有一個物理頁號和一個有效位。
如果有效位有效,則表示那個虛擬頁面對應的物理頁面在內存中,并且 PPN 項給出了對應的物理頁號。
5.2 產生虛擬地址
假設 CPU 執行了一條指令,它產生了一個有效地址 0x3d4。它把這個地址傳遞給了 MMU。
我們需要找出對應的物理地址,然后從緩存或內存中取出數據。
在這個例子中,虛擬頁面偏移(VPO)是0x24,虛擬頁號(VPN)是 0xf,TLB 索引(TLBI)是虛擬頁號的低兩位是 0b11,也就是 0x3。TLB 標記位(TLBT)是 3。
MMU 做的第一件是就是查詢 TLB,所以,我們先取出索引位,值為 3。
我們找到第 3 組,我們在第 3 組中找標記位為 3 的表項。
遍歷這 4 個條目,有一個標記位為 7 的項,但它不是我們想要的,它的有效位為 0。再往后找,找到一個標記位為 3 并且有效位為 1。
所以,我們在 TLB 中找到了頁表條目。頁表條目返回這個值。MMU 返回的物理頁號是 0x0D。
5.3 構造物理地址
現在我們可以構造物理地址,PPO的值總是等于VPO的值,可以直接拷貝過來,為0x24。
PPN的值從 TLB 緩存的 PTE 中得到,為0x0d。合在一起構成了物理地址 0x354。
下一步是使用這個物理地址去看高速緩存中有沒有這個物理地址的緩存。
5.4 遍歷高速緩存
把 0x354送入高速緩存,請求高速緩存返回對應物理地址上的值,在這個例子中,我們只需要返回一個字節。
高速緩存收到請求后,首先去檢查高速緩存中是否有塊緩存了該字節。
高速緩存先取出物理地址的索引位是 0b00101,也就是 0x5。
接著去第 5 組找。找標記位為 0xd 的項,有一個匹配的標記位且有效位為 1。這就是我們要在高速緩存中找的項。
偏移量是 0,所以我們去請求第五組偏移量為 0 的字節,值為 0x36。
緩存命中,高速緩存把這個字節返回給 MMU, MMU 把它傳遞給處理器。最后處理器可能把這個字節存儲在一個寄存器里。
以上就是一個完整的地址翻譯的例子,在這個例子中,并沒有出現缺頁的情況。
下面我們看一個在缺頁異常處理中,是如何完成地址翻譯的。
5.5 缺頁處理
好了,我們來看下一個例子。這次 CPU 發送給 MMU 的虛擬地址是 0x0020。
和之前的例子一樣,我們可以得到VPN為0x00,VPO為0x01,TLBI為0,TLBT為0x00。
第一步是檢查 TLB 看是否有頁表條目的緩存。
在 TLB 中,如果緩存存在,它應該在第一組,并且它的標記位應該為 0。所以,我們在第 0 組內找標記位為 0 的項。
第一項是 0x03,不匹配,第二項是 0x09,不匹配,第三項是 0x00,匹配,但是有效位為 0。所以,這次 TLB 緩存不命中。
查找緩存失敗了,我們只能去內存中去讀取頁表中對應的頁表條目。
查看頁表,尋找虛擬頁號為 0 的項。檢查對應的頁表條目,看虛擬頁是否在內存中。
虛擬頁號為 0 的項的有效位為1,我們就可以得到一個物理頁號為0x28。根據物理頁號和物理頁面偏移量就可以構造出物理地址。
現在 MMU 擁有了物理地址,就可以將其發送到高速緩存。并請求高速緩存返回對應的物理地址上的一個字節。
高速緩存得到了這個物理地址。它取出對應的索引位,在這個例子中是 0x8。
所以我們去高速緩存的第八組,然后尋找對應的標記位,在這個例子中是0x28。
第八組有一個條目,它的標記位是 24,這里是一次緩存不命中。
所以,緩存就要向內存傳遞物理地址去得到所需要的字節。相關內容本篇就不再做具體講解,可以參考下這篇文章。24張圖7000字詳解計算機中的高速緩存
6. 總結
虛擬存儲器的工作原理是有一些復雜,本文描述的也并不全是最真實的計算機中的工作方式,比如,PTE由一個有效位和一個地址字段組成其實是為了便于理解而假設出來的。
但是這種方式成功的解決了直接使用物理內存會出現的問題。比如,虛擬內存中連續存儲解決了物理內存碎片化,資源利用率過低的問題;每個進程只能訪問自己獨立的用戶空間而內核空間是共用的解決了進程間的安全問題;缺頁異常和選擇犧牲頁的算法提高了內存讀寫的效率等等。
我們應該對虛擬存儲器的工作原理有深層次的理解,可以更好的幫助我們理解系統是如何工作的,也可以幫助我們避免在使用malloc這類的管理虛擬存儲器的分配程序時遇到的一些錯誤。
本文參考 《深入理解計算機系統》
機器翻譯 虛擬化
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。