4

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

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

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

我能为此做些什么吗?

4

7 回答 7

8

1) Windows 会在内存中缓存最近读取的文件。《Windows Internals 》一书很好地描述了它是如何工作的。现代版本的 Windows 还使用一种称为 SuperFetch 的技术,该技术将尝试根据使用历史记录抢先将磁盘内容提取到内存中,而 ReadyBoost 可以缓存到闪存驱动器,从而实现更快的随机访问。所有这些都将提高初始运行后从磁盘访问数据的速度。

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

于 2009-09-29T18:27:07.400 回答
8

您编号的问题似乎已经得到解答。如果您仍然想知道如何提高硬盘读取速度,这里有一些提示:

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

是的,Windows(和大多数现代操作系统)将最近读取的文件数据保存在其他未使用的 RAM 中,这样如果在不久的将来再次请求该文件数据,它将已经在 RAM 中可用,并且可以避免磁盘访问。

至于使磁盘访问更快,您可以尝试对驱动器进行碎片整理,但我不希望它有太大帮助。与 RAM 访问相比,驱动器访问速度很慢,这就是 RAM 缓存提供如此出色加速的原因。

于 2009-09-29T18:20:34.967 回答
2

作为诊断测试,您能否准确测量第一次加载所需的时间?

然后用它来确定传输速率。然后,您可以采用该传输速率并将其与运行HD Tune时获得的传输速率进行比较。值得一提的是,我自己运行它,我的 Western Digital RE3 驱动器(可用的更快的 7200 RPM SATA 驱动器之一)获得了最低 44.2 MB/s、平均 87 MB/s、最高 110 MB/s 的读取速度。

所有这一切的重点是查看您自己的应用程序是否尽其所能。换句话说,除了缓存之外,您无法真正比​​硬盘驱动器更快地读取文件。因此,如果您达到了该限制,那么就没有什么可做的了。

于 2009-09-29T18:47:07.733 回答
2

此外,请确保您在测试期间没有耗尽内存。运行 perfmon 并监视正在读取的物理驱动器的 Memory > Available Bytes 和 PhysicalDisk > Disk Read Bytes/sec。监控进程的 I/O 也是一个好主意。请记住,后者结合了所有 I/O(包括网络)。

您应该期望从单个普通 SATA 驱动器进行连续读取的速度为 50 MB/s。几个好的条带串行 SCSI 驱动器将为您提供大约 220 MB/s。如果您看到可用内存接近于零,那将是您的问题。如果在您进行第一轮阅读后它保持平稳,那么它与您的应用程序有关。

于 2009-09-30T03:00:50.817 回答
1

称为contig的 Microsoft 实用程序可用于对磁盘上的单个文件进行碎片整理或创建新的未碎片整理文件。

于 2009-09-29T18:56:34.283 回答
0

对于疯狂的答案,您可以尝试格式化驱动器,以便将信息放在最快的部分,看看是否有帮助。

Tom's Hardware对如何做到这一点进行了审查。

于 2009-09-30T20:34:49.443 回答