1. 程式人生 > >幾種缺頁中斷演算法(FIFO,LRU與LFU)的實現過程

幾種缺頁中斷演算法(FIFO,LRU與LFU)的實現過程

  最近在做筆試題,其中虛擬儲存管理中幾種缺頁中斷演算法經常考到,雖然這類題可說非常簡單,但概念上卻容易混淆而且如果不掌握正確的做法很容易出錯,因此覺得有必要把這三種演算法的實現過程理一遍,並從原始碼級別去思考它們的實現。
 首先推薦一個部落格,對這兩個演算法給出了不易錯的演算步驟,也給了我一些啟示,這篇部落格也給出了原始碼,但我沒有去驗證。
 http://www.cnblogs.com/freeyiyi1993/archive/2013/05/18/3084956.html
 再給出騰訊的筆試題原題:在一個採用頁式虛擬儲存管理的系統中,有一使用者作業,它依次要訪問的頁面序列是1,2,3,4,1,2,5,1,2,3,4,5.假定分配給該作業的頁數為3且作業初始時未裝載頁面,那麼採用FIFO排程演算法產生的缺頁中斷數為多少,採用LRU排程演算法產生的缺頁中斷數為多少?
 FIFO演算法:(First In First Out),先進先出,一般看到這類思想,首先想到的資料結構應當是佇列,但是我們這裡最好是用vector,因為調頁過程中需要遍歷佇列檢查該頁是否已存在,當演算法的儲存結構是佇列或棧,但實現過程中需要經常遍歷全佇列或全棧的內容時,最好用vector,這是《劍指Offer》面試題25給我的啟發。給出一個訪問序列的模擬演算法到此應該非常簡單了,為了節省時間,下面僅給出題目計算步驟,程式碼今後再補。
           訪問序列:1,2,3,4,1,2,5,1,2,3,4,5
                   1,2,3先調入記憶體,記憶體結構:3      2      1    缺頁次數:3  
                   4調入記憶體,1調出,  記憶體結構:4      3      2    缺頁次數:4
                   1調入記憶體,2調出,  記憶體結構:1      4      3    缺頁次數:5
                   2調入記憶體,3調出,  記憶體結構:2      1      4    缺頁次數:6
                   5調入記憶體,4調出,  記憶體結構:5      2      1    缺頁次數:7
                   1存在,記憶體結構不改變
                   2存在,記憶體結構不改變
                   3調入記憶體,1調出,  記憶體結構:3      5      2    缺頁次數:8
                   4調入記憶體,2調出,  記憶體結構:4      3      5    缺頁次數:9
                   5存在,記憶體結構不改變
            共缺頁9次,缺頁中斷率 = 缺頁中斷次數 / 總訪問頁數 = 9 / 12    
LRU演算法:最近最少使用(Least Recently Used),先看一下調頁過程
          訪問序列:1,2,3,4,1,2,5,1,2,3,4,5
                
1,2,3先調入記憶體,記憶體結構:3      2      1    缺頁次數:3  
                4調入記憶體,1調出,  記憶體結構:4      3      2    缺頁次數:4
                1調入記憶體,2調出,  記憶體結構:1      4      3    缺頁次數:5
                2調入記憶體,3調出,  記憶體結構:2      1      4    缺頁次數:6
                
5調入記憶體,4調出,  記憶體結構:5      2      1    缺頁次數:7
           到這一步其實和FIFO並沒有區別
              1調入記憶體,由於記憶體中存在1,故沒有缺頁中斷,但由於1最近被訪問過,所以要將其位置調換,
              使它最後一個被淘汰,記憶體結構:1      5      2
              2調入記憶體,沒有缺頁中斷,但記憶體位置要變化,記憶體結構:2      1      5
                  3調入記憶體,5調出,  記憶體結構:3      2      1    缺頁次數:8
                  4調入記憶體,1調出,  記憶體結構:4      3      2    缺頁次數:9
                  5調入記憶體,2調出,  記憶體結構:5      4      3    缺頁次數:10
           共缺頁10次,缺頁中斷率:10/12
演算法總結:資料結構應該還是一個佇列,開始記憶體頁面不滿時按序把頁面填入,之後如果調入的頁不存在,則按照先進先出順序,淘汰隊頭頁面,如果調入的頁存在,則將該頁換至頁尾,該頁之後的元素前移,這個最好用什麼資料結構?
其實覺得騰訊這道題的序列沒有代表性,要真正理解LRU過程中記憶體儲存頁面結構的變化情況,還是推薦看一下上面的部落格。
LFU演算法:最近最不經常使用(Least Frequently Used),相比於前兩個,LFU演算法的資料要少得多,因為它的實現更加複雜,在網上搜到這個部落格,http://www.cnblogs.com/tingyuxuan007/p/3823537.html,這個部落格有這三個演算法思想的討論及圖解,有利於初學者去徹底弄懂這個問題,現摘錄一些它的語句來說清楚這個演算法的思想:
這是一個基於訪問頻率的演算法.與LRU不同,LRU是基於時間的,會將
時間上最不常訪問的資料淘汰;LFU為將頻率上最不常訪問的資料淘汰.既然是基於頻率的,就需要有儲存每個資料訪問的次數.從儲存空間上,較LRU會多出一些持有計數的空間.”,它描述這個演算法的圖也很經典
![這裡寫圖片描述](https://img-blog.csdn.net/20170325121205171?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdmljdG9yeWphY2s=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast) 我想有這幅圖就已經不需要再多說什麼了,如果還有不明白的,去原部落格看一下敘述就行了。
還是把騰訊這道題用LFU演算法再做一遍:
   訪問序列:1,2,3,4,1,2,5,1,2,3,4,5
 
     最初:                3(1)      2(1)      1(1)       缺頁次數:3      括號中是其訪問次數  
        調入4                 4(1)       3(1)      2(1)       淘汰1,缺頁次數:4 
        調入1                 1(1)       4(1)      3(1)       淘汰2,缺頁次數:5
        調入2                 2(1)       1(1)      4(1)       淘汰3,缺頁次數:6 
        調入5                 5(1)       2(1)      1(1)       淘汰4,缺頁次數:7
        調入1                 1(2)       5(1)      2(1)
        調入2                 2(2)       1(2)      5(1)
        調入3                 2(2)       1(2)      3(1)       淘汰5,缺頁次數:8 
        調入4                 2(2)       1(2)      4(1)       淘汰3,缺頁次數:9
        調入5                 2(2)       1(2)      5(1)       淘汰4,缺頁次數:10
    共缺頁10次,缺頁中斷率:10/12