因為LRU(最近最少使用)算法的兩種實現方案都比較麻煩而且開銷很大,所以提出了用軟件來模擬LRU算法的NFU(不經常使用)算法,但是NFU算法存在一些問題,比如在一個多次掃描編譯器中,在第一遍掃描中被頻繁用到的頁,在程序進入第二遍掃描時計數器值可能仍然很高。實際上,如果第一次掃描的執行時間恰好是各次掃描中最長的,含有以后各次掃描代碼的頁的計數器可能總是比含有第一次掃描代碼的頁小,其結果是操作系統將刪除掉有用的頁而不是不再使用的頁。
所以為了使NFU算法能夠更好的模擬LRU算法,需要對其進行修改,修改分兩部分:第一是計數器在R位被加進來之前右移一位;第二是R位加到計數器的最左端而不是最右端。這就是老化算法。
這樣修改以后的老化算法的結果是顯而易見的,因為每次都對計數器進行移位,這就相當於每次都“清除”掉上一次的計數值,但是這個值並非被完全去掉而是保存在后面的位中,然后通過對高位添加R位來決定需要淘汰的頁面,這樣就保證了需要淘汰頁面時計數器值最小的葉面肯定是最近最少訪問到的頁面。
|
時鍾周期0 |
時鍾周期1 |
時鍾周期2 |
時鍾周期3 |
時鍾周期4 |
頁面0 |
10000000 |
11000000 |
11100000 |
11110000 |
01111000 |
頁面1 |
00000000 |
10000000 |
11000000 |
01100000 |
10110000 |
頁面2 |
10000000 |
01000000 |
00100000 |
00010000 |
10001000 |
頁面3 |
00000000 |
00000000 |
10000000 |
01000000 |
00100000 |
頁面4 |
10000000 |
11000000 |
01100000 |
10110000 |
01011000 |
頁面5 |
10000000 |
01000000 |
10100000 |
01010000 |
00101000 |
用軟件模擬LRU的老化算法6個頁面在5個時鍾周期內的計數器情況
從上表可以看出,在未開始之前所有計數器的值都為0,每過一個時鍾周期首先將計數器右移一位,然后將新的R位添加到計數器最左端,發生淘汰時淘汰計數器值最小的頁面。
在第5個時鍾周期出現了選擇的問題,頁面3和5都連續兩個周期沒有被訪問了,而在兩個周期之前的一個周期中他們都被訪問過。根據LRU,如果有一個頁面必須被淘汰掉,我們應該在這兩個頁面中選一個。然而現在的問題是我們不知道在時鍾周期1到時鍾周期2期間這兩個頁中的哪一個后被訪問到,在每個時鍾周期中只記錄一位使我們無法區分一個周期內較早和較晚的訪問,我們所能作的只是淘汰掉頁3,因為頁5在再往前的周期中也被訪問過而頁3沒有。
老化算法存在的另外一個問題是計數器始終都只有有限位,如上表所示只有8位計數器,這就意味着開始的訪問數據會被沖掉,如果兩個頁面的計數值恰巧一樣的話,唯一的辦法就是從兩個頁面中隨機淘汰掉一個。