LRU算法

LRU 即:Least Recently Used 最近最少使用算法

 

關於操作系統的內存管理,如何節省利用容量不大的內存爲最多的進程提供資源,一直是研究的重要方向。而內存的虛擬存儲管理,是現在最通用,最成功的方式——在內存有限的情況下,擴展一部分外存作爲虛擬內存,真正的內存只存儲當前運行時所用得到信息。這無疑極大地擴充了內存的功能,極大地提高了計算機的併發度。虛擬頁式存儲管理,則是將進程所需空間劃分爲多個頁面,內存中只存放當前所需頁面,其餘頁面放入外存的管理方式

然而,有利就有弊,虛擬頁式存儲管理減少了進程所需的內存空間,卻也帶來了運行時間變長這一缺點:進程運行過程中,不可避免地要把在外存中存放的一些信息和內存中已有的進行交換,由於外存的低速,這一步驟所花費的時間不可忽略。因而,採取儘量好的算法以減少讀取外存的次數,也是相當有意義的事情。
 
對於虛擬頁式存儲,內外存信息的替換是以頁面爲單位進行的——當需要一個放在外存的頁面時,把它調入內存,同時爲了保持原有空間的大小,還要把一個內存中頁面調出至外存。自然,這種調動越少,進程執行的效率也就越高。那麼,把哪個頁面調出去可以達到調動儘量少的目的?我們需要一個算法。
 
自然,達到這樣一種情形的算法是最理想的了——每次調換出的頁面是所有內存頁面中最遲將被使用的——這可以最大限度的推遲頁面調換,這種算法,被稱爲理想頁面置換算法。可惜的是,這種算法是無法實現的。爲了儘量減少與理想算法的差距,產生了各種精妙的算法,最近最少使用頁面置換算法便是其中一個。
 
 
LRU算法的提出是基於這樣一個事實:在前面的向條指令中使用頻繁的頁面很可能在後面的幾條指令中頻繁使用;反過來說,已經很長時間沒有使用過的頁面很可能在未來較長的一段時間內也不會被用到。這就是局部性原理-------比內存速度還要快的cache也是基於些原理。因而,在每次調換時,找到最近最少使用的那個頁面調出內存,即LRU。
 
如何用具體的數據結構來實現這個算法?
 
首先,最容易想到,也最簡單的方法:計時法。給頁表中的每一頁增加一個域,專門用來存放計時標誌,用來記錄該頁面自上次被訪問以來所經歷的時間。頁面每被訪問一次,計時清0。要裝入新頁時,從內存的頁面中選出時間最長的一頁,調出,同時把各頁的計時標誌全部清0,重新開始計時。
計時法可以稍作改變,成爲計數法頁面被訪問,計數標誌清0,其餘所有內存頁面計數器加1;要裝入新頁時,選出計數最大的一頁調出,同時所有計數器清0。
這兩種方法確實很簡單,但運行效率卻不盡如人意。每個時刻,或是每調用一個頁面,就需要對內存中所有頁面的訪問情況進行記錄和更新,麻煩且開銷相當大
另一種實現的方法:鏈表法
操作系統爲每個進程維護一條鏈表,鏈表的每個結點記錄一張頁面的地址。調用一次頁面,則把該頁面的結點從鏈中取出,放到鏈尾;要裝入新頁,則把鏈頭的頁面調出,同時生成調入頁面的結點,放到鏈尾。
鏈表法可看作簡單計時/計數法的改良,維護一個鏈表,自然要比維護所有頁面標誌要簡單和輕鬆。可是,這並沒有在數量級上改變算法的時間複雜度,每調用一個頁面,都要在鏈表中搜尋對應結點並放至鏈尾的工作量並不算小
 
讓我們來談論一下LRU算法。首先,這是一個相當好的算法,它是理想算法很好的近似。在計算機系統中應用廣泛的局部性原理給它打造了堅實的理論基礎,而在實際運用中,這一算法也被證明擁有極高的性能。在大規模的程序運行中,它產生的缺頁中斷次數已很接近理想算法。或許我們還能找到更好的算法,但我想,得到的收益與付出的代價恐怕就不成比例了。當然,LRU算法的缺點在於實現方法的不足——效率高的硬件算法通常在大多數機器上無法運行,而軟件算法明顯有太多的開銷。與之相對的,FIFO算法,和與LRU相似的NRU算法,性能儘管不是最好,卻更容易實現。
 
所以,找到一個優秀的算法來實現LRU,就是一個非常有意義的問題。
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章