2010-01-10 79 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将开始将文件加载到缓存之前我甚至运行我的测试应用程序,所以我再也看不到页面读取正在完成。

因此,操作系统在背后做了很多事情,使得很难完成良好的性能测试!