来自映射文件的 IO 与使用文件流的 IO

IO from a mapped file vs IO using filestreams

我正在开发一个需要处理大量数据(以 GB 为单位)的应用程序。我不需要在任何时刻一次获得所有数据。可以对数据进行分段并仅在任何给定实例上处理(并因此将其存入内存)一个部分。

我了解到大多数需要处理大量数据的应用程序通常通过使用内存映射文件来实现。进一步阅读内存映射文件,我发现 reading/writing 数据 from/into 内存映射文件比普通文件 IO 更快,因为我们最终使用高度优化的页面文件算法来执行读写。

以下是我的查询:

  1. 使用内存映射文件(我计划使用 boost::file_mapping 并且我正在研究 windows)进行文件 IO 与使用文件流有何不同?
  2. 与使用文件流(在传统硬盘 7200 rpm 上)相比,内存映射文件中的数据 read/writes 可以预期多快?
  3. 内存映射文件是处理如此海量数据的唯一方法吗?有没有更好的方法(考虑我的用例)?

1

基本上内存映射文件只是从硬盘移动到内存的一个块。所以它只是复制你制作的任何大小的块,然后与你的硬盘相比,你的内存可以有多快来操作该块。

2

正如我所说,你的内存速度和硬盘速度基本上是不同的。

3

没有太多的大数据经验,所以我觉得没有资格回答这个问题。

How different is using memory mapped files(I am planning to use boost::file_mapping and I am working on windows) for file IO than using file streams?

非常不同。使用内存映射文件时,您只需像访问内存一样访问文件。没有显式加载或保存文件。

这对您的应用程序和数据存储提出了要求。您必须确保可以通过这种方式访问​​您的数据。您还必须确保您可以将数据放入可寻址内存中 - 使用 32 位系统,您将被限制为几 Gb 的数据。

How much faster can I expect the data read/writes to be in case of memory mapped files when compared to using file streams(on a traditional hard disk 7200 rpm)?

别这么期待。如果您将指针页面对齐,它很可能具有相同的性能。另请注意,如果您读入数据并且它不适合物理 RAM,它将被换出,就像您将内存映射到文件时一样。

Is memory mapped files the only way to deal with such huge amounts of data? Are there better ways of doing this(considering my use case)?

这取决于你的实际情况。

  • 文件的内容永远不会在交换文件中结束
  • 一旦文件被映射,就不需要系统调用
  • 系统将优化RAM的使用
  • 如果写入内存映射文件并且您的进程崩溃,文件内容将与内存内容匹配,无需执行最终 (write/flush) 系统调用
  • 多个进程(在同一台机器上)可以查看同一文件的内容并立即传播更改 (reader/writer)。并且文件的内容不会在每个 reader/writer.
  • 的交换文件中结束
  • 多个进程将共享同一 RAM 以映射同一文件

(免责声明:我是 proposed Boost.AFIO 的作者)

How different is using memory mapped files(I am planning to use boost::file_mapping and I am working on windows) for file IO than using file streams?

大大简化的答案:

内存映射文件会延迟读取 4Kb 块,即当您第一次访问该 4Kb 页面时。当您请求数据时,文件流会进行读取。

更准确的答案:

内存映射文件使您可以直接访问文件 i/o 的内核页面缓存。您可以确切地看到内核为某个打开的文件保留了哪些内容。读取和写入直接到内核页面缓存 - 缓冲 i/o.

的速度再快不过了

How much faster can I expect the data read/writes to be in case of memory mapped files when compared to using file streams(on a traditional hard disk 7200 rpm)?

可能不明显。如果您对差异进行基准测试,则可能是混杂因素,例如不同的缓存算法。硬盘这么慢,它永远是主导因素。

现在,如果您真的要问效率如何 从系统负载的角度比较两者,那么内存映射文件的效率可能要高得多。 STL iostreams 至少复制一次内存,再加上 Windows 大多数 "immediate" i/o 实际上是来自 Windows 内核为您的进程配置的小型内部内存映射的 memcpy,所以那是你阅读的所有内容的至少两个内存副本。

效率最高的始终是 O_DIRECT/FILE_FLAG_NO_BUFFERING 伴随而来的所有问题,但是您编写的缓存算法比操作系统的算法好得多的情况非常罕见。毕竟,他们花了几十年时间调整他们的算法。

Is memory mapped files the only way to deal with such huge amounts of data? Are there better ways of doing this(considering my use case)?

内存映射文件让内核使用通用缓存算法为您缓存一个非常大的数据集,该算法利用您系统中的所有可用内存。一般来说,对于大多数用例,您不会用自己的算法打败他们。