c – 进程外内存堆以解决32位地址空间问题

问题:大型模拟游戏具有大量不同的对象,必须对其进行跟踪,更新,并用于视觉渲染和逻辑模型更新.只有4 GB的地址空间,您只能将很多东西放入内存中.如果你诉诸磁盘,事情开始变慢,除非你很幸运,并且经常点击页面缓存.但即使这样,当文件系统同步到磁盘时,进行大量更新/写入也会很昂贵.

让我们假设用户至少拥有32GB的RAM(少数已经报告了64个),并希望进行大量的模拟,使得模型比大多数游戏开发的数据要多一个数量级.它们当然有64位操作系统(比方说,Windows 7 x64或Windows 8 x64).当然,如果您只是将所有这些模型数据存储在进程中的虚拟地址空间中,即使使用大地址识别,您也会遇到内存不足的情况,即使主机具有千兆字节和千兆字节的可用RAM(因为32位进程超出虚拟地址空间(VAS).

我们还假设,由于完全不受您控制的原因,您无法使主二进制64位.你依赖于一些专有的框架,花费了大量的时间编码到那个框架,并且必须从一个方块重新开始转移到其他东西.您的框架只提供32位版本,因此您遇到困难.

对?

也许.

我有一个随意的想法,这似乎是一个长镜头,因为我不知道我是否可以使它高效或实用.

如果我可以创建一个64位子进程,它可以用于所有实际目的,就像现在任何人都可以购买和插入主板一样多的RAM,即使在非常高端的服务器机箱上也是如此.

现在,我希望能够有效地存储和检索已被推入子进程的模型中的大块数据,并且不时将该数据的子部分复制到子进程中.所以基本上,所有千兆字节荣耀的“主要”模型(一系列非常巨大的树形和哈希表结构)将位于64位进程中,32位进程将在那里窥视,抓住一个大量的数据,做它的东西(或者我应该要求子进程在那里做一些处理以提取它?),然后摆脱它 – 以保持32位进程中的内存使用可管理.

所有模型读取/变异/模拟算法都基于模型在进程中本地可用的假设,因此随机数组访问等常见.我很难将我的访问模式提取到主模型中的一些基于块的顺序读取,并且整个模型的步行也不是非常罕见.

我的目标是:

>保持因内存不足而导致的崩溃事件(#1目标)
>性能(非常接近#2,但使用极端复杂程度的人可能会比模拟更小,更简单的游戏的人接受更差的性能)
>对现有代码的最小重构(或多或少带有渲染调用和多线程的vanilla C)

这似乎是一个非常重要的项目甚至承担,因为从一个连贯的内存模型到必须基本上通过一个比我在任何时候都能抓到的更大模型的光圈看起来可能需要大量的算法重新设计.

我的问题:

>这样做有先例吗?
>如何在Windows上做到最好?是否存在某种类型的共享内存,如Linux,或轻量级的高带宽随机内存访问IPC,可以通过类似operator []()实现的方式集成到C中?
>任何IPC的性能是否都会如此糟糕,甚至不值得尝试?我应该只依赖磁盘(你知道,数据库或键值或其他)并让操作系统/文件系统弄清楚如何使用RAM?

请记住,我需要支持极其“讨厌”的IPC机制,因为许多处理算法(AI等)是围绕小内存访问和更新而设计的.这在进程中运行良好,甚至对缓存局部性有一些关注,但是当你通过IPC访问它时,所有这些都变得奇怪.

最佳答案 我遇到了类似的情况,GUI是32位但需要x64代码才能与系统连接.我们采用的方法是使用WM_COPYDATA并在魔法进程位边界上来回传递数据.当然,它没有使用dll那么快,但这不是一个选择.对于我们的用例,性能权衡是可以接受的.

点赞