我目前正在编写一个能够处理核心数据的程序。所以我处理的文件大小从 1MB 到 50GB(将来可能更大)。
我已经阅读了一些关于内存映射文件的教程,现在正在使用内存映射文件来管理数据 IO,即从/向硬盘驱动器读取和写入数据。
现在我还处理数据,需要一些与数据大小相同的临时数组。我现在的问题是,我是否也应该为此使用内存映射文件,或者我是否应该在不明确定义内存映射文件的情况下以某种方式让它由操作系统管理。问题如下:
我在多个平台上工作,但总是使用 64 位系统。理论上,64 位虚拟地址空间绝对足以满足我的需要。但是,在 Windows 中,最大虚拟地址空间似乎受到操作系统的限制,即用户可以设置是否允许分页以及允许的最大虚拟内存大小。我还在某处读到,Windows 64 中的最大虚拟内存不是 2^64,而是 2^40 或类似的某个地方,这对我来说仍然足够,但似乎是一个非常奇怪的限制。此外,Windows 有一些奇怪的限制,例如最大大小为 2^31 个元素的数组,与数组类型无关。我不知道这一切是如何在 linux 上处理的,但我认为它的处理方式相似。可能允许的最大虚拟内存=OS-RAM+Swap 分区大小?因此,如果我想使用系统来处理超过内存大小的数据,有很多事情需要解决。我什至不知道我是否可以在 c++ 中以某种方式使用整个 64 位虚拟地址空间。在我的简短测试中,我得到一个编译器错误,无法初始化 mot 超过 2^31 个元素,但我认为,使用 std::vector 等很容易超越这一点。
但是,另一方面,通过使用内存映射文件,它将始终是使用我所有的内存写入操作写入硬盘的数据。特别是对于比我的物理 RAM 小的数据,这应该是一个相当大的瓶颈。还是因为超出了RAM而避免写入直到必须写入?内存映射文件的优势出现在与共享内存或临时通信的进程间通信中,例如我启动应用程序,写一些东西,退出应用程序然后重新启动它,并且只有效地将那些数据读取到我需要的 RAM 中。由于我需要处理整个数据,并且只需要在一个执行实例中使用一个进程,因此在我的情况下这两个优点都没有出现。
注意:作为我的问题的替代解决方案的流式方法实际上并不可行,因为我严重依赖对数据的随机访问。
我理想地想要的是一种方法,我可以独立于它们的大小和操作限制设置限制来处理所有模型,但处理 RAM 中所有可能的情况,并且只有在超出物理限制时,才使用内存映射文件或其他机制(如果还有其他)用于分页超出数据的 RAM,最好由操作系统管理。
最后,处理这些临时现有数据的最佳方法是什么?如果我可以在没有内存映射文件和平台独立的情况下做到这一点,你能给我任何代码片段或类似的东西,并解释它是如何避免这些操作系统限制的吗?