2010-10-20 112 views
13

我需要依次讀取(掃描)文件並處理其內容。 文件大小可以是從非常小(一些KB)到非常大(一些GB)的任何東西。Win32內存映射文件與CRT fopen/fread的性能

我嘗試使用VC10/VS2010兩種技術在Windows 7 64位:

  1. 的Win32存儲器映射文件(即的CreateFile,的CreateFileMapping,MapViewOfFile等)
  2. 的fopen和的fread從CRT。

我認爲內存映射文件技術可能比CRT功能更快,但是一些測試表明在這兩種情況下速度幾乎相同。

以下C++語句被用於MMF:

HANDLE hFile = CreateFile(
    filename, 
    GENERIC_READ, 
    FILE_SHARE_READ, 
    NULL, 
    OPEN_EXISTING, 
    FILE_FLAG_SEQUENTIAL_SCAN, 
    NULL 
    ); 

HANDLE hFileMapping = CreateFileMapping(
    hFile, 
    NULL, 
    PAGE_READONLY, 
    0, 
    0, 
    NULL 
    ); 

文件被順序地讀出,由大塊大塊;每個塊大小爲SYSTEM_INFO.dwAllocationGranularity

考慮到速度幾乎與MMF和CRT一樣,我會使用CRT函數,因爲它們更簡單和多平臺。但我很好奇:我是否正確使用MMF技術?這種情況下scannig文件中的MMF性能是否與CRT相同?

謝謝。

回答

14

我相信,如果您按順序訪問該文件,則看不到太多差異。由於文件I/O的緩存很大,所以可能還會使用預讀。

,如果你有很多「跳躍」文件數據處理過程中,事情會有所不同。然後,每次設定一個新的文件指針和閱讀一個新的文件部分可能會殺了CRT,而MMF會給你最大可能的性能

4

既然你要掃描的文件順序我不希望磁盤的使用模式是多少兩種方法都不同。

對於大文件,MMF可能會減少數據的局部性,甚至會導致將所有或部分文件放置在頁面文件中,而通過CRT使用小緩衝區進行處理將全部發生在RAM中。在這種情況下,MMF可能會變慢。您可以通過一次僅映射底層文件的一部分來減輕這種影響,但事情變得更加複雜,沒有任何可能勝過直接順序I/O。

MMF是真正的Windows實現進程間共享內存的方式,而不是一種方法,以加快我廣義的文件/ O。內核中的文件管理器緩存是您真正需要在這裏使用的內容。

+4

爲什麼MMF會把東西放在頁面文件中? MMF頁面由打開的數據文件支持,而不是頁面文件。 – 2012-02-23 23:14:32

+0

我同意本。複製到頁面文件似乎不太可能。 – Joe 2014-03-25 01:41:41

+0

是的,通過使用MMF明確避免了頁面文件。 http://blogs.msdn.com/b/khen1234/archive/2006/01/30/519483.aspx但請注意這個問題:「在將大文件映射到虛擬內存以對它們執行I/O時,請注意事實您在虛擬內存中刻錄的每個地址都是您的應用程序無法使用的地址,通常使用常規文件I/O例程在大型文件上執行讀取/寫入操作效率更高。「 – 2015-02-23 04:52:56

1

這兩種方法最終會回落到磁盤I/O,這將是你的瓶頸。如果我需要順序訪問和固定大小的文件,我會考慮使用內存映射文件,如果我需要流式處理,我將使用文件。

或者,當你有一個僅適用於存儲器中的算法的情況下,則MEM映射文件可以出更簡單的方法。

2

我認爲內存映射文件 技術能比CRT 功能更快,但一些試驗表明, 速度幾乎是在這兩種情況下, 相同。

您可能正在爲您的測試命中文件系統緩存。除非您明確創建文件句柄以跳過文件系統緩存(調用CreateFile時爲FILE_FLAG_NO_BUFFERING),否則文件系統緩存將啓動並將最近訪問的文件保留在內存中。

由於操作系統必須執行額外的副本以及系統調用開銷,因此讀取文件系統緩存中的文件與打開緩衝之間的速度差異很小。但爲了您的目的,您應該堅持使用CRT文件功能。 (從通用操作系統的角度來看)。