1. 程式人生 > >作業系統中的page cache機制

作業系統中的page cache機制

在現代計算機系統中,CPU,RAM,DISK的速度不相同,按速度高低排列為:CPU>RAM>DISK。CPU與RAM之間、RAM與DISK之間的速度差異常常是指數級。同時,它們之間的處理容量也不相同,其差異也是指數級。為了在速度和容量上折中,在CPU與RAM之間使用CPU cache以提高訪存速度,在RAM與磁碟之間,作業系統使用page cache提高系統對檔案的訪問速度。

作業系統在處理檔案時,需要考慮兩個問題:

1.      存放在磁碟上的檔案讀寫速度比記憶體差了一個數量級。
2.      檔案載入到記憶體一次,供多個程式共享。

    例如,在Windows系統中,一個程序中常常包含各種系統DLL模組,其大約佔用15MB空間,如果這些DLL不被共享,將會佔用大量的系統記憶體。

    作業系統使用page cache機制解決上面的兩個問題。

    以下是一個應用程式事例,在linux下, render程序對sence.dat檔案的操作步驟如下:

2012-04-06 <wbr>16:26 <wbr>作業系統中的page <wbr>cache機制

    當render程式從sence.dat中讀取了12KB資料之後,系統的頁面記憶體可能如下:

2012-04-06 <wbr>16:26 <wbr>作業系統中的page <wbr>cache機制

    對於系統的所有檔案I/O請求,作業系統都是通過page cache機制實現的,對於作業系統而言,磁碟檔案都是由一系列的資料塊順序組成,資料塊的大小隨系統不同而不同,x86 linux系統下是4KB(一個標準頁面大小)。核心在處理檔案I/O請求時,首先到page cache中查詢(page cache中的每一個數據塊都設定了檔案以及偏移資訊),如果未命中,則啟動磁碟I/O,將磁碟檔案中的資料塊載入到page cache中的一個空閒塊。之後再copy到使用者緩衝區中。

    很明顯,同一塊檔案資料,在記憶體中儲存了兩份,這既佔用了不必要的記憶體空間、冗餘的拷貝、以及造成的CPU cache利用率不高。針對此問題,作業系統提供了記憶體對映機制(linux中mmap、windows中Filemapping)。如下圖:

2012-04-06 <wbr>16:26 <wbr>作業系統中的page <wbr>cache機制

    在使用mmap呼叫時,系統並不是馬上為其分配記憶體空間,而僅僅是新增一個VMA到該程序中,當程式訪問到目標空間時,產生缺頁中斷。在缺頁中斷中,從pagecaches中查詢要訪問的檔案塊,若未命中,則啟動磁碟I/O從磁碟中載入到pagecaches。然後將檔案塊在pagecaches中的物理頁對映到程序mmap地址空間。

    當程式退出或關閉檔案時,系統是否會馬上清除page caches中的相應頁面呢?答案是否定的。由於該檔案可能被其他程序訪問,或該程序一段時間後會重新訪問,因此,在實體記憶體足夠的情況下,系統總是將其保持在page caches中,這樣可以提高系統的整體效能(提高page caches的命中率,儘量少的訪問磁碟)。只有當系統實體記憶體不足時,核心才會主動清理page caches。

    當程序呼叫write修改檔案時,由於page cache的存在,修改並不是馬上更新到磁碟,而只是暫時更新到page caches中,同時mark 目標page為dirty,當核心主動釋放pagecaches時,才將更新寫入磁碟(主動呼叫sync時,也會更新到磁碟)。

       Filemapping可以是共享或私有的。對於共享的Filemapping,情況較簡單。多個程序mmap對映到相同的pagecache。

    當filemapping為私有的時,為了防止一個程序修改操作影響到另一個程序,處理情形如下圖:

2012-04-06 <wbr>16:26 <wbr>作業系統中的page <wbr>cache機制