当内存映射BIG文件时,我应该警惕哪些陷阱?

时间:2011-05-24 12:51:42

标签: performance memory operating-system mapping

我有一堆大文件,每个文件可以超过100GB,数据总量可以是1TB,它们都是只读文件(只是随机读取)。

我的程序在具有大约8GB主内存的计算机上对这些文件进行小读取。

为了提高性能(没有seek()和没有缓冲区复制)我考虑使用内存映射,基本上对整个1TB数据进行内存映射。

虽然起初听起来很疯狂,但作为主要内存<<磁盘,了解虚拟内存的工作原理,您应该看到在64位计算机上应该没有问题。

从磁盘读取以回答我的read()的所有页面都将被视为“干净”,因为这些页面永远不会被覆盖。这意味着所有这些页面都可以直接进入操作系统可以使用的页面列表,而无需写回磁盘或交换(清洗它们)。这意味着操作系统实际上只能在物理内存中存储LRU页面,并且当页面不在主存储器中时,它将只读取()。

这意味着由于巨大的内存映射,没有交换,也没有增加i / o。

这是理论;我正在寻找的是你们中的任何一个曾经尝试或使用这种方法进行实际生产的人,并且可以分享他的经验:这个策略有任何实际问题吗?

1 个答案:

答案 0 :(得分:3)

你所描述的是正确的。使用64位操作系统,您可以将1TB的地址空间映射到文件,并让操作系统管理读取和写入文件。

您没有提到您所使用的CPU架构,但大多数(包括amd64)CPU在每个页表条目中都保留了一点是否已写入页面中的数据。操作系统确实可以使用该标志来避免将尚未修改的页面写回磁盘。

由于映射很大,IO不会增加。您实际访问的数据量将决定这一点。大多数操作系统(包括Linux和Windows)都具有统一的页面缓存模型,其中缓存的块使用与内存映射页面相同的内存物理页面。我不希望操作系统使用内存映射的内存多于缓存IO。您只是直接访问缓存页面。

您可能遇到的一个问题是将已修改的数据刷新到磁盘。我不确定您的操作系统上的策略是什么,但是修改页面和操作系统实际将数据写入磁盘的时间可能比您预期的要长很多。如果在一定时间内写入数据很重要,请使用flush API强制将数据写入磁盘。

我过去没有使用那么大的文件映射,但我希望它能很好地工作,至少值得一试。

相关问题