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\Horizo​​ns\BaseName3D_1\RR_AP SUCCESS 偏移量:9,390,069,长度:17
1:39:39.4624639 PM DiskSpeedTest.exe 89628 FASTIO_CHECK_IF_POSSIBLE \\BCCDC01\BCC-raid3\SeisWareInc Temp Dir\BPepers_Temp\Projects\PT_4\Horizo​​ns\BaseName3D_1\RR_AP 成功操作:读取,偏移:9,390,069,长度:17
1:39:39.4624838 PM DiskSpeedTest.exe 89628 ReadFile \\BCCDC01\BCC-raid3\SeisWareInc Temp Dir\BPepers_Temp\Projects\PT_4\Horizo​​ns\BaseName3D_1\RR_AP 成功偏移:9,388,032,长度:32,768,I/O 标志:非缓存,分页 I/O,同步分页 I/O,优先级:正常
1:39:39.4633839 PM DiskSpeedTest.exe 89628 ReadFile \\BCCDC01\BCC-raid3\SeisWareInc Temp Dir\BPepers_Temp\Projects\PT_4\Horizo​​ns\BaseName3D_1\RR_AP SUCCESS 偏移量:9,417,269,长度:17
1:39:39.4634002 PM DiskSpeedTest.exe 89628 FASTIO_CHECK_IF_POSSIBLE \\BCCDC01\BCC-raid3\SeisWareInc Temp Dir\BPepers_Temp\Projects\PT_4\Horizo​​ns\BaseName3D_1\RR_AP 成功操作:读取,偏移:9,417,269,长度:17
1:39:39.4634178 PM DiskSpeedTest.exe 89628 ReadFile \\BCCDC01\BCC-raid3\SeisWareInc Temp Dir\BPepers_Temp\Projects\PT_4\Horizo​​ns\BaseName3D_1\RR_AP SUCCESS 偏移量:9,444,469,长度:17
1:39:39.4634324 PM DiskSpeedTest.exe 89628 FASTIO_CHECK_IF_POSSIBLE \\BCCDC01\BCC-raid3\SeisWareInc Temp Dir\BPepers_Temp\Projects\PT_4\Horizo​​ns\BaseName3D_1\RR_AP 成功操作:读取,偏移:9,444,469,长度:17
1:39:39.4634529 PM DiskSpeedTest.exe 89628 ReadFile \\BCCDC01\BCC-raid3\SeisWareInc Temp Dir\BPepers_Temp\Projects\PT_4\Horizo​​ns\BaseName3D_1\RR_AP 成功偏移:9,441,280,长度:32,768,I/O 标志:非缓存,分页 I/O,同步分页 I/O,优先级:正常
1:39:39.4642199 PM DiskSpeedTest.exe 89628 ReadFile \\BCCDC01\BCC-raid3\SeisWareInc Temp Dir\BPepers_Temp\Projects\PT_4\Horizo​​ns\BaseName3D_1\RR_AP SUCCESS 偏移量:9,471,669,长度:17
1:39:39.4642396 PM DiskSpeedTest.exe 89628 FASTIO_CHECK_IF_POSSIBLE \\BCCDC01\BCC-raid3\SeisWareInc Temp Dir\BPepers_Temp\Projects\PT_4\Horizo​​ns\BaseName3D_1\RR_AP 成功操作:读取,偏移:9,471,669,长度:17
1:39:39.4642582 PM DiskSpeedTest.exe 89628 ReadFile \\BCCDC01\BCC-raid3\SeisWareInc Temp Dir\BPepers_Temp\Projects\PT_4\Horizo​​ns\BaseName3D_1\RR_AP SUCCESS 偏移量:9,498,869,长度:17
1:39:39.4642764 PM DiskSpeedTest.exe 89628 FASTIO_CHECK_IF_POSSIBLE \\BCCDC01\BCC-raid3\SeisWareInc Temp Dir\BPepers_Temp\Projects\PT_4\Horizo​​ns\BaseName3D_1\RR_AP 成功操作:读取,偏移:9,498,869,长度:17
1:39:39.4642922 PM DiskSpeedTest.exe 89628 ReadFile \\BCCDC01\BCC-raid3\SeisWareInc Temp Dir\BPepers_Temp\Projects\PT_4\Horizo​​ns\BaseName3D_1\RR_AP 成功偏移:9,498,624,长度:32,768,I/O 标志:非缓存,分页 I/O,同步分页 I/O,优先级:正常

注意 32,768 的额外读取,其中 I/O 标志设置为非缓存、分页 I/O、同步分页 I/O、优先级:正常。这些额外的读取将它从 272 KB 带到 106 MB 并导致缓慢。从本地文件读取或读取一行时它们不会发生,所以它们都是连续的。

我试过设置 FILE_FLAG_RANDOM_ACCESS 但它似乎没有帮助。关于导致这些额外读取的原因以及如何使它们停止的任何想法???

测试在 Vista 64 位系统上运行。我可以提供一个程序的源代码来演示这个问题,以及一个进行测试的控制台程序。

4

5 回答 5

2

I found the answer to this. Windows does file reads through the page cache so when I read 17 bytes, it first has to transfer a full page of 32K over and then can copy the 17 bytes I want out of the page cache. Nasty result on performance!

The same thing is actually happening the first time the reads are done on a local file since in that case it does still load a full page at a time into the page cache. But the second time I run the test locally, the files are all already in the page cache so I don't see it. And if SuperFetch is turned on and I've been doing these tests for a while, Windows will start loading the file into the cache before I even run my test application so again I don't see the page reads being done.

So the operating system is doing a lot of things behind the scenes that makes it tough to get good performance testing done!

于 2011-11-29T04:41:43.313 回答
2

您可能会在 smb 上遇到操作锁定问题。通常,当通过网络读取/保存文件时,windows 会将完整文件拉到客户端处理它并发送回更改。当您使用平面文件数据库或文件时,可能会导致对 smb 文件共享进行不必要的读取。

我不确定是否有办法只提取整个文件,从本地副本上的该文件中读取行,然后推回更改。

你会读到一些关于 oplocks 和平面文件数据库的噩梦。

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

不确定这是否能解决您的问题,但它可能会让您指向正确的方向。祝你好运!

于 2010-01-13T16:51:48.910 回答
0

我的猜测是,操作系统正在对文件进行自己的预读,以防您稍后需要数据。如果它不伤害你,那应该没关系。

查看CreateFile API 的缓存行为部分。

您可能想尝试“FILE_FLAG_NO_BUFFERING”,看看它是否会停止额外的读取。请注意,使用此标志可能会减慢您的应用程序的速度。通常,如果您了解如何尽可能快地从磁盘流式传输数据并且操作系统缓存只会妨碍您,那么您通常会使用此标志。

此外,如果您使用 'FILE_FLAG_SEQUENTIAL_SCAN' 标志,您可能能够获得与具有本地文件的网络文件相同的行为。此标志提示 Windows 缓存管理器您将要做什么,并将尝试提前为您获取数据。

于 2010-01-16T00:35:34.497 回答
0

我经常看到这种情况,而且它超出了你的控制:网络做它想做的事。

如果您知道文件将小于 1MB,只需将整个文件拉入内存即可。

于 2010-01-15T20:41:27.927 回答
0

我认为 SMB 总是传输一个块,而不是一小组字节。

可以在此处找到有关块大小协商的一些信息。 http://support.microsoft.com/kb/q223140

因此,您会看到复制相关块的读取,然后是块内 17 个字节的本地读取。(如果您查看模式,有一些 17 字节读取对,其中两个读取位于同一块内)。

修复显然取决于您对应用程序的控制以及数据库的大小和结构。(例如,如果数据库每个文件有一列,那么所有读取都是顺序的。如果您使用数据库服务器,则不会使用 SMB 等)

如果有什么安慰的话,iTunes 在使用网络驱动器时也表现不佳

于 2010-01-17T20:20:42.907 回答