在學操作系統的時候,就會接觸到緩存調度算法,緩存頁面調度算法:先分配一定的頁面空間,使用頁面的時候首先去查詢空間是否有該頁面的緩存,如果有的話直接拿出來,如果沒有的話先查詢,如果頁面空間沒有滿的時候,使用新頁面的時候,就釋放舊的頁面空間,把新頁面緩存起來,以便下次使用同樣的頁面的時候方便調用。
緩存調度流程圖
緩存機制就是上面所說的那樣,但是實現的過程以及淘汰舊頁面的機制不同,所以會有不同緩存調度方法,就常見的就是FIFO,LRU,LFU緩存過期策略。
1.FIFO(First In First out):先見先出,淘汰最先近來的頁面,新進來的頁面最遲被淘汰,完全符合隊列。
2.LRU(Least recently used):最近最少使用,淘汰最近不使用的頁面
3.LFU(Least frequently used): 最近使用次數最少, 淘汰使用次數最少的頁面
下面詳細解釋三種算法是怎么實現的。下面解釋轉自http://blog.csdn.net/yangpl_tale/article/details/44998423
一、FIFO
按照“先進先出(First In,First Out)”的原理淘汰數據,正好符合隊列的特性,數據結構上使用隊列Queue來實現。
如下圖:
1. 新訪問的數據插入FIFO隊列尾部,數據在FIFO隊列中順序移動;
2. 淘汰FIFO隊列頭部的數據;
二、LRU
(Least recently used,最近最少使用)算法根據數據的歷史訪問記錄來進行淘汰數據,其核心思想是“如果數據最近被訪問過,那么將來被訪問的幾率也更高”。
最常見的實現是使用一個鏈表保存緩存數據,詳細算法實現如下:
1. 新數據插入到鏈表頭部;
2. 每當緩存命中(即緩存數據被訪問),則將數據移到鏈表頭部;
3. 當鏈表滿的時候,將鏈表尾部的數據丟棄。
三、LFU
(Least Frequently Used)算法根據數據的歷史訪問頻率來淘汰數據,其核心思想是“如果數據過去被訪問多次,那么將來被訪問的頻率也更高”。
LFU的每個數據塊都有一個引用計數,所有數據塊按照引用計數排序,具有相同引用計數的數據塊則按照時間排序。
具體實現如下:
1. 新加入數據插入到隊列尾部(因為引用計數為1);
2. 隊列中的數據被訪問后,引用計數增加,隊列重新排序;
3. 當需要淘汰數據時,將已經排序的列表最后的數據塊刪除。
前面兩種算法實現並不算難,LFU實現起來會有點麻煩,下面是我自己考慮的淘汰實現思路,來了頁面的時候會發生如下情況
1.判斷是否有舊的頁面存在,沒有則淘汰尾部元素,增加新的元素。
2.有舊頁面的存在,查詢舊頁面的位置,然后把舊頁面的元素一直上移到同等次數的頁面的上一個元素。
比如說元素(a,1)代表頁面為a,調用次數為1,那么在緩存里面集合為{ (f,4), (e,2), (d,2), (c,2), (b,2), (a,1) },這時候調用c頁面,只需要用折半查詢找到c元素的位置,把c元素存儲起來,把c元素到e元素之間的元素(不包含c元素)全部后移一位,然后把c元素放到原來e元素的位置即可。
下面附上三種算法的下載地址: