【操作系統】第四章:非連續內存分配(Part2:頁表)

頁表的結構

在這裏插入圖片描述
本質是一個大數組。索引就是頁號,索引對應的內容就是幀號。
特殊的bit:Flags(標誌位)
存在位,修改位,引用位等:邏輯地址空間很大,可能有一部分邏輯地址空間是沒有到對應到物理地址空間的,那麼這個時候他的存在位的屬性就應該是不存在了。假設爲0【1代表存在0代表不存在】。還有比如代表讀寫的情況,會有一系列的表示方法來表示這些特殊屬性。
在這裏插入圖片描述
實例分析:
216B(byte)=210B26=26KB=64KB2^{16}B(byte)=2^{10}B*2^6=2^6KB=64KB
內存空間大小:16位系統:16byte(64KB),但是物理內存只有32KB【1KB=1024B,1B=8bit】
他們的頁內偏移是一樣的,因爲頁的大小是一樣的,頁的大小和頁幀的大小都是1024byte(1K)。在這種情況下邏輯頁的兩個地址(4,0)和(3,1023)分表表示頁號是4偏移量是0對應的物理頁幀的頁號是3,頁內偏移是1023對應的物理頁(頁幀)的地址是多少。
在這裏插入圖片描述
首先CPU開始找這個地址,第一個的存在標誌位是0,代表當前物理頁幀不存在,這個頁對應的頁幀不存在,沒有這個映射關係,此時CPU如果訪問了這個地址會產生一個內存訪問異常。第二個的存在位是1,對應的物理頁幀確實在物理地址中存在,然後就可以查到他的頁幀號(這裏是00100也就說是4),然後映射出來頁幀內偏移是1023【和頁的頁內偏移量相等】,此時結合公式計算可得:

Addr.physical=2Sf+o=2104+1023Addr.physical=2^S*f+o=2^{10}*4+1023
內存非法訪問:一般會殺死進程。【存在位屬性爲不存在時,內存訪問異常會發生】

頁表機制的性能問題

分頁機制存在性能問題,主要是空間的代價問題。
1.我們希望空間佔用越小越好
2.執行速度越快越好
頁表訪問:訪問一個內存單元需要兩次內存訪問,一次用於獲取頁表項,一次用於訪問數據。
現在的計算機64位很常見,64位機器如果每頁1024Byte,那麼一個頁表會是264÷210=254KB2^{64}\div2^{10}=2^{54}KB 現在的一般計算機是完全無法存下這樣一個頁表的。
計算機內存中同時跑多個程序,爲了有效地實現地址空間的隔離,我們需要每一個運行的程序都有自己的頁表,所以頁表所佔的空間也相應增加。頁表的整個組織空間過大,就不能放在CPU裏,因爲CPU的Cache很小。那麼就需要把頁表放到內存裏,那麼每次尋址都要訪問一次頁表要訪問兩次內存,這也存在不小的開銷。因此我們需要一些對策。
一般由兩種處理方法:
1.緩存:我們希望把常用的數據緩存到距離CPU距離比較近的地方(比如Cache,可以提高訪問速度)
2.間接(Indirection)訪問:通過多級頁表機制可以有效緩解頁表空間佔據過大的問題

頁表的時間問題

TLB:Translation Look-aside Buffer.快表
CPU裏的MMU(內存管理單元)有TLB,是一個cache,他緩存的是頁表裏的內容。TLB是一個特殊的區域,位於CPU內部,它包含了兩項(p和f)。p是key,f是value,這兩部分形成了一個TLB的表項;而TLB的表項是有相關存儲器(associative memory)來實現的,具備快速訪問功能,可以併發查找,但是容量有限,執行代價較大。可以把當前/經常用到的頁表項放入TLB,這樣每次訪問就不需要訪問頁表了。
在這裏插入圖片描述
當CPU得到一個邏輯地址,首先根據p查找TLB,如果TLB裏有p則可以直接找到f,然後f加上頁幀偏移量o就可以直接得到物理地址,然後找內存中對應的地址和內容,這樣就避免了一次對頁表的訪問。但是TLB容量有限,總有訪問不到的情況,此時TLB miss,這時候會再去查頁表,若存在(存在位爲1),則取回frame number,然後用一個TLB表項來存儲和緩存這一數據。這時也使得TLB本身效率提高。通過TLB,我們可以儘量避免對內存頁表的訪問,降低整體開銷。
miss之後,把頁表的項存入TLB的這個過程是由操作系統完成的。(MIPS);但是如果是x86系統,則是由硬件本身(CPU)完成的,這兩種情況都存在。

頁表的空間問題

多層次多級頁表可以有效緩解空間開銷大的問題。

二級頁表

在這裏插入圖片描述
偏移量object不變,但是把頁號再分爲兩塊,p1和p2對應的分別是一級頁表和二級頁表的頁號,拆分使得對一個大地址的尋址變成對N個小頁表的尋址。
CPU尋址,會先找一級頁表,一級頁表的起始地址CPU是知道的,只要把p1作爲index(索引)可以查找對應的一級頁表的頁表項,一級頁表的頁表項存儲的是二級頁表的起始地址(基址)。二級基址知道後,會根據二級頁表的p2(作爲index)找到對應p2的頁表項。二級頁表項的表項內容就是頁幀號(Frame number),又因爲頁內偏移量和幀內偏移量是一樣的,所以此時只需要加上偏移量o就可以獲得完整的物理地址。
這個處理過程又多了一次尋址、查找、處理且頁表都放在內存中,看似開銷很大,但是這種方式使得某些不存在映射關係的頁表項就沒必要佔用內存了。如果p1中的存在位是0,那麼就沒有對應二級頁表中某項的必要了。如果是單一頁表,即使映射關係不存在,對應的空間仍然需要保留在頁表中,這樣就可以極大節省了存儲空間。

多級頁表

在這裏插入圖片描述
進一步細分。一級頁表的頁表項對應二級頁表的基址,二級頁表的頁表項對應三級頁表的基址,三級頁表的頁表項對應頁幀號。這種結構可以表示一個更大的地址空間。頁表級數越多,訪問開銷會越來越大,時間花的很多,空間也省的很多。這種情況下我們需要結合前面的TLB來節省時間開銷。

反向頁表

頁表大小和邏輯地址空間大小有直接關係,邏輯空間越大,那麼對應的頁表就越多。訪問的開銷也就相對越大,當地址空間足夠大時,訪問開銷也將非常大
大地址空間問題:
那麼我們爲什麼不試着去讓頁表與物理地址空間建立對應映射關係呢?我們設計一個數據結構,它的存儲信息容量與邏輯地址空間大小無關的同時,還要建立物理與邏輯地址空間的映射關係。前面的所有方式都是用邏輯頁號做index,反頁表就是把物理頁幀表做index。
在這裏插入圖片描述
頁寄存器:也是一個數組。這裏的index是頁幀號(物理頁號),對應的表項內容是頁號(邏輯頁號)。正好反過來,這種方式使得寄存器的容易只與物理地址的大小相關,而與邏輯地址空間的大小無關。這也就限制了寄存器數量。
但是這裏存在的問題:
我們查找是根據頁號來找頁幀號,我們用這種數據結構的話,怎麼去找到頁號所在的位置呢,因爲我們只得到了以頁幀號爲索引的數組(通過頁幀號找到頁號)。 【也就說怎麼根據頁號找到頁幀號】

在這裏插入圖片描述
例子:
物理內存大小:16MB(4K4K)
頁幀數(size):4K
頁寄存器使用的空間:(假設8字節/寄存器):4K
8=32K
那麼頁寄存器帶來的額外開銷就是32K/16M=0.2%
確實內存開銷比較小。

基於關聯內存的方案:

在這裏插入圖片描述
p是頁號,值是頁幀號,但是開銷太大。設計成本太大,關聯存儲器用到的硬件邏輯很複雜,導致容量不可能足夠大。如果幀數較少,可以通過關聯存儲器儲存頁寄存器。在關聯存儲中查找邏輯頁號,成功則頁幀號被提取,失敗則返回頁錯誤異常(Page fault)
存在的問題:
在這裏插入圖片描述
所以這種方式不夠實用。

基於哈希計算的反向頁表:

在這裏插入圖片描述
把關聯存儲器中通過頁號查找頁幀號的過程通過哈希計算來實現。哈希表是一個數學計算方法,只要給哈希函數一個輸入值,那麼就應該有一個輸出值。這裏的輸入值是頁號,輸出就是頁幀號。哈希可以用軟件計算也可以用硬件加速,爲了效率明顯應該選擇硬件加速。
爲了提高效率,我們增加一個PID【當前運行程序的ID】,算出對應的幀號。關聯存儲器的變成了繼續哈希表的組織,這種方式可以有效緩解映射開銷。當然相對而言這種方式還是有問題,查找的時候雖然可行,但是查找的時候會出現哈希衝突,也就說一個輸入可能會對應多個輸出(不同的輸入可能存在相同輸出)。這就需要明確多個頁幀號到底選哪一個,這也就強調了爲什麼要通過PID來解決這個問題。
在這裏插入圖片描述
反頁表放入內存,所以哈希計算也需要從內存取值,也就說內存的開銷仍然大,爲此還需要一個類似TLB的機制來降低訪問反頁表的時間。
整個系統只需要一個反頁表,因爲使用頁幀號做的映射表,所以相對而言比多級頁表在空間上節省了很多。但是他需要有高效的哈希計算函數,以及解決衝突的機制,才能讓訪問效率得到保障。這種機制就是軟件硬件相互配合,在空間和時間上取得一個比較好的結果。

段頁式存儲

段式存儲在內存保護方面有優勢,頁式存儲在內存利用和優化轉移到後備存儲方面有優勢。所以,二者的結合:段頁式儲存。兼顧了段式在邏輯上的清晰和頁式在管理上方便的特點
在這裏插入圖片描述

在這裏插入圖片描述

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