繁体   English   中英

为什么不在C ++游戏中经常分配和释放内存?

[英]Why not allocate and deallocate memory frequently in C++ games?

我最近转换为C ++用于游戏编程 - 我在处理C#中的内存管理和垃圾收集问题方面有很多经验,但对C ++没有那么多。

我过去听过一些模糊的建议,以避免游戏过程中的分配和解除分配(即newdelete ),并预先分配您可能需要的所有内容。 但是,这比在游戏运行时(敌人,粒子等)根据需要分配和释放游戏对象要繁琐且在架构上更复杂。

我认为我读到的建议是指资源受限的平台 - 我的目标是主要针对PC开发,我认为经常变化的游戏状态数据最多只能达到几兆字节。 其余的是我要预加载的纹理,声音资产等。

所以我的问题是:在拥有千兆字节内存的个人电脑世界中,为我的游戏状态数据设置精心设计的内存池,预分配等是否值得头疼? 或者这只是一些毫无疑问的“最佳实践”传统,在最大化有限的平台时发展,现在又作为福音重复了?

如果我的2 MB游戏数据变得支离破碎并且现在已经超过4MB,我无法想象在1990年之后在PC上做出的任何事情 - 但我很想知道我是否遗漏了一些东西:)。

除非在游戏环境中有必要,否则避免调用new主要原因是

  1. 内存的动态分配确实非常昂贵。
  2. 缓存未命中对性能有害。

动态分配

在我的工作中,我们开发了类似游戏的产品(虚拟手术),我们的大部分内存都是通过工厂或内存池预先分配和处理的。 这样做是因为动态分配内存需要很长时间。 系统必须在任何时候处理许多不同大小的内存请求。 这意味着需要进行大量工作,例如最大限度地减少碎片。 如果你问系统内存,你将不得不等待它做这些事情。 如果预先分配内存,则可以使用工厂或其他特定于块大小的内存管理器来缓解这些问题。

我可以从经验告诉你,一个简单的错误,比如每帧从头开始分配一个相当大的std::vector ,而不是重新使用预先分配的内存,可以将帧速率拖动到阴沟中。

缓存未命中

另一个相关问题是缓存一致性。 缓存未命中,迫使操作系统将新页面带入缓存,也非常昂贵。 如果经常发生这种情况,你将拥有一款无法玩的游戏。 但是,如果你预先分配大块内存,这对改进缓存局部性有很大帮助,这使得缓存错过了很少。

故事的道德启示

因此,简而言之:如果您不管理自己的预分配内存,则可能会因为等待系统分配内存或处理缓存未命中而导致大量计算时间丢失。

在具有千兆字节内存的PC世界中

如果在该PC上运行一个理智的操作系统,那么您的进程只需几兆字节。 (但这不是主要问题。)

为我的游戏状态数据设置精心设计的内存池,预分配等是值得的

我不敢说“总是预先分配所有东西”,因为有时它是不可能的,对于不太常用的对象,它可能不值得付出努力,但C和C ++中的动态内存管理肯定是资源 -密集而缓慢。 因此,如果您每秒向屏幕渲染30帧,则可能避免分配和解除分配,然后在每个帧/迭代期间为要渲染的对象重新分配缓冲区。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM