【问题标题】:What pitfalls should I be wary of when memory mapping BIG files?内存映射 BIG 文件时应该注意哪些陷阱?
【发布时间】:2011-08-31 22:17:04
【问题描述】:

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

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

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

虽然一开始听起来很疯狂,但作为主内存

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

这意味着没有交换,也没有增加 i/o,因为内存映射很大。

这是理论;我正在寻找的是任何在实际生产中尝试或使用过这种方法并能分享他的经验的人:这种策略有什么实际问题吗?

【问题讨论】:

  • 只要确保(如果读取确实是均匀随机的)禁用操作系统预取机制...

标签: performance memory operating-system mapping


【解决方案1】:

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

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

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

您可能会担心将修改后的数据刷新到磁盘。我不确定您的操作系统上的具体政策是什么,但是从修改页面到操作系统实际将该数据写入磁盘之间的时间可能比您预期的要长得多。如果在特定时间之前写入数据很重要,请使用刷新 API 强制将数据写入磁盘。

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

【讨论】:

    猜你喜欢
    • 2010-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-03
    • 2017-06-06
    • 1970-01-01
    • 1970-01-01
    • 2011-12-11
    相关资源
    最近更新 更多