頁面置換演算法之Clock演算法

2022-02-24 06:11:25 字數 3858 閱讀 2686

緩衝池是資料庫最終的概念,資料庫可以將一部分資料頁放在記憶體中形成緩衝池,當需要乙個資料頁時,首先檢查記憶體中的緩衝池是否有這個頁面,如果有則直接命中返回,沒有則從磁碟中讀取這一頁,然後快取到記憶體並返回。

但是記憶體的價值較高,一般來說伺服器的記憶體總是小於磁碟大小的,而且記憶體不能完全分配給資料庫作為緩衝池。這就意味著資料庫基本上無法將所有的資料都緩衝到記憶體中。

當緩衝池滿後,如果還有新的頁面要被緩衝到池中,就要設計一種頁面置換的演算法,將乙個舊的頁面替換成新的頁面。

一般來說我們熟悉的演算法有下面幾種:

下面逐一介紹各種演算法。

如果被替換掉的頁是以後再也不會使用的,那麼這種演算法無疑是最優秀的。因為不管什麼演算法,替換掉的頁也有可能再次被快取,替換掉其它的頁。

但是這種演算法是無法實現的,我們不可能知道哪個頁面以後也在不會被使用。

或者我們退一步,將這個演算法改成被替換掉的頁是以後很長一段時間都不會再次被使用的,那麼這種演算法無疑也是最優秀的。

但是還是會面對乙個無法實現的問題,我們還是不知道哪些頁面會在未來多長一段時間內不會被再次訪問。頁面無法確認,時間也無法確定。

雖然這種演算法無法被實現,但是可以作為一種度量,如果有一種演算法其效率最接近opt,那麼這種演算法無疑是優秀的演算法。

先進先出演算法是一種很簡單的演算法,其基本思想是形成乙個佇列,最先入隊的頁面最先被逐出。我們用示意圖來模擬一下fifo演算法:

我們的記憶體假設只能儲存4個頁面,此時的訪問請求按照時間順序是1->2->3->4->5,那麼按照時間順序,當訪問到4號頁面時佇列正好填滿,當要訪問5號頁面時,會將最先入隊的1號頁面逐出。

這種演算法實現起來很簡單,但是從實現上來看,效能和opt演算法差距最大。因為被替換出去的頁面很有可能是最常使用的頁面,因此這個演算法很少見出現在資料庫緩衝池管理中的。

fifo演算法會出現乙個叫做belay異常的現象,就這個現象我們解釋如下。

我們首先定義乙個4個頁面長度的佇列作為緩衝池,然後按照下面的順序訪問:1->2->3->4->5->3->9->1->4->2->7->4->7。那麼我們按照剛才描述的fifo來看看訪問的過程:

訪問順序

訪問頁記憶體佇列

是否命中11

1否22

1,2否33

1,2,3否4

41,2,3,4否5

52,3,4,5否6

32,3,4,5是7

93,4,5,9否8

14,5,9,1否9

44,5,9,1是10

25,9,1,2否11

79,1,2,7是12

41,2,7,4否13

71,2,7,4

是從這個**上看到,非命中次數有9次,那麼我們將這個佇列的容量增加到5,然後再次重複這個訪問序列,看看效果:

訪問順序

訪問頁記憶體佇列

是否命中11

1否22

1,2否33

1,2,3否4

41,2,3,4否5

51,2,3,4,5否6

31,2,3,4,5是7

92,3,4,5,9否8

13,4,5,9,1是9

43,4,5,9,1是10

24,5,9,1,2否11

75,9,1,2,7否12

49,1,2,7,4否13

79,1,2,7,4

否這樣的話,非命中的次數是10次,奇怪的是增加了緩衝池的容量,非命中緩衝的數量還增加了,這種現象就叫做belay異常。

這種演算法不應該被考慮。

lru演算法的思想也很簡單,實現乙個鍊錶(雙向鍊錶),每次要緩衝新的頁面時,遍歷鍊錶,選擇最近最少使用的頁面進行逐出操作。

這種演算法要求每個頁面上記錄乙個上次使用時間t,程式決定逐出時,以這個時間t為準,t距離當前時間最大的,就是要被逐出的頁面。

下圖中按照1->5->2->2->6->5->4的順序訪問,記憶體和訪問示意圖如下:

其中最接近頂端的頁面我們認為其t最小,最接近底部,我們認為其t最大。

訪問6號頁面的時候,記憶體被填滿,下一次訪問5號頁面的時候,會將5號頁面提公升到頂部,也就是t最小,之後訪問4號頁面,因為原先記憶體中沒有4號頁面,因此會選擇逐出乙個頁面。此時1號頁面在底部,其t最大,因此被逐出。

那麼lru演算法是否解決了belay異常呢?

訪問順序

訪問頁記憶體佇列

是否命中11

1否22

1,2否33

1,2,3否4

41,2,3,4否5

52,3,4,5否6

32,4,5,3是7

94,5,3,9否8

15,3,9,1否9

43,9,1,4否10

29,1,4,2否11

71,4,2,7否12

41,2,7,4是13

71,2,4,7

是一共有10次未命中。增加容量到5,看一下新的情況:

訪問順序

訪問頁記憶體佇列

是否命中11

1否22

1,2否33

1,2,3否4

41,2,3,4否5

51,2,3,4,5否6

31,2,4,5,3是7

92,4,5,3,9否8

14,5,3,9,1否9

45,3,9,1,4是10

23,9,1,4,2否11

79,1,4,2,7否12

49,1,2,7,4是13

79,1,2,4,7

是未命中的次數已經變成了9次,減少了一次,如果我設計的佇列中有大量的重複,那麼這個改進應該更加明顯。

lru演算法在innodb的實現中是被改進的,每次新新增進去的頁面會被放在佇列的3/8處。

無論如何,lru演算法都被認為是最接近opt的演算法。

時鐘置換演算法可以認為是一種最近未使用演算法,即逐出的頁面都是最近沒有使用的那個。我們給每乙個頁面設定乙個標記位u,u=1表示最近有使用u=0則表示該頁面最近沒有被使用,應該被逐出。

按照1-2-3-4的順序訪問頁面,則緩衝池會以這樣的一種順序被填滿:

注意中間的指標,就像是時鐘的指標一樣在移動,這樣的訪問結束後,緩衝池裡現在已經被填滿了,此時如果要按照1-5的順序訪問,那麼在訪問1的時候是可以直接命中快取返回的,但是訪問5的時候,因為緩衝池已經滿了,所以要進行一次逐出操作,其操作示意圖如下:

最初要經過一輪遍歷,每次遍歷到乙個節點發現u=1的,將該標記位置為0,然後遍歷下乙個頁面,一輪遍歷完後,發現沒有可以被逐出的頁面,則進行下一輪遍歷,這次遍歷之後發現原先1號頁面的標記位u=0,則將該頁面逐出,置換為頁面5,並將指標指向下乙個頁面。

假設我們接下來會訪問2號頁面,那麼可以直接命中指標指向的頁面,並將這個頁面的標記為u置為1。

但是考慮乙個問題,資料庫裡逐出的頁面是要寫回磁碟的,這是乙個很昂貴的操作,因此我們應該優先考慮逐出那些沒有被修改的頁面,這樣可以降低io。

因此在時鐘置換演算法的基礎上可以做乙個改進,就是增加乙個標記為m,修改過標記為1,沒有修改過則標記為0。那麼u和m組成了乙個元組,有四種可能,其被逐出的優先順序也不一樣:

頁面置換演算法 CLOCK置換演算法及其改進版演算法

本文主要介紹頁面置換演算法中的clock置換演算法。頁面置換演算法中的lru演算法最接近理想情況下的opt演算法,但是實現起來比較困難且開銷較大,所以很多設計者試圖用開銷比較小的演算法接近lru演算法,clock演算法就是其中一種。1.簡單的clock演算法是通過給每乙個訪問的頁面關聯乙個附加位 r...

程序頁面的時鐘(CLOCK)置換演算法

假設頁表項如下,其實可能更複雜,還有更多標記。頁號,物理塊號,存在位,修改位,使用位,假設作業系統給這個程序2個物理塊,0塊和1塊,那麼可以組成乙個時鐘形狀的迴圈佇列。0 1 0 環狀 時鐘置換演算法運作過程如下 假設 此時使用位情況 0 1,1 1 指標位置 0 初始化假設 開始,0塊使用位為1,...

頁面置換演算法

常用的頁面置換演算法有三種 先進先出演算法fifo first in first out 該演算法的基本思想是首先淘汰那些駐留在主存時間最長的頁面。最近最久未用演算法 lru 該演算法的基本思想是 如果某一頁被訪問了,那麼它很可能馬上又被訪問 反之,如果某一頁很久沒被訪問,那麼最近也不會再訪問。lr...