快取演算法(頁面置換演算法) FIFO LFU LRU

2021-07-13 19:19:35 字數 1997 閱讀 1075

快取演算法(頁面置換演算法)-fifo、lfu、lru

在前一篇文章中通過leetcode的一道題目了解了lru演算法的具體設計思路,下面繼續來**一下另外兩種常見的cache演算法:fifo、lfu

fifo(first in first out),先進先出。其實在作業系統的設計理念中很多地方都利用到了先進先出的思想,比如作業排程(先來先服務),為什麼這個原則在很多地方都會用到呢?因為這個原則簡單、且符合人們的慣性思維,具備公平性,並且實現起來簡單,直接使用資料結構中的佇列即可實現。

在fifo cache設計中,核心原則就是:如果乙個資料最先進入快取中,則應該最早淘汰掉。也就是說,當快取滿的時候,應當把最先進入快取的資料給淘汰掉。在fifo cache中應該支援以下操作;

get(key):如果cache中存在該key,則返回對應的value值,否則,返回-1;

set(key,value):如果cache中存在該key,則重置value值;如果不存在該key,則將該key插入到到cache中,若cache已滿,則淘汰最早進入cache的資料。

舉個例子:假如cache大小為3,訪問資料序列為set(1,1),set(2,2),set(3,3),set(4,4),get(2),set(5,5)

則cache中的資料變化為:

(1,1)                               set(1,1)

(1,1) (2,2)                       set(2,2)

(1,1) (2,2) (3,3)               set(3,3)

(2,2) (3,3) (4,4)               set(4,4)

(2,2) (3,3) (4,4)               get(2)

(3,3) (4,4) (5,5)               set(5,5)

那麼利用什麼資料結構來實現呢?

下面提供一種實現思路:

利用乙個雙向鍊錶儲存資料,當來了新的資料之後便新增到鍊錶末尾,如果cache存滿資料,則把鍊錶頭部資料刪除,然後把新的資料新增到鍊錶末尾。在訪問資料的時候,如果在cache中存在該資料的話,則返回對應的value值;否則返回-1。如果想提高訪問效率,可以利用hashmap來儲存每個key在鍊錶中對應的位置。

lfu(least frequently used)最近最少使用演算法。它是基於「如果乙個資料在最近一段時間內使用次數很少,那麼在將來一段時間內被使用的可能性也很小」的思路。

注意lfu和lru演算法的不同之處,lru的淘汰規則是基於訪問時間,而lfu是基於訪問次數的。舉個簡單的例子:

假設快取大小為3,資料訪問序列為set(2,2),set(1,1),get(2),get(1),get(2),set(3,3),set(4,4),

則在set(4,4)時對於lfu演算法應該淘汰(3,3),而lru應該淘汰(1,1)。

那麼lfu cache應該支援的操作為:

get(key):如果cache中存在該key,則返回對應的value值,否則,返回-1;

set(key,value):如果cache中存在該key,則重置value值;如果不存在該key,則將該key插入到到cache中,若cache已滿,則淘汰最少訪問的資料。

為了能夠淘汰最少使用的資料,因此lfu演算法最簡單的一種設計思路就是 利用乙個陣列儲存 資料項,用hashmap儲存每個資料項在陣列中對應的位置,然後為每個資料項設計乙個訪問頻次,當資料項被命中時,訪問頻次自增,在淘汰的時候淘汰訪問頻次最少的資料。這樣一來的話,在插入資料和訪問資料的時候都能達到o(1)的時間複雜度,在淘汰資料的時候,通過選擇演算法得到應該淘汰的資料項在陣列中的索引,並將該索引位置的內容替換為新來的資料內容即可,這樣的話,淘汰資料的操作時間複雜度為o(n)。

另外還有一種實現思路就是利用 小頂堆+hashmap,小頂堆插入、刪除操作都能達到o(logn)時間複雜度,因此效率相比第一種實現方法更加高效。

如果哪位朋友有更高效的實現方式(比如o(1)時間複雜度),不妨**一下,不勝感激。

lru演算法的原理以及實現在前一篇博文中已經談到,在此不進行贅述:

快取演算法(頁面置換演算法) FIFO LFU LRU

1.fifo 先進先出 如果乙個資料最先進入快取中,則應該最早淘汰掉。也就是說,當快取滿的時候,應當把最先進入快取的資料給淘汰掉。實現 利用乙個雙向鍊錶儲存資料,當來了新的資料之後便新增到鍊錶末尾,如果cache存滿資料,則把鍊錶頭部資料刪除,然後把新的資料新增到鍊錶末尾。在訪問資料的時候,如果在c...

快取演算法(頁面置換演算法) FIFO LFU LRU

fifo first in first out 先進先出。其實在作業系統的設計理念中很多地方都利用到了先進先出的思想,比如作業排程 先來先服務 為什麼這個原則在很多地方都會用到呢?因為這個原則簡單 且符合人們的慣性思維,具備公平性,並且實現起來簡單,直接使用資料結構中的佇列即可實現。在fifo ca...

快取演算法(頁面置換演算法) FIFO LFU LRU

在前一篇文章中通過leetcode的一道題目了解了lru演算法的具體設計思路,下面繼續來 一下另外兩種常見的cache演算法 fifo lfu fifo first in first out 先進先出。其實在作業系統的設計理念中很多地方都利用到了先進先出的思想,比如作業排程 先來先服務 為什麼這個原...