内存映射文件性能 - 使用大型数据集时的内存管理

时间:2010-10-29 14:43:05

标签: c++ memory-management

我遇到的情况是我需要使用大量(15-30)的大型(几百mb)数据结构。它们不会同时适合所有内存。更糟糕的是,在它们上运行的算法适用于所有这些结构,即不是第一个,而是另一个。我需要尽快做到这一点。

所以我想我会在磁盘上分配内存,这些文件基本上是数据加载到内存时的直接二进制表示,并使用内存映射文件来访问数据。我使用例如50兆字节的mmap'views'(每次将50 MB的文件加载到内存中),所以当我有15个数据集时,我的进程使用750 MB的内存来存储数据。最初(测试)是可以的,当我有更多的数据时,我会以一定的速度调低50 mb。

然而,这个启发式现在是硬编码的(我知道我将测试的数据集的大小)。 “在野外”,我的软件需要能够确定要分配的“正确”内存量以最大限度地提高性能。我可以说'我将使用500 mb的内存使用',然后将500除以数据结构的数量,以达到mmap视图大小。我发现当尝试将此“目标内存使用率”设置得太高时,虚拟内存管理器磁盘抖动将(几乎)锁定计算机并使其无法使用,直到处理完成。在我的“生产”解决方案中应该避免这种情况。

所以我的问题,解决问题的方法有所不同:

  • 单个流程的“最佳”目标大小是多少?我是否应该尝试最大化我拥有的2GB(假设32位Win XP及以上,非/ 3GB现在)或尝试保持我的进程大小更小,以便我的软件不会占用机器?当我在我的机器上打开2个Visual Studio,Outlook和Firefox时,它们可以轻松地使用1/2 gb的虚拟内存 - 如果我让我的软件使用2 GB的虚拟内存,则交换会严重降低机器速度。但那么我如何确定'最佳'流程大小。

  • 在处理内存映射文件时,我该怎么做才能保持机器的性能?我的应用程序对数据执行相当简单的数值运算,这基本上意味着它可以快速地切换数百兆字节的数据,导致整个内存映射文件(几千兆字节)被加载到内存中并再次快速换出,再次(想想蒙特卡洛风格模拟)。

  • 是否有可能不使用内存映射文件,只使用fseek / fgets比使用内存映射文件更快或更少侵入?

  • 我能读到的任何文章,论文或书籍?无论是“烹饪书”式解决方案还是基本概念。

感谢。

5 个答案:

答案 0 :(得分:1)

我觉得你可以为“太慢”设置一些预定义的阈值,并使用计算机的挂钟动态进行修改。

保守低开始。如果这低于“太慢”的阈值,请将下一个文件的大小稍微提高一点。迭代地这样做。当你超过阈值时,慢慢地反复缩小尺寸。

答案 1 :(得分:1)

我认为这是尝试Address Windowing Extensions的好地方:http://msdn.microsoft.com/en-us/library/aa366527(v=VS.85).aspx

通过提供滑动窗口,可以使用超过4GB的内存。缺点是并非所有版本的Windows都有它。

答案 2 :(得分:1)

我可能不会为此应用使用内存映射文件。当您拥有大的虚拟地址空间(至少相对于您正在处理的数据的大小)时,内存映射文件最有效。您映射整个文件,让操作系统决定哪些部分仍然驻留。

但是,如果您反复映射和取消映射文件的片段(而不是整个文件),您可能最终也会通过fseekfread阅读块来做同样的事情。 - 但请注意,希望以这种方式读取单个数据(即,执行一次大读取而不是大量小读取)。

手动分段内存映射文件可能获胜的一种方法是,如果您有稀疏读取:如果您只是触摸,比如说给定文件的10%。在这种情况下,内存映射意味着操作系统将只读取那些被触摸的页面,而显式读取将加载整个文件。

哦,我肯定花时间试图控制我的资源消耗。操作系统会比你做得更好,因为它知道所有竞争过程。

答案 3 :(得分:0)

最好将内存映射文件的大小修改为总系统内存的一定百分比,可能设置为最小值。

请记住,当您访问单个字节时,操作系统将有效地加载整个内存页面,这可能在后台发生,但只有在顺序数据访问往往靠近时才会很快。

因此,您应该尽可能地将数据的顺序访问保持在内存/文件中。在实际需要数据之前,您还可以查看预加载策略以推测方式访问数据。这些与优化内存缓存效率时需要的注意事项相同。

如果顺序数据访问广泛分散在您的文件中,您可能最好使用fseek和fread来访问数据,因为这样可以更好地精细控制何时将数据写入内存。

还要记住,没有严格的规则。优化有时可能是违反直觉的,因此请尝试一系列不同的事情,看看哪些在平台上最适合这些操作。

答案 4 :(得分:0)

也许您可以将 /LARGEADDRESSAWARE 用于 Visual Studio 的链接器,并为您的进程使用 bcdedit 以使用大于 2GB 的内存。