頁表(含二級頁表、倒排頁表)
1. 分頁機制的基本概念
-
分頁的原因:固定分區會產生內部碎片,動態分區會產生外部碎片,這兩種技術在內存上的使用都是低效的。
-
分頁的基本思想:內存被划分成大小相等且固定的塊,塊相對較小,作為主存的基本單位。每個進程也以同樣大小的塊為單位進行划分。
這樣,進程只有在為最后一個不完整的塊申請一個主存塊空間時,才產生主存碎片(內部碎片),這種碎片相對於進程來說很小。每個進程平均只產生半個塊大小的內部碎片。
分頁不會產生外部碎片。
-
分頁的幾個基本概念
-
頁和頁大小
-
頁(page):進程中的塊稱為頁。
-
頁框(page frame,也稱為頁幀):內存中的塊稱為頁框。
-
進程在執行時需要申請主存,即要為每個頁分配主存中的可用頁框,這就產生了頁和頁框的一一對應。
-
頁大小應該適中。頁太小會導致進程的頁數過多,頁表過長,占用大量內存。頁太大會導致內部碎片增多,降低內存利用率。
規定頁和頁框大小必須是 2 的冪,方便划分頁號和偏移量。
-
-
頁表(page table)
- 操作系統為每個進程維護一個頁表,頁表給出了該進程每頁所對應的頁框位置。
- 給出邏輯地址 <頁號,偏移量> 后,處理器使用頁表得到物理地址 <頁框號,偏移量> 。
2. 二級頁表
-
目的:克服頁表占用過大內存空間的問題,壓縮頁表。
例如,對於 64 位的 CPU,若頁面大小為 4 KB,則頁表有 2^52 個表項,如果每個頁表項占 8 字節,則整個頁表需要占用 8 * 2^52 Bytes = 32 PB 存儲空間!實際中不可能把那么大的 頁表放入連續的內存中。若不把這些頁表放入連續的內存空間中,則需要一張索引表來告訴我們第幾張頁表該上哪里去找,這能解決頁表的查詢問題,且不用把所有的頁表都調入內存,只在需要它時才調入。
建立多級頁表的目的在於建立索引,以便不用浪費主存空間去存儲無用的頁表項,也不用盲目地順序式查找頁表項。
采用多級頁表時,最高級頁表不能超出一頁大小。
若采用二級頁表(如 32 位的 x86 CPU),則頁號被划分成兩個域:PT1 和 PT2
頂級頁表(內存中)以 PT1 為索引,其表項指向二級頁表,二級頁表以 PT2 為索引
除頂級頁表外的其他頁表可以在內外存間交換
對 64 位處理器,一般采用三級頁表
Linux 為了通用,采用的也是支持 64 位處理器的三級頁表結構,對 32 位CPU,可以通過設中間頁表的表項個數為 1 來解決。
-
具體實例
操作系統使用 32 位地址,虛擬地址空間大小為 4 GB (2^32),頁大小為 4 KB (2^12),則虛擬地址空間由 2^20 頁組成,每個頁表項映射的大小為 4 B。
那么,一個用戶頁表有 2^20 頁表項,大小為 2^20 * 4B(頁表項大小) = 4 MB。由於在二級頁表機制中,頁表和其他頁都服從分頁管理,因此用戶頁表由 4 MB(用戶頁表內存大小) / 4 KB(頁大小) = 2^10 頁組成。
由於用戶頁表有 2^10 頁,我們再用一個頁表(根頁表)來映射用戶頁表,就需要 2^10 個頁表項映射。根頁表大小為 2^10 * 4 B = 4 KB (2^12) 。
那么,一個 4B 的根頁表項究竟能對應多大的用戶內存呢?
- 1 個根頁表項可以映射到 1 頁的用戶頁表。
- 而 1 頁的用戶頁表又包含了 4 KB(頁大小) / 4 B(頁表項大小)= 1k 項頁表項映射。
- 每個頁表項可以映射到 1 頁的用戶內存。
所以,1 個根頁表項可以映射到 1k * 4 KB = 4 MB 用戶內存。可以看到使用二級頁表,每個頁表項可以映射到更多的內存空間了(從 4 KB 擴大為到 4 MB)。
對於上述提到的方案,虛擬地址的前 10 位用於檢索根頁表,查找關於用戶頁表的頁的頁表項。
-
若該頁不在內存中,則發生一次缺頁中斷。
-
若該頁在內存中,則用虛擬地址中接下來的 10 位檢索用戶頁表項頁。
-
3. 倒排頁表
前述頁表設計的一個重要缺陷是,頁表的大小與虛擬地址空間的大小成正比。
頁表結構稱為倒排的原因是,它使用頁框號而非虛擬頁號來索引頁表項。
-
實際內存的每個頁框對應一個頁表項(而不是每個虛擬內存的頁有一個頁表項)
-
頁表項的內容為(進程ID,頁號)= (n, p),記錄定位於該占用頁框的進程號和頁號
-
優點——當物理內存較小時,反向頁表可大量節省空間
-
缺點——從虛擬地址轉換到物理地址變得非常困難(不能使用CPU所提供的頁框號映射機制,得自己搜索整個反向頁表,查找對應於頁表項 (n, p) 的頁框號)
具體請看書 P218
4. 轉換檢測緩沖區(Translation Lookaside Buffer,TLB)
原則上,每次虛存訪問都可能會引起兩次物理訪問:一次取相應的頁表項,另一次取需要的數據。
為克服這個問題,使用一個高速緩存,通常稱為轉換檢測緩沖區(Translation Lookaside Buffer,TLB)
使用TLB的地址轉換工作原理:
1. 給定一個邏輯地址,CPU首先到TLB去檢查,判斷頁號在不在其中。
2. 若在(命中,hit),則直接從 TLB 中提取頁框號並形成物理地址。
3. 若不在(不中/未命中,miss),則按普通訪問頁表方式工作,形成物理地址,並更新TLB(用新找到的頁表表項替換一個TLB表項)。
不使用TLB地址轉換工作原理:
1. 由頁號去頁表檢查該頁在不在內存(P位)。
2. 若在,則形成物理地址。
3. 若不在,則產生頁錯誤(Page Fault)並發出缺頁中斷,由OS將頁調入內存並更新頁表,進而形成物理地址。