2016-01-25 35 views
1

我使用CreateFile()WriteFile()將約100個大小爲50MB的文件依次寫入磁盤上的目錄。第二步,使用CreateFile()ReadFile()來讀取這些文件的內容。爲什麼使用操作系統和磁盤緩衝區寫入文件後讀取操作要快得多?

我注意到一些局部奇怪的事情:
如果我通過FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH寫文件時,讀取需要noticably長的時間(通常幾百毫秒)。但是,當我不通過這些標誌(但使用FlushFileBuffers()代替)時,寫入似乎以大致相同的速度發生,但在寫入文件後讀取這些文件的速度非常快(每個文件少於20毫秒!)。

這怎麼可能?在寫入5000MB數據後會如何影響讀取?磁盤是否緩存整個5GB?

回答

2

當您通過FILE_FLAG_NO_BUFFERING時,您告訴系統不要將數據放入其磁盤緩存中。然後當你讀取數據時,系統必須從磁盤獲取數據。

當您忽略FILE_FLAG_NO_BUFFERING時,系統可以將數據放入其磁盤緩存中。所以當你隨後讀取數據時,它可以直接從內存中讀取,這比磁盤快。

https://support.microsoft.com/en-us/kb/99794

爲的CreateFile的FILE_FLAG_WRITE_THROUGH標誌()使得該手柄由任何寫操作被直接寫入文件而不被緩衝。數據被緩存(存儲在磁盤緩存中);但是,它仍然直接寫入文件。此方法允許對該數據執行讀操作,以滿足來自緩存數據(如果仍然存在)的讀取請求,而不必執行文件讀取以獲取數據。寫入調用在數據寫入文件之前不會返回。這也適用於遠程寫入 - 網絡重定向器將FILE_FLAG_WRITE_THROUGH標誌傳遞給服務器,以便在數據寫入文件之前服務器知道不滿足寫入請求。

FILE_FLAG_NO_BUFFERING將此概念推進了一步,並消除了所有預讀文件緩衝和磁盤緩存,以確保所有讀取都來自文件,而不是來自任何系統緩衝區或磁盤緩存。

您可能感興趣的文章Raymond Chen:We’re currently using FILE_FLAG_NO_BUFFERING and FILE_FLAG_WRITE_THROUGH, but we would like our WriteFile to go even faster。摘錄:

一位顧客說,他們的程序的I/O模式是打開一個文件,然後 每隔一段時間寫數據的100KB到文件中。他們目前正在使用的 FILE_FLAG_NO_BUFFERING和FILE_FLAG_WRITE_THROUGH 標誌打開一個文件,他們想知道他們可以做些什麼 讓自己寫去得更快。

嗯,一件事,你停止通過這兩個標誌!

這兩個標誌的組合基本上意味着「給我最慢的 可能的I/O性能!」,因爲它們強制所有I/O立即通過物理介質到達 。

+0

這是否意味着RAM負載的增加,因爲5GB需要緩存在RAM中?在執行我的程序期間,我看不到有任何顯着的RAM變化。 –

+0

你如何測量磁盤緩存使用了多少內存? –

+0

我使用默認的Windows性能監視工具來測量RAM。如果5GB被緩存,我預計會看到一些差異。我剛剛編輯了我的問題,並補充說我在每次寫入後都使用'FlushFileBuffers()',並且我懷疑即使在使用FlushFileBuffers()後Windows仍然將這些文件保存在緩存中。 –