硬盘读取的性能问题

Nav*_*een 4 c++ performance winapi disk

我有一个C++程序,它从硬盘上读取文件,并对文件中的数据进行一些处理.我使用标准的Win32 API来读取文件.我的问题是这个程序有时非常快,然后突然减慢到之前速度的1/6.如果我在多次运行中一次又一次地读取相同的文件,那么通常第一次运行将是最慢的.然后它保持速度,直到我读取其他一组文件.所以我明显的猜测是分析磁盘访问时间.我使用了perfmon实用程序并测量了我的程序的IO读取字节数/秒.正如预期的那样,读取的字节数存在巨大差异(约5倍).我的问题是:

(1).OS(在我的情况下是Windows)是否将最近读取的文件缓存到某处,以便后续加载更快?

(2).如果我可以保证我读取的所有文件都位于同一目录中,那么有什么方法可以将它们放在硬盘中以便我的磁盘访问时间更快?

我能为此做点什么吗?

Mic*_*ael 8

1)Windows会将最近读取的文件缓存到内存中.Windows Internals这本书包含了对其工作原理的精彩描述.Windows的现代版本也使用名为SuperFetch的技术,该技术将尝试根据使用历史预先将磁盘内容提取到内存中,而ReadyBoost可以缓存到闪存驱动器,从而实现更快的随机访问.所有这些都将提高初始运行后从磁盘访问数据的速度.

2)目录确实不会影响磁盘上的布局.对驱动器进行碎片整理会将文件数据组合在一起.Windows Vista on up将自动对磁盘进行碎片整理.理想情况下,您希望执行大型顺序读取并最小化写入.小的随机访问和带有读取的交错写入会严重损害性能.您可以使用Windows性能工具包来分析磁盘访问.


Adr*_*thy 8

您的编号问题似乎已经得到了解答.如果您仍然想知道如何提高硬盘读取速度,请参考以下提示:

  • 如果可能,请阅读OS功能(例如ReadFile),而不是包装库(如iostreamsstdio).许多包装器引入了更多级别的缓冲.
  • 按顺序读取,让Windows知道你将按顺序读取FILE_FLAG_SEQUENTIAL_SCAN标志.
  • 如果您只想阅读(而不是写),请务必打开文件进行阅读.
  • 读取块,而不是字节或字符.
  • 理想情况下,块应该是磁盘簇大小的倍数.
  • 在群集对齐的偏移处从光盘读取.
  • 在页面边界读取内存.(如果你要分配一个大块,它可能是页面对齐的.)
  • 高级:如果您只是在读取文件的开头后就可以开始计算,那么您可以使用重叠的I/O来尝试尽可能地并行化计算和后续读取.