10

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

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

以下是我的疑问:

  1. 使用内存映射文件(我计划使用 boost::file_mapping 并且我正在使用 Windows)进行文件 IO 与使用文件流有何不同?
  2. 与使用文件流(在传统硬盘 7200 rpm 上)相比,在内存映射文件的情况下,我期望数据读取/写入速度能快多少?
  3. 内存映射文件是处理如此大量数据的唯一方法吗?有没有更好的方法来做到这一点(考虑到我的用例)?
4

4 回答 4

8

(免责声明:我是提议的 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 以及所有附带的问题,但是您很少会编写比操作系统更好的缓存算法。毕竟,他们花了几十年的时间来调整他们的算法。

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

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

于 2015-11-24T14:06:34.277 回答
3
  • 文件的内容永远不会出现在交换文件中
  • 一旦文件被映射,就不需要系统调用
  • 系统将优化RAM的使用
  • 在写入内存映射文件并且您的进程崩溃的情况下,文件的内容将匹配内存的内容,而无需执行最终(写入/刷新)系统调用
  • 多个进程(在同一台机器上)可以看到同一个文件的内容并立即传播更改(读取器/写入器)。并且文件的内容不会最终出现在每个读取器/写入器的交换文件中。
  • 多个进程将共享相同的 RAM 用于同一文件的映射
于 2015-11-23T21:55:49.160 回答
2

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

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

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

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

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

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

这取决于你的实际情况。

于 2015-11-23T14:52:51.883 回答
-1

1

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

2

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

3

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

于 2015-11-23T14:45:52.997 回答