【问题标题】:Can I (ab)use VirtualAlloc for every vector-like container in a game?我可以(ab)对游戏中的每个类似矢量的容器使用 VirtualAlloc 吗?
【发布时间】:2023-03-06 09:06:01
【问题描述】:

想象一下我正在制作一个游戏

  • 我知道它将在 64 位系统、64 位操作系统上运行
  • 游戏的内存预算是固定的2(或4)Gibibytes

这是否意味着在该进程的 64 位 Virtual Address Space 中,我可以随意使用 32 位?

我可以 - 例如 - 对于游戏中的每个容器(容器 = 类似于 std::vector)使用 VirtualAllocMEM_RESERVE 2 Gibibytes 内存吗?

随着新元素的添加,新的pages(大约 64K)会根据需要进行MEM_COMMITed。随着容器死亡,内存被相应地释放为VirtualFree

出于好奇:

  1. 技术上会起作用吗?

  2. 是否有任何性能原因不这样做?


编辑:澄清:如果游戏中有 10000 个容器,则 保留 2GiB * 10000 内存 - 但 提交 内存将小于 2(或 4)吉布。

这 10000 个容器也可以增加到 2^16 个容器(或者地址空间允许的任何数量)。

【问题讨论】:

  • 在否决或投票结束之前/之后发表评论将不胜感激。谢谢。
  • IIRC 当前处理器只为您提供 48 位地址空间(前 16 位必须为 0,如果您处于内核模式但不是,则为 1)
  • 此外,“玩的东西”的整个概念毫无意义。
  • @immibis, "bits to play around" - 就像你可以调用 VirtualAlloc 并询问一个特定的地址 - 在 64 位地址空间内 - reserved 内存将从那里开始。 (据我了解)。并不是说VirtualAlloc 保证符合请求(也许?)
  • 是的,这很好。几乎是 VirtualAlloc() 存在的原因。 HeapAlloc() 将直接调用 VirtualAlloc() 进行如此大的分配,不同之处在于它将提交整个分配。如果您发现现在需要编写自己的子分配器来分配内存块,那么您就失去了优势,HeapAlloc() 并没有那么糟糕。

标签: c++ c 64-bit virtual-address-space virtualalloc


【解决方案1】:

是的,它可以工作。

当我玩弄它时1,我发现它仍然最好将内存从相当大的内存块(例如,兆字节)开始提交给它,然后跟随尺寸的几何级数。调用VirtualAlloc(显然)需要切换到内核模式,因此如果可以提供帮助,您需要避免经常这样做。


1. 虽然那是很久以前的事了——Windows NT 4 或者可能是 Win2K 时间框架,所以从那以后事情可能已经改变了。

【讨论】:

  • 无论如何,malloc 最终不会最终调用VirtualAlloc(不是每个malloc 自然调用),所以VirtualAlloc 调用的数量大致相同?
  • 另外,您是否在每次VirtualAlloc 调用时保留(但不提交)大量内存?
  • @JBeurer 我认为他的观点是,如果您每次拨打VirtualAlloc 时都会拨打malloc,那么您拨打的VirtualAlloc 电话将比malloc 拨打的电话多。
  • @immibis,如果VirtualAlloc 也被调用以使用几何级数(而不是逐页)提交,那不可能是这样,不是吗?
猜你喜欢
  • 2011-02-23
  • 1970-01-01
  • 1970-01-01
  • 2019-02-10
  • 2019-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-24
相关资源
最近更新 更多