c++ - 进程外内存堆可在32位地址空间内工作

标签 c++ winapi ipc out-of-memory

问题:大型模拟游戏中有许多荒谬的不同对象,必须对其进行跟踪,更新并用于视觉渲染和逻辑模型更新。仅4 GB的地址空间,您就只能在内存中容纳这么多东西。如果您求助于磁盘,除非运气好并且不断访问页面缓存,否则事情会开始放慢速度。但是即使那样,当文件系统同步到磁盘时,进行大量更新/写入也将是昂贵的。

假设用户至少有32GB的RAM(少数报告有64GB),并且希望进行巨大的模拟,从而导致该模型所承载的数据量比游戏中要处理的大多数事物都要多一个数量级。它们当然具有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代码才能与系统接口(interface)。我们采用的方法是使用 WM_COPYDATA 并在魔术过程位边界之间来回传递数据。自然,它不如使用dll快,但这不是一种选择。在我们的用例中,性能折衷是可以接受的。

    关于c++ - 进程外内存堆可在32位地址空间内工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16028361/

    相关文章:

    c - 消息队列中的 msgtype 成员

    C++:读取.txt内容并存储到二维数组中

    c++ - C++ 跨平台编程

    c++ - Qt Creator 链接错误 : undefined reference to `KFUNC'

    c++ - 在 Visual Studio 中将输出锁定到输出窗口

    c++ - 如何在 ISAPI 过滤器中设置多个 cookie

    c# - 命名管道 C# 客户端无法连接到 C++ 服务器

    c - 为什么时间在 IPC 的代码中打印相同

    c++ - 结构编译错误 - 取消引用指向不完整类型的指针

    c++ - 将 ULARGE_INTEGER QuadPart 转换为毫秒