lirs演算法
Ⅰ lirs是什麼意思 翻譯
LIRS是Low Interreference Recency Set Replacement Policy的縮寫,是一種計算機磁碟調度演算法。以下是關於LIRS的詳細解釋:
定義與用途:LIRS是對經典LRU演算法的擴展優化,主要用於解決磁碟Cache中的頁面置換問題,旨在提高磁碟IO的效率和性能。
工作原理:LIRS演算法的核心是選出一個Low InterReference Recency Set,即最近訪問時間有序的一些頁面。內存中的所有頁面可以分成LIRS集合和非LIRS集合。第一次訪問頁面直接加入LIRS集合,當緩存滿時,如果某個頁面的訪問間隔比LIRS集合中的某個頁面長,則將該頁面替換出去。
優勢:相比常見的LRU演算法,LIRS演算法顯著提高了磁碟IO效率和性能,特別是對於具有較高訪問局部性的工作負載,其效果更為顯著。
應用場景:LIRS演算法大多應用於將存儲設備作為磁碟緩存的操作系統中,如Linux中的Buffer Cache和Page Cache、Windows中的NTFS文件系統、HyperV虛擬化軟體等。
局限性:LIRS演算法的實現較為復雜,需要更高的計算和存儲成本。同時,在面對較少訪問局部性和大量隨機訪問負載時,LIRS演算法可能會降低效率。
綜上所述,LIRS演算法為提高磁碟IO效率和性能提供了有力的工具和優化策略,在需要處理大量磁碟IO的系統和應用中具有重要的應用價值。
Ⅱ golang sync.pool對象復用 並發原理 緩存池
在go http每一次go serve(l)都會構建Request數據結構。在大量數據請求或高並發的場景中,頻繁創建銷毀對象,會導致GC壓力。解決辦法之一就是使用對象復用技術。在http協議層之下,使用對象復用技術創建Request數據結構。在http協議層之上,可以使用對象復用技術創建(w,*r,ctx)數據結構。這樣即可以回快TCP層讀包之後的解析速度,也可也加快請求處理的速度。
先上一個測試:
結論是這樣的:
貌似使用池化,性能弱爆了???這似乎與net/http使用sync.pool池化Request來優化性能的選擇相違背。這同時也說明了一個問題,好的東西,如果濫用反而造成了性能成倍的下降。在看過pool原理之後,結合實例,將給出正確的使用方法,並給出預期的效果。
sync.Pool是一個 協程安全 的 臨時對象池 。數據結構如下:
local 成員的真實類型是一個 poolLocal 數組,localSize 是數組長度。這涉及到Pool實現,pool為每個P分配了一個對象,P數量設置為runtime.GOMAXPROCS(0)。在並發讀寫時,goroutine綁定的P有對象,先用自己的,沒有去偷其它P的。go語言將數據分散在了各個真正運行的P中,降低了鎖競爭,提高了並發能力。
不要習慣性地誤認為New是一個關鍵字,這里的New是Pool的一個欄位,也是一個閉包名稱。其API:
如果不指定New欄位,對象池為空時會返回nil,而不是一個新構建的對象。Get()到的對象是隨機的。
原生sync.Pool的問題是,Pool中的對象會被GC清理掉,這使得sync.Pool只適合做簡單地對象池,不適合作連接池。
pool創建時不能指定大小,沒有數量限制。pool中對象會被GC清掉,只存在於兩次GC之間。實現是pool的init方法注冊了一個poolCleanup()函數,這個方法在GC之前執行,清空pool中的所有緩存對象。
為使多協程使用同一個POOL。最基本的想法就是每個協程,加鎖去操作共享的POOL,這顯然是低效的。而進一步改進,類似於ConcurrentHashMap(JDK7)的分Segment,提高其並發性可以一定程度性緩解。
注意到pool中的對象是無差異性的,加鎖或者分段加鎖都不是較好的做法。go的做法是為每一個綁定協程的P都分配一個子池。每個子池又分為私有池和共享列表。共享列表是分別存放在各個P之上的共享區域,而不是各個P共享的一塊內存。協程拿自己P里的子池對象不需要加鎖,拿共享列表中的就需要加鎖了。
Get對象過程:
Put過程:
如何解決Get最壞情況遍歷所有P才獲取得對象呢:
方法1止前sync.pool並沒有這樣的設置。方法2由於goroutine被分配到哪個P由調度器調度不可控,無法確保其平衡。
由於不可控的GC導致生命周期過短,且池大小不可控,因而不適合作連接池。僅適用於增加對象重用機率,減少GC負擔。2
執行結果:
單線程情況下,遍歷其它無元素的P,長時間加鎖性能低下。啟用協程改善。
結果:
測試場景在goroutines遠大於GOMAXPROCS情況下,與非池化性能差異巨大。
測試結果
可以看到同樣使用*sync.pool,較大池大小的命中率較高,性能遠高於空池。
結論:pool在一定的使用條件下提高並發性能,條件1是協程數遠大於GOMAXPROCS,條件2是池中對象遠大於GOMAXPROCS。歸結成一個原因就是使對象在各個P中均勻分布。
池pool和緩存cache的區別。池的意思是,池內對象是可以互換的,不關心具體值,甚至不需要區分是新建的還是從池中拿出的。緩存指的是KV映射,緩存里的值互不相同,清除機制更為復雜。緩存清除演算法如LRU、LIRS緩存演算法。
池空間回收的幾種方式。一些是GC前回收,一些是基於時鍾或弱引用回收。最終確定在GC時回收Pool內對象,即不迴避GC。用java的GC解釋弱引用。GC的四種引用:強引用、弱引用、軟引用、虛引用。虛引用即沒有引用,弱引用GC但有空間則保留,軟引用GC即清除。ThreadLocal的值為弱引用的例子。
regexp 包為了保證並發時使用同一個正則,而維護了一組狀態機。
fmt包做字串拼接,從sync.pool拿[]byte對象。避免頻繁構建再GC效率高很多。
Ⅲ lirs是什麼意思 翻譯
LIRS是一個計算機磁碟調度演算法,是對經典LRU(最近最少使用)演算法的擴展優化,旨在提高磁碟IO的效率和性能。其全稱為Low Inter-reference Recency Set Replacement Policy(低間隔參考程度替換策略),主要用於解決磁碟Cache中的頁面置換問題。此演算法能夠針對連續存儲訪問模式的工作負載,有效地減少磁碟IO次數。
LIRS演算法的核心是選出一個Low Inter-Reference Recency Set(低間隔參考程度集合),即最近訪問時間有序的一些頁面,這樣,內存中的所有頁面可以分成兩個部分:LIRS集合和非LIRS集合。第一次訪問頁面直接加入LIRS集合,但當緩存滿時,如果某個頁面的訪問間隔比LIRS集合中的某個頁面長,那麼就將該頁面替換出去,這個時候我們稱LIRS集合中的頁面被"頂出"到非LIRS集合里,LIRS集合就歸屬於LIRS-IR集合,非LIRS集合歸屬於LIRS-NIR集合,並將非LIRS集合中距離最遠的頁面替換出去。
相比常見的LRU演算法來說,LIRS演算法顯著提高了磁碟IO效率和性能,特別是對於具有較高訪問局部性的工作負載,其效果更為顯著。但是,LIRS演算法的實現較為復雜,需要更高的計算和存儲成本。同時,在面對較少訪問局部性和大量隨機訪問負載時,LIRS演算法可能會降低效率。
LIRS演算法大多應用於將存儲設備作為磁碟緩存的操作系統中。比如Linux中的Buffer Cache和Page Cache、Windows中的NTFS文件系統、Hyper-V虛擬化軟體等。總之,LIRS演算法為提高磁碟IO效率和性能提供了有力的工具和優化策略,對於需要處理大量磁碟IO的系統和應用,有著重要的應用價值。