2010-01-10 125 views
6

我正在讀取一個文件,並且我讀取一行數據(1600個連續讀取的17個字節)或一列數據(1600個讀取的17個字節以1600 * 17分隔= 27,200字節)。該文件位於本地驅動器或遠程驅動器上。我做了10次讀取,因此我預計在每種情況下都會讀取272,000字節的數據。通過網絡讀取文件由於額外讀取緩慢

在本地驅動器上,我看到了我的期望。在順序讀取時,在遠程驅動器上,我也看到了我期望的內容,但是當閱讀一篇專欄文章時,我看到大量的額外讀取正在完成。它們的長度爲32,768字節,看起來並沒有被使用,但它們使讀取的數據量從272,000字節跳到79 MB到106 MB的任何地方。下面是使用進程監視器輸出:

 
1:39:39.4624488 PM DiskSpeedTest.exe 89628 ReadFile \\BCCDC01\BCC-raid3\SeisWareInc Temp Dir\BPepers_Temp\Projects\PT_4\Horizons\BaseName3D_1\RR_AP SUCCESS Offset: 9,390,069, Length: 17 
1:39:39.4624639 PM DiskSpeedTest.exe 89628 FASTIO_CHECK_IF_POSSIBLE \\BCCDC01\BCC-raid3\SeisWareInc Temp Dir\BPepers_Temp\Projects\PT_4\Horizons\BaseName3D_1\RR_AP SUCCESS Operation: Read, Offset: 9,390,069, Length: 17 
1:39:39.4624838 PM DiskSpeedTest.exe 89628 ReadFile \\BCCDC01\BCC-raid3\SeisWareInc Temp Dir\BPepers_Temp\Projects\PT_4\Horizons\BaseName3D_1\RR_AP SUCCESS Offset: 9,388,032, Length: 32,768, I/O Flags: Non-cached, Paging I/O, Synchronous Paging I/O, Priority: Normal 
1:39:39.4633839 PM DiskSpeedTest.exe 89628 ReadFile \\BCCDC01\BCC-raid3\SeisWareInc Temp Dir\BPepers_Temp\Projects\PT_4\Horizons\BaseName3D_1\RR_AP SUCCESS Offset: 9,417,269, Length: 17 
1:39:39.4634002 PM DiskSpeedTest.exe 89628 FASTIO_CHECK_IF_POSSIBLE \\BCCDC01\BCC-raid3\SeisWareInc Temp Dir\BPepers_Temp\Projects\PT_4\Horizons\BaseName3D_1\RR_AP SUCCESS Operation: Read, Offset: 9,417,269, Length: 17 
1:39:39.4634178 PM DiskSpeedTest.exe 89628 ReadFile \\BCCDC01\BCC-raid3\SeisWareInc Temp Dir\BPepers_Temp\Projects\PT_4\Horizons\BaseName3D_1\RR_AP SUCCESS Offset: 9,444,469, Length: 17 
1:39:39.4634324 PM DiskSpeedTest.exe 89628 FASTIO_CHECK_IF_POSSIBLE \\BCCDC01\BCC-raid3\SeisWareInc Temp Dir\BPepers_Temp\Projects\PT_4\Horizons\BaseName3D_1\RR_AP SUCCESS Operation: Read, Offset: 9,444,469, Length: 17 
1:39:39.4634529 PM DiskSpeedTest.exe 89628 ReadFile \\BCCDC01\BCC-raid3\SeisWareInc Temp Dir\BPepers_Temp\Projects\PT_4\Horizons\BaseName3D_1\RR_AP SUCCESS Offset: 9,441,280, Length: 32,768, I/O Flags: Non-cached, Paging I/O, Synchronous Paging I/O, Priority: Normal 
1:39:39.4642199 PM DiskSpeedTest.exe 89628 ReadFile \\BCCDC01\BCC-raid3\SeisWareInc Temp Dir\BPepers_Temp\Projects\PT_4\Horizons\BaseName3D_1\RR_AP SUCCESS Offset: 9,471,669, Length: 17 
1:39:39.4642396 PM DiskSpeedTest.exe 89628 FASTIO_CHECK_IF_POSSIBLE \\BCCDC01\BCC-raid3\SeisWareInc Temp Dir\BPepers_Temp\Projects\PT_4\Horizons\BaseName3D_1\RR_AP SUCCESS Operation: Read, Offset: 9,471,669, Length: 17 
1:39:39.4642582 PM DiskSpeedTest.exe 89628 ReadFile \\BCCDC01\BCC-raid3\SeisWareInc Temp Dir\BPepers_Temp\Projects\PT_4\Horizons\BaseName3D_1\RR_AP SUCCESS Offset: 9,498,869, Length: 17 
1:39:39.4642764 PM DiskSpeedTest.exe 89628 FASTIO_CHECK_IF_POSSIBLE \\BCCDC01\BCC-raid3\SeisWareInc Temp Dir\BPepers_Temp\Projects\PT_4\Horizons\BaseName3D_1\RR_AP SUCCESS Operation: Read, Offset: 9,498,869, Length: 17 
1:39:39.4642922 PM DiskSpeedTest.exe 89628 ReadFile \\BCCDC01\BCC-raid3\SeisWareInc Temp Dir\BPepers_Temp\Projects\PT_4\Horizons\BaseName3D_1\RR_AP SUCCESS Offset: 9,498,624, Length: 32,768, I/O Flags: Non-cached, Paging I/O, Synchronous Paging I/O, Priority: Normal 

通知與我的32,768額外的讀取/設置爲O標記的非緩存,分頁I/O,同步分頁I/O,優先級:正常。這些額外的讀取是從272 KB到106 MB,並導致緩慢。從本地文件讀取時,或者如果我正在讀取一行,所以它們都是順序的,它們不會發生。

我試過設置FILE_FLAG_RANDOM_ACCESS,但它似乎沒有幫助。任何想法是什麼導致這些額外的讀取,以及如何使他們停止?

測試正在Vista 64位系統上運行。我可以提供程序的源代碼來演示問題以及執行測試的控制檯程序。

+1

也許你可以粘貼你讀取的代碼部分。這將排除一些編碼錯誤,這比平臺錯誤更常見:-) – Ariel 2010-01-12 13:44:14

回答

2

您可能會遇到smb的操作鎖問題。通常,當通過網絡讀取/保存文件時,窗口將把整個文件拖到客戶機上併發送更改。當您使用平面文件數據庫或文件時,它可能會導致跨smb文件共享進行不必要的讀取。

我不確定是否有一種方法可以將整個文件拉過來,從本地副本上的該文件中讀取行,然後再推回所做的更改。

你會讀到關於oplocks和平面文件數據庫的一些噩夢。

http://msdn.microsoft.com/en-us/library/aa365433%28VS.85%29.aspx

不知道這是否解決您的問題,但它可能讓你在正確的方向。祝你好運!

0

我總是看到這一點,它超出了你的控制範圍:網絡按照自己的意願去做。

如果您知道該文件將小於1MB,只需將整個內容拉入內存。

0

我的猜測是,操作系統正在自己對文件進行預讀,以避免您稍後需要數據。如果它不傷害你,那麼它應該無關緊要。

Checkout caching behavoir CreateFile API的一部分。

您可能想嘗試'FILE_FLAG_NO_BUFFERING'來查看它是否停止了額外的讀取。被警告,使用這個標誌可能會減慢你的應用程序。通常情況下,如果您瞭解如何儘可能快地從磁盤流式傳輸數據,並且操作系統緩存只能以此方式使用,則可以使用此標誌。

如果您使用'FILE_FLAG_SEQUENTIAL_SCAN'標誌,您也許能夠獲得與具有本地文件的網絡文件相同的行爲。這個標誌向Windows緩存管理器提示你將要做什麼,並且會嘗試提前爲你提供數據。

0

我認爲SMB總是傳輸一個塊,而不是一小組字節。

有關塊大小協商的一些信息可以在這裏找到。 http://support.microsoft.com/kb/q223140

因此,您看到一個讀取複製相關塊,然後是該塊內的本地17個字節的讀取。 (如果查看模式,則有一對17字節讀取,其中兩個讀取落在同一個塊中)。

該修復顯然取決於您對應用程序以及數據庫大小和結構的控制。 (例如,如果數據庫每個文件只有一列,那麼所有的讀取都是順序的,如果你使用的是數據庫服務器,則不會使用SMB等等)

如果是任何安慰,iTunes performs abysmally when using a network drive too

2

我找到了答案。 Windows通過頁面緩存進行文件讀取,因此當我讀取17個字節時,它首先必須傳輸32K的整頁,然後才能將我想要的17個字節複製到頁面緩存中。表現惡劣的結果!

第一次在本地文件上完成讀取時實際上發生了同樣的事情,因爲在這種情況下,它仍然一次將整個頁面加載到頁面緩存中。但是我第二次在本地運行測試時,這些文件都已經在頁面緩存中,所以我沒有看到它。如果SuperFetch打開並且我一直在做這些測試,Windows將開始將文件加載到緩存之前我甚至運行我的測試應用程序,所以我再也看不到頁面讀取正在完成。

因此,操作系統在背後做了很多事情,使得很難完成良好的性能測試!