为什么资产需要自定义内存管理?


10

几乎所有与游戏编程有关的资源,尤其是3D开放世界游戏,都在谈论您如何不断地在磁盘,系统内存和视频内存之间进行资产的卸载和重新加载。我可以在控制台上理解这一点,因为它们具有非常简单的内存管理方案,无法处理任何潜在的溢出。

但是,在PC上,情况就大不相同了。操作系统提供了用于系统内存的虚拟内存,图形驱动程序负责从CPU到GPU的来回交换。那么,为什么一次加载所有内容并仅处理预取并仅确保在交换所需资产时没有阻塞是为什么呢?


这并不是说所有的事情都是像那样天真地分配的malloc。一切都将保持连续并且与缓存保持一致。如果您不必担心手动分页和换页,那么提高内存访问的效率可以说很容易...


更新:

在对异步缓冲区传输进行了一些了解之后,我发现图形驱动程序可以自动分页内存的方式不是最理想的。CPU资源是否也是如此?即,是否最好始终手动管理何时在存在虚拟内存的情况下何时加载和卸载给定资源?


1
您假设资产内容存储在系统内存中。您的大部分资产数据将存储在GPU内存中,而内存则更为有限。
dadoo Games 2014年

通过阅读这里的答案我得到了OpenGL驱动程序也自动将所有缓冲区/纹理保留在CPU上的想法。但是,我明白了为什么手动指定这些传输以利用异步上传可能会有用。
jmegaffin 2014年

您确定这与您的游戏项目有关吗?我不确定我看到的是技术挑战,只有解决方案。如果您没有面临技术挑战,则很难定制解决方案或理解解决方案。
AturSams 2014年

我想知道为什么当操作系统/驱动程序已经具有虚拟内存系统时,游戏引擎会实现复杂的资产缓存系统。这与我有关,因为我正在编写一个开放世界的游戏,该信息非常重要。
jmegaffin 2014年

您的游戏是否遇到性能问题,并且性能分析工具显示它是由于内存访问引起的?包含开放关卡的游戏的问题在于,从技术上讲,这会转化为大量数据。您对数据的控制越多,性能就会越好。为什么不实施最有效的系统来管理数据?游戏开发的竞争非常激烈,如果您有足够的钱来聘请专家,您将一筹莫展,寻求更多细节和更高的fps。
AturSams 2014年

Answers:


16

现代开放世界游戏根本不适合记忆。请记住,由于具有32位操作系统的游戏玩家数量众多,大多数游戏仍为32位,并且32位进程一次最多只能具有4GB的寻址内存(与虚拟内存无关),但实际上是限制为2-3 GB。碎片化以及一次可以在内存中拥有的可用对象的实际数量要比大型环境所需的总数据小很多。即使在64位OS上,您通常也需要针对仅具有4GB内存的低规格计算机,以确保最大程度的最终用户兼容性。让我们不要忘记移动设备,WiiU等“动力不足”的硬件等。开发人员的目标不只是大型花式游戏PC设备。

虚拟内存不是解决方案,首先是因为它没有消除地址空间限制,而且还因为它不是最佳的。操作系统可以在不适当的时间或以不适当的方式将内容分页。当休眠第一次出现时,这是操作系统要解决的一个问题。在某些情况下,将进程分页到磁盘,然后再分页回去,这比让应用程序显式地将资源流回原点要慢得多。当系统内存不足时,您仍然可以看到今天的问题,页面分页到磁盘,并且系统变得无响应成为运行WM / explorer.exe的必要关键。虚拟内存是几十年前针对一个问题而设计的解决方案,当时系统的RAM很小,内存和磁盘速度之间的差距要小得多。即使在今天' 最快的SSD只是廉价/慢速RAM速度的一小部分,并且试图假装可以将磁盘用作虚拟RAM不再是最好的主意。在这个时代,有些人反其道而行,并将文件系统加载到RAM磁盘中。导致创建虚拟内存的约束不再成立。

除磁盘问题外,自定义资源管理仍是游戏开发的重要组成部分。从调试钩子到碎片问题再到复杂资源的智能流传输,仅仅假装整个世界是一个无限大的盒子是不现实的。


感谢您的详细回答。尽管我仍在寻找有关GPU驱动程序处理虚拟内存(在VRAM和系统RAM之间)的方式的信息。
jmegaffin 2014年

@Boreal:同样的问题。只需将“ RAM”替换为“ VRAM”,将“磁盘”替换为“ CPU内存
Sean Middleditch 2014年

@SeanMiddleditch +1不错的答案:“这个时代有些人做相反的事情,并将文件系统加载到RAM磁盘中”,您的意思是内存映射文件吗?我也从您的答案中了解到,自定义内存分配器阻止操作系统分页出内存,不是这种情况,因为只要您使用brk()向内核询问内存,内存就会被分页。使用自定义内存分配器可完全防止在PC上进行分页?
concept3d 2014年

1
@ concept3d:不是内存映射,而是文字RAM磁盘。您可以使驱动器由内存而不是磁盘支持。自定义内存管理器不会阻止分页(某些其他应用程序可能会耗尽所有内存)。智能地管理资源(在对象/资源管理层),仅意味着您为不再需要的对象释放了内存。想一想操作系统的磁盘缓存将其保留在内存中
Sean Middleditch

6

对于32位游戏,由于大​​多数游戏出于多种原因,即使是单面DVD(4.3GB)上的游戏也已经具有更多内容,可以装入32位地址空间。并假设内容没有在磁盘上压缩,并且是最佳选择,可以将所有内容立即加载到连续的地址空间方法中。现在,许多游戏都带有多张DVD,轻松超过10GB的内容。根据我在PC上的经验,一旦您的地址空间接近2GB,分配将开始失败,并且无论用户拥有多少物理内存,这都会成为一个硬限制。

如果您确实跳到了64位,并且假设您的引擎支持,那么硬限制就会消失,而只能由有效的软限制代替-虚拟内存交换一旦开始发生,游戏的性能就会下降不能接受。如果主进程不得不等待内存被换回页面,则帧速率将变得不稳定。虚拟内存可能会使它变得透明,但并不能提高其性能。从磁盘取回内存实际上需要时间,而在等待期间,游戏已停止。尽管可以解决(通过后台预取您不久将需要的内存页面),但这是一个困难且不可靠的过程,并且仍然会影响性能。

操作系统用于确定将哪些页面换出到磁盘的算法不了解您的游戏以及下一步可能需要做什么。此外,操作系统仍然必须支持与您的游戏同时运行的其他应用程序,以及操作系统本身。从磁盘返回页面时必须停顿,这会严重影响性能,无论是您的游戏,其他应用程序还是引起该问题的操作系统都无济于事,游戏的性能将受到严重影响。

因此,无论内存限制是软限制还是硬限制,内存仍然受到限制。但是,即使您可以立即加载所有内容而不影响性能,仍然有您不愿意这样做的原因:

  1. 您的游戏加载并进入交互状态所需的时间远远超过了所需的时间,因为它只是在开始时就加载了所有内容并保持其驻留状态。您可以从硬盘上加载大约150MB /秒,甚至最快的DVD驱动器(24x)也可以以33MB /秒的速度加载。这意味着示例4.3GB DVD内容的内容从HDD加载至少需要30秒,从DVD加载至少需要133秒。这是不可接受的长加载时间。

  2. 您的游戏占用的内存比合理的要多得多。如果在任何一次仅可见10%的内容,那么保留其余居民就很浪费,并且会阻止用户将内存用于其他用途。用户通常不会原谅那些需要大量内存才能正常运行的游戏。

动态地从磁盘流式传输资产,无论是在后台还是在加载屏幕期间同步进行,都可以使您的内存使用效率大大提高,而工作量可忽略不计,对用户而言只有很小的缺点。但这是一种优化,与其他任何优化一样,您尝试使用它的次数越多,回报率就越低。在某些时候,保留某些内容所需要的内存占用空间增加了,而无需将其加载就可以得到好处。但是直到达到这一点,最好只在需要时加载所需的内容。


1

仅是非常笼统和简单地讲,并且在不考虑虚拟内存实现细节的情况下,开发人员在预见性方面始终了解VM实现缺少的知识。

开发人员总是可以说:“我现在不需要加载此音频文件。其中的音乐仅用于屏幕游戏。” 并且在游戏结束后,开发人员可以立即说:“我不再需要物理内存中的音频片段。它仅用于游戏结束时。”

操作系统没有这种预见性。以后可能会发现很多页面错误,因为已经有一段时间没有访问它了,因此物理内存中不再需要某些音频剪辑。但是,将远见变成事后预见会导致很多页面错误,而很多页面错误则会导致软件中的帧率降低,而视频游戏等时间至关重要。如果您想避免这种麻烦,开发人员的远见卓识确实会有所帮助。

这在概念上适用,与硬件和软件无关。假设内存中的页面调度很昂贵,那么开发人员的远见卓识将始终有助于减少这种开销。

概括地说,硬件设计人员,编译器设计人员,OS /驱动程序设计人员和应用程序开发人员之间存在一个永无止境的循环。硬件/编译器/ OS /驱动程序开发人员经常尝试根据其通常的内存访问模式来实现优化,以加快普通应用程序的运行速度,有时甚至希望“人们应该能够随心所欲地编写代码,应该很快。”但是,如果考虑到这种类型的情况,通常对于性能至关重要的字段都会失败,因为性能关键的开发人员开始学习其编译器,硬件,操作系统,驱动程序等的复杂细节,并开始专门编写代码设计用于尽可能多地编写最快的代码(例如预取,热/冷字段拆分,SoA等用于缓存友好的代码)。那就像一个永无止境的游戏。在开发人员争夺性能的情况下,这些事情在性能至关重要的领域从未被视为黑匣子。

我个人有点希望虚拟内存不存在,因为它以一种过于极端和招致的方式增加了性能不可预测性的另一层,当事情真的到了无法使用的地步时,就会对性能造成太大的影响。有时我遇到过这样的情况:使用某些应用程序时,我在喝醉到某个输入字段时无意中输入了额外的一两位数字,然后导致它以如此快的速度耗尽了物理内存,从而导致操作系统无法进行爬行。甚至无需再单击进度条上的“取消”按钮,就不得不等待10分钟,同时按下Ctrl + Alt + Del终止进程,然后对自己进行诅咒,同时又将我的饮料洒到了可以再次使用的地步。尽管页面文件存储在SSD中。在那种情况下,我宁愿选择“内存不足”错误或其他方法,此时我可能会关闭我的17个色情标签(没关系,无论如何我都收藏了我的收藏夹)以释放一些内存,然后立即处理恢复我的业务。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.