【操作系統】第六章:頁面置換算法(Part1:局部頁面置換算法)

局部頁面置換算法

功能:當缺頁中斷髮生,需要調入新的頁但是物理內存已滿,此時需要把當前一部分頁換出去,空出空間。選擇內存中哪一個頁被替換
目標:
1.儘可能減少換入和換出的次數。具體來說,把未來不再使用或者近期不會使用/較少使用的頁面換出,通常只能在局部性原理指導下依據過去的統計數據預測。
2.頁面鎖定。 有一些物理頁是需要常駐內存的,比如OS相關的代碼和數據,這些隨時都有可能訪問,那麼這些頁我們需要常駐訪問。我們用頁面鎖定技術,把相關的頁放在內存裏,使得這些頁不在頁面置換算法的考慮範圍內。
例子:
在這裏插入圖片描述
(3,0)這個序列的意思是訪問了第三個頁面的第0個便宜。也就說(頁序號,偏移量object)。我們這裏可以忽略他的偏移量,只考慮頁序號。因爲只有當一個頁不存在的時候,纔會產生缺頁中斷,才需要考慮頁面置換。在同一個頁裏面有多次訪問,只有第一次訪問纔有可能產生缺頁中斷,所以我們可以忽略偏移量只考慮頁號。

最優頁面置換算法

在這裏插入圖片描述
這個算法可以說是一個不太實際的算法,但是我們可以把它作爲一個評價標準。這個算法根據未來的情況進行推算,一般來說缺頁次數產生最少。一般我們用其他頁面置換算法運行後的結果與最優頁面置換算法比較,比較缺頁次數,只要能夠儘量逼近最優選法,我們就可以認爲這是一種比較好的算法。
在這裏插入圖片描述
根據最優頁面置換算法,由於訪問之前物理內存中已經存儲了abcd,所以前四次訪問不會改變物理內存中的頁。但是當第五次訪問發生時,根據換出距離下次訪問時間最長的頁,得應該換出d置入e,則此時物理內存中是abce,沒有d。則當下次訪問d時,應該換出最長等待時間的c。第十次訪問後,物理內存的頁編號是abde
在這裏插入圖片描述

FIFO先進先出

在這裏插入圖片描述
鏈表(List),典例是程序中的Queue。
產生缺頁中斷次數比較多。
Belady現象:當我們給一個程序分配更多的物理頁時,它的缺頁次數應該減少,但是FIFO可能會導致分配的物理頁越多,缺頁次數增加的現象。
在這裏插入圖片描述
先入先出原則,替換list中滯留時間最久的那一個。

內容 內容 內容 內容 時間點
a b c d 0
a b c d 1
a b c d 2
a b c d 3
a b c d 4
e b c d 5
e b c d 6
e a c d 7
e a b d 8
e a b c 9
d a b c 10

LRU最近最久未使用算法

在這裏插入圖片描述
和最長滯留時間不同,最長滯留時間是在物理內存中駐留時間很久,但是他可能在近期被訪問過;這個算法是換出在隊列中最長時間沒有被訪問的頁。根據程序局部性原理,在最近的一小段時間內,程序訪問的代碼和數據未來還有可能會繼續訪問,所以LRU就是合理的,因爲反推局部性原理,一段時間內沒用,那麼接下來一段時間也可能不會用到。
在這裏插入圖片描述
缺頁中斷:3次
*:較久訪問 標記越多,程序內優先級越高
粗體:置換/更新訪問,當內存內數據被訪問時,其替換優先級清零

訪問請求 c a d b e b a b c d 最終
默認a a a a* a** a*** a**** a a* a** a*** a
默認b b b b b b* b b* b b* b** b
默認c c c* c** c*** e e* e** e*** e**** d d
默認d d d d d* d** d*** d**** d***** c c c

LRU需要記錄各個頁面使用時間的先後順序,開銷比較大。目前有兩種可能的實現方法。
在這裏插入圖片描述
1.使用鏈表[List]。每當一個頁面被訪問時,如果內存中有這個頁,則將其放在首,最久訪問自然會在不斷換頭的過程中排序放在尾部。沒有的數據則淘汰鏈表尾部,然後插入首部。
例子:

內容 內容 更新
a b c d default
c a b d c
e c a b e
a e c b a

2.使用堆棧。
在這裏插入圖片描述
頁面置入棧頂後,查找是否有相同頁號這個過程開銷比較大。棧底一定是最久未被使用,所以需要替換時,直接替換棧底。
在這裏插入圖片描述
總結:LRU算法,結果雖然不錯,但是他的開銷比較大。他不是一個合適的實現方法,OS設計講究高效且簡潔,爲了實現效果而花費很大代價,則得不償失。需要一個平衡。

Clock時鐘頁面置換算法

LRU的近似,FIFO的改進。沒有LRU的精確,但是能夠近似的表明訪問的先後順序狀態的算法,開銷自然小很多。
頁表項中的acess位,訪問後0變成1,這個過程由硬件完成,不需要軟件參與。但是我們的軟件可以對其進行清零操作和置1操作。所以,當CPU訪問到這個頁的時候,會把acess bit置1。因此我們可以粗略估計,如果這個頁的acess bit 是1,我們就認爲他被訪問了,是0則認爲他沒有被訪問。只用了一個比特表示時間信息,雖然不精確但是有效。然後我們把程序訪問的所有頁面組成一個環形列表,並通過一個指針指向當前頁,並且探測他是否是近似最老的頁。老的判斷就是:因爲OS會定期把訪問位清零,你一旦訪問頁後CPU又會置1,然後看這個訪問位01狀態,0是老頁,就可以把這個頁換出去。
在這裏插入圖片描述
抽象成時鐘後,如圖所示,指針指向某一物理內存時,檢測其訪問爲是否爲1,爲1則將其置0且指針走向下一項。爲0則其頁幀就需替換出去。如果內存中有這一項且其訪問位爲0,則不需要指針轉動檢測,只需要將這一項置1即可。且這一操作不會導致指針轉動到下一個位置【指針位置不變】。
在這裏插入圖片描述
解析:

階段 變化
1~4 物理內存中有這一項,所以訪問位0=>1,指針不轉動,默認停在首位
5 由於物理內存中所有項訪問位均爲1,指針空轉一圈。此時所有訪問位置0,指針處於首位,指向a。此時更新頁幀(a->e)且將訪問位置1
6 b已存在於內存,更新訪問位爲1。指針不變,仍指b
7 指針指向b,將b置0後指向下一位。由於c訪問位爲0,則將c替換爲a並置1,指針向下一位移動。
8 更新b,指針不變,指向d
9 更新d爲c並置1.此時內存中所有訪問位均爲1
10 進行空轉一週,訪問位全部清0,此時指針將從頭開始旋轉,指向首部,替換第一個頁幀號。e=>d並置1

也就說當內存中訪問位全爲1時,該算法退化爲FIFO

二次機會法Enhanced Clock

Clock算法是對訪問進行標示,訪問其實就是讀寫。這一過程並不能區分讀和寫,只能區分大致是否訪問。因此對髒頁的處理代價就比較大。寫操作進行後,硬件會將髒位置1
髒位(dirty bit):如果頁是寫操作,置1;讀操作,置0
在訪問過程中,如果全是讀操作,就意味着內存中與硬盤中的內容是一致的。所以如果替換這一頁的時候,我們不需要寫回硬盤,只需要釋放內存空間(開銷小);但是如果這一頁在內存訪問過程中,是對這一頁進行寫操作,也就說內存與硬盤中內容可能不一致,我們替換這一頁時,需要把這一頁的內容寫會硬盤,來確保數據一致。
所以用上髒位,配合Clock算法可以來減少對硬盤的訪問(寫回操作的次數)
算法解析:
根據圖示在這裏插入圖片描述
只有髒位(圖中修改位)和訪問位(圖中使用位)均爲0時,纔會置換指針指向的頁,然後將其訪問位置1。當髒位和訪問位僅有一個1時,將這一個1置0,指針指向下一位。均爲1時,訪問位置0,髒位不變,指針下移。
也就說如果某一個頁他的兩個校驗位均爲1,指針經過他兩次纔會將其全部清零,也就說第三次纔會被置換。
在這裏插入圖片描述
通過這種算法,可以吧髒位(經常使用的頁)有更多的機會留在內存中,而不會被頻繁換入換出,而只讀頁會更優先的換出,使得被寫過的頁換出的概率減少,對硬盤的訪問次數也就隨之減少。這種算法修改了髒位,也就說每次替換都要寫回主存。
理解hit】相比較訪問位相同的頁,髒位爲1的頁將賦予它多一次機會,優先將讀操作的頁換出去。
圖示:aw中,w代表是這次訪問是寫操作。
在這裏插入圖片描述

階段 變化
1~4 物理內存中有這一項,所以訪問位0=>1,指針不轉動,默認停在首位
5 指針空轉一輪,然後從上到下分別變爲01 01 00 00,指針回到首部,開始掃,數據變爲00 00 c替換e 10 00 abed
6 b已存在於內存,更新訪問位爲1。00 10 10 00 指針不變
7 a的寫操作。11 10 10 00 abed
8 與7相同
9 更新d爲c並置1。 11 10 10 10 abec
10 進行空轉一週,訪問位全部清0,此時指針將從頭開始旋轉,指向首部,替換第一個頁幀號。d=>a並置1 01 10 00 00 adec

Belady現象

當我們給正在運行的程序分配的物理頁越多,它產生缺頁的次數應該越少。但是當採取了某些頁面置換算法後,物理內存分配的越多缺頁現象反而增加的現象。典例是FIFO。因爲FIFO替換的頁面不是當前程序近期不會訪問或者不常用的頁面,它置換出去的頁很可能接下來要使用。
在這裏插入圖片描述
如上圖所示,FIFO的頁面置換情況下出現的缺頁現象。

階段 變化
1~7 滿足FIFO條件,先進先出,發生缺頁後頭部替換出去且剩餘內容順位移動,在尾部加入當前要訪問的頁幀號
8~9 第七次訪問後,此時鏈表中的數據是1-2-5,此時再次訪問1和2這個已經存在於鏈表中的頁幀,這裏不會產生缺頁中斷但是整個鏈表沒有體現出時間相關的信息,此時1和2雖然是鏈表中放的比較久的頁,但是這裏並不能體現他們的駐留時間。它只體現了它存在的先後時間卻沒有體現動態訪問中訪問時間先後。
10~12 未命中,缺頁中斷,FIFO先入先出替換

上面是給鏈表設置了三個頁的空間,那麼如果我們設置多一個空間又會怎樣呢?理論上應該是缺頁次數更少纔對。
在這裏插入圖片描述
如圖,缺頁次數反而比之前更多了。這就是Belady現象。
反觀LRU算法
在這裏插入圖片描述
同樣的訪問序列,當在內存分三個頁幀時,產生了10次缺頁,當內存中頁幀分配量增加1時,只產了8次缺頁。也就說隨着物理頁幀空間的增加,缺頁次數減少了,LRU沒有Belady現象。
LRU算法符合棧算法的特點,棧算法的特點之一就是給的物理頁幀越多,它的缺頁次數越少。

FIFO/LRU/Clcok的比較

LRU和FIFO都是先進先出的思路,所以可以用鏈表或者棧來表示它的訪問次序和駐留時間,但是LRU算法除了滯留時間還考慮了最近訪問時間,所以當訪問到內存中已存在的頁幀時,他會將其置於head其他頁順序推移。這就是FIFO和LRU的最大區別。程序局部性特點越好,LRU算法就會產生越少的缺頁次數。但是如果程序沒有很好的局部性特點,則LRU會退化爲FIFO算法,甚至完全等價。
Clock算法是LRU算法的一種近似,用1-2位bit來模擬訪問時間,所以他有效逼近LRU算法且開銷小。
LRU算法開銷過大,FIFO性能不佳,所以折中我們會偏愛Clock算法。每一次訪問時,不必動態的去調整該頁面在鏈表中的順序,而僅需要做一個標記,然後等待缺頁中斷髮生時,再把它移動到鏈表尾部。對於內存中未被訪問的頁面,Clock與LRU一樣好。而對於訪問過的頁面,則比LRU算法差。

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