【问题标题】:IO from a mapped file vs IO using filestreams来自映射文件的 IO 与使用文件流的 IO
【发布时间】:2016-02-25 16:55:39
【问题描述】:

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

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

以下是我的疑问:

  1. 对文件 IO 使用内存映射文件(我计划使用 boost::file_mapping 并且我正在使用 Windows)与使用文件流有何不同?
  2. 与使用文件流(在 7200 rpm 的传统硬盘上)相比,内存映射文件的数据读取/写入速度可以提高多少?
  3. 内存映射文件是处理如此大量数据的唯一方法吗?有没有更好的方法(考虑到我的用例)?

【问题讨论】:

标签: c++ boost file-mapping


【解决方案1】:

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

使用内存映射文件有何不同(我打算使用 boost::file_mapping 和我在 windows 上工作)的文件 IO 比 使用文件流?

大大简化的答案:

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

更准确的答案:

内存映射文件让您可以直接访问内核页面缓存以进行文件 i/o。您可以准确地看到内核为某些打开的文件缓存了什么。读取和写入直接到内核页面缓存 - 缓冲 i/o 的速度不会更快。

我期望数据读取/写入的速度有多快 与使用文件相比,在内存映射文件的情况下 流(在传统硬盘 7200 rpm 上)?

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

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

最有效的方法总是 O_DIRECT/FILE_FLAG_NO_BUFFERING 并附带所有的陷阱,但很少有人会编写比操作系统更好的缓存算法。毕竟,他们花了几十年的时间来调整他们的算法。

是内存映射文件 处理如此大量数据的唯一方法?有没有更好的 这样做的方法(考虑我的用例)?

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

【讨论】:

    【解决方案2】:
    • 文件的内容永远不会出现在交换文件中
    • 一旦文件被映射,就不需要系统调用了
    • 系统会优化内存使用率
    • 如果写入内存映射文件并且您的进程崩溃,文件的内容将与内存的内容相匹配,而无需执行最终(写入/刷新)系统调用
    • 多个进程(在同一台机器上)可以看到同一个文件的内容并立即传播更改(读取器/写入器)。并且文件的内容不会最终出现在每个读取器/写入器的交换文件中。
    • 多个进程将共享同一个 RAM 用于映射同一个文件

    【讨论】:

      【解决方案3】:

      使用内存映射文件(我计划使用 boost::file_mapping 并且我正在使用 Windows)进行文件 IO 与使用文件流有何不同?

      这是非常不同的。使用内存映射文件时,您只需访问该文件,因为它是内存。没有显式加载或保存文件。

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

      与使用文件流(在 7200 rpm 的传统硬盘上)相比,内存映射文件的数据读取/写入速度可以预期多高?

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

      内存映射文件是处理如此大量数据的唯一方法吗?有没有更好的方法(考虑到我的用例)?

      这取决于你的实际情况。

      【讨论】:

      • 如果我没有使用内存映射文件,而是使用传统的文件IO,除了可以像写入内存一样读写的优势(在后端仍然需要更新文件通过调用刷新)内存映射文件有什么好处?
      • @Arun 它主要提供的好处是您将学习如何使用它以及它提供的好处......答案非常具有描述性并且通常是正确的。您只需要自己尝试描述结果。
      • @sehe :我实际上已经尝试过使用它,与读取/写入文件相比,它似乎确实提供了一些性能优势,但不是很重要(2 X)。我发布这个问题是为了了解我期望看到的性能提升......也许是 10 倍 :-)
      【解决方案4】:

      1

      基本上,内存映射文件只是从硬盘移动到内存的一个块。因此,它只是复制您创建的任何大小的块,然后与您的硬盘运行速度相比,操作该块的速度与您的内存可以运行的速度一样快。

      2

      正如我所说,你的内存速度和硬盘速度之间的差异基本上是。

      3

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

      【讨论】:

      • 并不是那么简单...内存映射文件仍然需要由磁盘上的文件支持...并且写入其中的数据(就像它是内存一样)仍然需要刷新到有磁盘写入开销的磁盘上,不等于写入内存
      猜你喜欢
      • 2013-02-09
      • 1970-01-01
      • 2011-04-22
      • 1970-01-01
      • 2015-08-15
      • 1970-01-01
      • 1970-01-01
      • 2015-07-09
      • 1970-01-01
      相关资源
      最近更新 更多