使用操作系统和磁盘缓冲区写入文件后,为什么读取操作会更快?

时间:2016-01-25 11:08:43

标签: windows winapi buffer disk hard-drive

我正在使用CreateFile()WriteFile()将大约50MB的文件按顺序写入磁盘上的目录。在第二步中,使用CreateFile()ReadFile()来读取这些文件的内容。

我注意到一些奇怪的事情:
如果我在写文件时传递FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH,那么读取需要花费相当长的时间(通常是几百毫秒)。但是,当我没有传递这些标志(但是使用FlushFileBuffers()代替)时,写入似乎以大致相同的速度发生,但是在写入之后读取这些文件的速度非常快(每个文件少于20毫秒!)。 / p>

这怎么可能?写5000MB数据时标志如何影响以后读取?磁盘是否在其缓存中缓存整个5GB?

1 个答案:

答案 0 :(得分: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都通过   物理媒体马上。

相关问题