1. 程式人生 > >快取管理器是什麼

快取管理器是什麼

快取管理器

Windows 的快取管理器是一組核心模式的函式和系統例程,為所有的Windows檔案系統驅動程式提供了系統快取的能力。

Windows 快取管理器按照虛擬地址為基礎來快取資料,它被賦予系統虛擬地址空間中的一個區域來進行管理。快取管理器將每個地址空間區域分成256KB 的槽,稱為檢視:

 

系統中每個256KB 的槽都是通過一個VACB 來描述的;每個被單獨開啟的、被快取的檔案都有一個私有的快取表,其中包含了用於控制預讀的資訊;

每個被快取的檔案都有一個共享的快取表結構,它指向系統快取中包含有該檔案對映檢視的那些槽

 

VACB 陣列的地址儲存在變數CcVacbs 中。

VACB中的第一個域是資料在系統快取中的虛擬地址。 第二個域是一個指標,指向共享的快取表結構,它標識了哪個檔案被快取了

。第三個域標識了該檢視在檔案內部的偏移(總是以256KB粒度為基礎)。最後,VACB包含了該檢視的引用數,也就是說,有多少活動的讀或寫操作正在訪問該檢視。非零時,此VACB是活動的(active)。對於檔案系統元資料的訪問,活動計數代表了有多少個檔案系統驅動程式使該檢視中的頁面鎖定在記憶體中。

針對每個檔案的快取資料結構

開啟的檔案對應檔案物件,如果檔案被快取了,該檔案物件指向一個私有的快取表結構,這個結構包含了最近兩次讀的位置,所以,快取管理器可以執行智慧預讀,針對同一個檔案的已開啟例項的所有私有快取表被連結在一起。

每一個被快取的檔案,都有一個共享的快取表結構,描述了快取的檔案的狀態,比如大小,有效的資料長度。同時,共享快取表指向了由記憶體管理器所維護的記憶體區物件、與該檔案相關聯的私有快取表的列表,以及VACB。

對於給定的檔案,快取管理器維護了一個VACB 指標陣列,稱為VACB 索引陣列,第一項指向該檔案的第一個256KB,第二個指向第二個256KB…

當一個程序訪問一個特定檔案的特定位置,找到正確的VACB 陣列項,確定所請求的資料是否已經被對映到系統快取中了。是,進行操作,否,在系統快取中找到一個空閒槽,以對映所請求的檢視。

 

當然,對於比較大的檔案,以及特別大的檔案,VACB索引陣列的大小並不會相應的無線擴大。共享的快取表包含了一個VACB 索引陣列,含4個索引項,描述1MB。如果1MB<檔案大小<32MB從非換頁記憶體池中分配一個單獨VACB 索引陣列,大小為該檔案的大小/256KB並向上取整。>32MB,從非換頁記憶體池中分配的VACB 索引陣列變成一個稀疏的多級索引陣列,每個索引陣列包含128項,一個檔案所需要的級數:

(表示檔案大小所需要的位數– 18)/7

檔案系統訪問檔案的資料有三種方式:

從快取中來回拷貝資料

因為系統快取位於系統空間中,無法從使用者模式中訪問的,使用者應用程式若要讀寫被快取的檔案,則必須通過核心模式的例程來獲得服務:這些核心模式例程在“系統空間的快取緩衝區”和“駐留在程序地址空間中的應用程式緩衝區”之間拷貝資料。被檔案系統驅動程式用來執行這一操作的函式如下表

函式

說明

CcCopyRead

將指定的位元組範圍從系統快取拷貝到使用者緩衝區中

CcFastCopyRead

CcCopyRead的一個變形,更加快速,但也有限制:32位檔案偏移,以及同 步讀操作

CcCopy Write

將指定的位元組範圍從使用者緩衝區拷貝到系統快取中

CcFastCopyWrite

CcCopyWrite的一個變形,更加快速,但也有限制:32位檔案偏移,以及同步的、非直寫(non-write-through)的寫操作(NTFS使用這種寫糢式,FAT 不使用)

通過對映和鎖定接□進行快取

當用戶應用程式讀和寫磁碟檔案中的資料時,檔案系統驅動程式需要讀和寫那些描述這些檔案本身的資料(元資料,或者卷結構資料)。然而,由於檔案系統驅動程式執行在核心模式 下,因此,如果快取管理器被正確地通知到的話,這些檔案系統驅動程式就可以直接修改系統快取中的資料。為了允許這種優化,快取管理器提供了表11.6中所示的函式。這些函式使得文件系統驅動程式可以找到檔案系統的元資料駐留在虛擬記憶體中的什麼地方,因此允許直接進行元資料修改,而無需使用中間緩衝區

尋找元資料位置的函式

函式

說明

CcMapData

為了讀訪問而對映一段位元組範圍

CcPinRead

為了讀/寫訪問而對映一段位元組範圍,並鎖定這段範圍

CcPreparePinWrite

為了寫訪問(讀訪問不是有效的)而對映並鎖定一段位元組範圍

CcPinMappedData

鎖定一個原先已被對映的緩衝區

CcSetDirtyPinnedData

通知快取管理器,此資料已被修改了

CcUnpinData

釋故這些頁面,因而它們可以被從記憶體中移除

如果一個檔案系統驅動程式需要讀快取中的檔案系統元資料,那麼,它呼叫快取管理器的對映接門來獲得目標資料的虛擬地址。快取管理器尋找所有被請求的頁面,並把它們帶入到內存中,然後將控制返回給檔案系統驅動程式。於是,檔案系統驅動程式可以直接訪問這些資料

如果檔案系統驅動程式需要修改快取中的頁面,那麼,它呼叫快取管理器的鎖定服務,該服務會將這些被修改的頁面保持在記憶體中。這些頁面並不真的被鎖在記憶體中(比如當裝置驅動程式為了直接記憶體訪問傳輸而鎖住頁面時所做的那樣)。在絕大多數時間,檔案系統驅動程式將它的元資料流標記為“不可寫出(no write) •,這指示記憶體管理器的對映頁面寫出器不要將這些頁面寫出到磁碟上,直到明確地通知它可以寫出為止當檔案系統驅動程式解除鎖定(釋放)這些頁面時,快取管理器將所有的變化重新整理到磁碟上,並且釋放這些元資料所佔據的快取檢視

對映和鎖定介面解決了一個在實現檔案系統時很棘手的問題:緩衝區管理。檔案系統若不能直接操作被快取的元資料,那麼,它必須預測“當它更新一個卷的結構時”所需緩衝區的最大數量。由於允許檔案系統直接訪問和更新快取中的元資料,因此,快取管理器消除了對緩衝區的需求,檔案系統只需簡單地更新記憶體管理器所提供的虛擬記憶體中的卷結構即可。檔案系統所碰到的惟一限制是,有多少記憶體可供使用。

通過直接記憶體訪問介面進行快取

直接記憶體訪問(DMA)。通過DMA函式,可以直接讀或寫系統快取的頁面,而無需經由緩衝區的介入。

DMA介面將被快取的使用者資料的實體地址返回給檔案系統,然後,這些實體地址可以直接被用於在實體記憶體和網路裝置之間傳輸資料。

為了描述這些對於實體記憶體的引用,需要用到記憶體描述符列表(MDL)

函式

說明

CcMdIRead

返回一個描迷了指定位元組範圍的MDL

CcMdIReadComplete

釋放MDL

CcMdIWrite

返回一個“描述一指定位元組範圍(可能包含了零)”的MDL

CcMdlWriteComplete

釋放MDL,並將該範圍標記為已被修改

快速 I/O

快速I/O是一種對於被快取檔案的讀寫方法,它無需經過“生成一個IRP”這樣的環節。通過快速I/O, I/O管理器呼叫檔案系統驅動程式的快速I/O 例程,以確定該I/O是否可以直接由快取管理器來滿足,而無需生成一個1RP。

因為快取管理器是建立在虛擬記憶體子系統之上的,因此,檔案系統驅動程式只需簡單地對於“對映到實際被引用檔案”的頁面進行資料拷貝,就可以使用快取管理器來訪問檔案資料,這樣做也避免了生成一個IRP所需要的開銷。

 

在用快速I/O 服務一個讀或寫操作的時候:

1.      執行緒執行讀或者寫操作

2.      如果檔案已經快取,且同步I/O,該請求被傳遞給檔案系統驅動程式的快速I/O u入口點,如果檔案尚未被快取,檔案系統驅動程式建立起該檔案的快取訪問環境,因而下一次可以使用快速I/O 來處理一個讀或寫請求。

3.      如果檔案系統驅動程式的快速I/O 例程確定快速I/O 是可能的,呼叫快取管理器的讀或寫例程來直接訪問快取中的檔案資料(如果快速I/O 不可能,生成一個IRP,並最終呼叫檔案系統的常規讀例程。

4.      .快取管理器將所提供的檔案偏移轉譯成快取中的虛擬地址。

5.      對於讀操作,快取管理器將資料從快取拷貝到發出該請求的程序的緩衝區中:對於寫操作,它將資料從程序緩衝區拷貝到快取中。

6.      以下動作之一發生:

對於讀操作:若檔案開啟時未指定FILE_FLAG_RANDOM_ACCESS ,呼叫者的私有快取表中的預讀資訊被更新

對於寫操作:快取中任何已修改頁面的髒位被設定,因而延遲寫出器將知道該把這些頁面重新整理到磁碟上

對於直寫的檔案(write-throungh file),任何修改都被重新整理到磁碟上。

快速I/O 並不總是發生的

非同步讀寫;同步I/O 上,檔案系統驅動程式可以確定該I/O 不能用於快速I/O 機制來處理,如果所涉及的檔案有一個鎖定的位元組範圍(呼叫LockFile和 UnlockFile函式的結果),而快取管理器不知道哪些檔案的哪些部分被鎖定了,檔案系統驅動程式必須檢查讀寫的有效性。

有關普通檔案I/O 和對映檔案I/O 的效能問題:

通過上面的介紹我們瞭解到,其實快取管理器就是利用的記憶體區物件來實現類似於對映檔案讀寫的過程,只不過,記憶體區物件的使用和維護是由作業系統控制的,而我們顯式使用對映檔案讀寫檔案的時候自己控制了記憶體區物件的使用,比較直接,因此,一般檔案的讀寫過程與記憶體對映檔案讀寫資料的效能差距在於,快取管理器需要將檔案資料先拷貝到系統快取中,然後再拷貝到使用者提供的快取區中,而記憶體對映檔案可以直接將檔案資料拷貝到使用者快取區中)。

下面這個部落格做了驗證性實驗,讀寫磁碟資料較少(小於1MB)的時候,使用記憶體檔案對映和普通IO 差異很小,大檔案需要進行較為頻繁的訪問,或者一開始需要全部載入這些大檔案的時候,就要考慮使用記憶體檔案對映。

http://www.voidcn.com/blog/lishenglong666/article/p-1213219.html