頁面置換算法詳解(10種)


    如果對於虛擬內存,頁表,分頁等技術還是一知半解的道友可以參考我之前寫的一篇博客: 虛擬內存、分頁以及頁表,建議讀者從頭往后讀,有的頁面置換算法是對前面頁面置換算法的修改或者性能提升。
       當發生缺頁中斷時,操作系統必須在內存中選擇一個頁面將其換出內存,以便為即將調入的頁面騰出空間。

 

1. 最優頁面置換算法

       此算法不可能實現。在發生缺頁中斷的時候,在內存中的頁面有的很快就會被訪問,而有的頁面可能要到10、100、1000條指令后才會被訪問。此時要置換最遲被訪問的頁面,把因調用被替換的頁面而引起的中斷推遲到將來,越久越好。當缺頁中斷發生時,操作系統無法知道各個頁面下一次將在什么時候被訪問,因此這個算法是無法被實現的。
       這個算法可以用來對其他可實現算法的性能進行比較。

2. 最近未使用頁面置換算法(NRU)(Not Recently Used)

       當頁面被訪問(讀或寫)時設置R位,頁面被寫入(修改)時設置M位。
       當啟動一個進程時,它的所有頁面的兩個位都由操作系統設為0,R位被定期地(比如在每次時鍾中斷時)清零,以區別最近沒有被訪問的頁面和被訪問的頁面。
       當發生缺頁中斷時,操作系統檢查所有的頁面並根據它們當前的R位和M位的值,把它們分為4類:

  •  第0類:沒有被訪問,沒有被修改。
  •  第1類:沒有被訪問,已被修改(M)。
  •  第2類:已被訪問,沒有被修改(R)。
  •  第3類:已被訪問,已被修改(RM)。

       NRU(Not Recently Used)算法隨機地從類編號最小的非空類中挑選一個頁面淘汰。在一個時間滴答中(大約20ms)淘汰一個沒有被訪問的已修改頁面要比淘汰一個被頻繁使用的“干凈”頁面好。NRU算法的主要優點是易於理解和能夠有效地被實現,雖然它的性能不是最好的,但是已經夠用了。

3. 先進先出頁面置換算法(FIFO)

       開銷同樣較小的FIFO算法,最新進入的頁面放在表尾,最早進入的頁面放在表頭。當缺頁中斷時,淘汰表頭的頁面並把新調入的頁面加到表尾。這種算法的缺點是可能會把有用的頁面淘汰掉。

4. 第二次機會頁面置換算法(SC)(Second Chance)

       對FIFO算法的改進,對FIFO算法做一個簡單的修改:檢查最老頁面的R位。如果R位是0,那么這個頁面既老又沒有被使用,可以立刻置換掉;如果是1,就將R位置0,並把該頁面放到鏈表的尾端,修改它的裝入時間使它就像剛裝入時間使它就像剛裝入的一樣,然后繼續搜索。
       第二次機會(second chance)算法是尋找一個在最近的時鍾間隔內沒有被訪問過的頁面。如果所有的頁面都被訪問過了,該算法就簡化為純粹的FIFO算法。假設所有頁面的R位都被設置了,操作系統將會一個接一個地把每個頁面都移動到鏈表的尾部並清除被移動的頁面的R位。最后又會回到原來的表頭頁面,此時它的R位已經被清除了,因此這個頁面會被淘汰,所以這個算法總是可以結束的。

5. 時鍾頁面置換算法(CLOCK)

       對第二次機會算法的改進,第二次機會算法經常要在鏈表中移動頁面,既降低了效率又不是很必要。
       一個更好的做法就是把所有的頁面都保存在一個類似鍾面的環形鏈表中,一個表指針指向最老的頁面。當發生缺頁中斷時,首先檢查表指針指向的頁面,如果它的R位是0就淘汰該頁面,並把新的頁面插入這個位置,然后把表指針前移一個位置。如果R位是1就清除R位並把表指針前移一個位置;重復這個過程一直到找到一個R位為0的頁面為止。

6. 最近最少使用頁面置換算法(LRU)(Least Recently Used)

       在缺頁中斷發生時,置換未使用時間最長的頁面。
       LRU理論上是可以實現的,但是代價很高。維護一個所有頁面的鏈表,最近最多使用的頁面在表頭,最近最少使用的頁面在表尾。困難的是在每次訪問內存時都必須要更新整個鏈表。
       假設用硬件實現:硬件有一個64位計數器C,它在每條指令執行完后自動加1,每個頁表項必須有一個足夠容納這個計數器值的域。在每次訪問完內存后,將當前的C值保存到被訪問頁面的頁表項中。一旦發生缺頁中斷,操作系統就檢查所有頁表項中計數器的值,找到值最小的一個頁面,這個頁面就是最近最少使用的頁面。
       但是只有非常少的計算機擁有這樣的硬件。

7. 最不常用頁面置換算法(NFU)(Not Frequently Used)

       用一個軟件模擬LRU,該算法將每個頁面與一個軟件計數器相關聯。計數器的初值為0。每次時鍾中斷時,由操作系統掃描內存中所有的頁面,將每個頁面的R位(它是0或1)加到它的計數器上。這個計數器大體上跟蹤了各個頁面被訪問的頻繁程度。發生缺頁中斷時,則置換計數器值最小的頁面。
       NFU的缺點是它不從不忘記任何事,比如一個頁面之前頻繁被訪問,導致這個它的計數器很大,但是后來它不被訪問了,而它的計數器的值還是很大,所以它一直不會被置換出去。

8. 老化算法

       老化算法是對NFU算法的修改,其修改包括兩個部分,首先,在R位被加進之前將計數器右移一位,其次,將R位加到計數器最左端的位而不是最右端的位。
       老化算法中的計數器只有有限位數,如果時鍾滴答是20ms,8位一般是夠用的。假如一個頁面160ms沒有被訪問過,那么它很可能並不重要。

9. 工作集頁面置換算法

       一個進程當前正在使用的頁面的集合稱為它的工作集。
       若每執行幾條指令就產生一次缺頁中斷,那么就稱這個程序發生了顛簸。
       在單純的分頁系統中,剛啟動進程時,在內存中並沒有頁面。在CPU試圖讀取第一條指令時就會產生一次缺頁中斷,使操作系統裝入含有第一條指令的頁面,其他由訪問全局數據和堆棧引起的缺頁中斷通常會緊接着發生。一段時間后,進程需要的大部分頁面都已經在內存了,進程開始在較少缺頁中斷的情況下運行。這個策略被稱為請求調頁。
       有不少分頁系統會設法跟蹤進程的工作集,以確保在讓進程運行以前,它的工作集就已經在內存中了。該方法稱為工作集模型,大大減少缺頁中斷率。在進程前裝入其工作集頁面也稱為預先調頁。工作集是隨時間變化的。
       事實上大多數程序會任意訪問一小部分頁面,工作集隨時間緩慢變化。當程序重新開始時,就有可能根據它上次結束時的工作集對要用到的頁面做一個合理的推測,預先調頁就是在程序IXUS運行之前預先裝入推測的工作集的頁面。
       按照以前的方法,定義工作集為前1000萬次內存訪問鎖使用過的頁面的集合,那么現在就可以這樣定義:工作集即是過去10ms中的內存訪問所用到的頁面的集合。這樣的模型很合適而且更容易實現。要注意到,每個進程只計算它自己的執行時間。因此,如果一個進程在T時刻開始,在(T+100ms)的時刻使用了40msCPU時間,對工作集而言,它的時間就是40ms。一個程序從它開始執行到當前所實際使用的CPU時間總數通常稱作當前實際運行時間。通過這個近似的方法,進程的工作集可以被稱為在過去的τ秒實際運行時間中它所訪問過的頁面的集合。
       基於工作集的頁面置換算法就是找出一個不在工作集中的頁面並淘汰它。每個表項至少包含兩條信息:上次使用該頁面的近似時間和R(訪問位)。

       過程:掃描所有的頁面檢查R位:
              若(R == 1)
                     設置上次使用時間為當前實際時間,以表示缺頁中斷時該頁面正在被使用
              若(R == 0 且生存時間>τ)
                     移出這個頁面,該頁面在當前時鍾滴答中未被訪問,不在工作集中,用新的頁面置換它。掃描會繼續進行以更新剩余的表項。
              若(R == 0 且生存時間≤τ)
                     記住最小時間。如果該頁面R==0且生存時間小於或等於τ,則頁面仍在工作集中。把頁面臨時保存下來,但是要記住生存時間最長(“上次使用時間”的最小值)。如果掃描完整個頁表卻沒有找到合適的淘汰的頁面,如果找到了一個或多個R == 0的頁面,就淘汰生存時間最長的頁面。
       在最壞的情況下,在當前時鍾滴答中,所有的頁面都被訪問過了,也就是所有的R都為1,因此就隨機選擇一個頁面淘汰,如果有的話最好選一個干凈頁面。

10. 工作集時鍾頁面置換算法

       在工作集頁面置換算法中中,當缺頁中斷發生后,需要掃描整個頁表才能確定被淘汰的頁面,因此基本工作集算法是比較費時的。
       基於時鍾算法,並且使用了工作集信息,被稱為WSClock(工作集時鍾)算法。由於它實現簡單,性能較好,所以在實際工作中得到了廣泛應用。
       與時鍾算法一樣,所需的數據結構是一個以頁框為元素的循環表。最初,該表示空的,當裝入第一個頁面后,把它加到該表中。隨着更多的頁面加入,它們形成一個環。每個表項包含來自基本工作集算法的上次使用時間,以及R位和M位。
       與時鍾算法一樣,每次缺頁中斷時,首先檢查指針指向的頁面。如果R位是1,該頁面在當前時鍾滴答中就被使用過,那么該頁面就不適合被淘汰。然后把該頁面的R位置為0,指針指向下一個頁面,並重復該算法。
       如果R位是0,查看生存時間,如果生存時間大於τ並且該頁面是干凈的,它就不在工作集中,而且在磁盤上它有一個有效的副本。申請此頁框,並把新頁面放在其中。如果該頁面已經被修改過,就不立即申請此頁框,為了避免由於調度寫磁盤操作引起的進程切換,指針繼續向前走,算法繼續對下一個頁面進行操作,有可能存在一個舊的而且干凈的頁面可以立即使用。
       原則上,所有的頁面都有可能因為磁盤I/O在某個時鍾周期被調度,為了降低磁盤阻塞,需要設置一個限制,即最大只允許寫回n個頁面。一旦達到該限制,就不允許調度新的寫操作。
       指針經過一圈返回它的起點,有兩種情況:

    • 至少調用了一次寫操作
    • 沒有調用過寫操作
             對於第一種情況,執行了寫操作的頁面已經是干凈的了,置換遇到的第一個干凈頁面,這個頁面不一定是第一個被調度寫操作的頁面,因為硬盤驅動程序為了優化性能可能已經把寫操作重排序了。
             對於第二種情況,所有的頁面都在工作集中,否則將至少執行了一個寫操作。由於缺乏額外的信息,一個簡單的方法就是隨便置換一個干凈的頁面來使用,掃描中需要記錄干凈頁面的位置。如果不存在干凈頁面,就選定當前頁面並把它協會磁盤。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM