简介
与大多数计算应用程序不同——它们必须允许多个应用程序在其硬件上同时运行——游戏主机则尽力保证游戏对设备资源拥有独占访问权。虽然大多数主机的硬件规格低于高端游戏 PC,但这使得主机游戏可以针对目标平台进行显式优化,从而带来超越单看硬件规格所能预期的超高质量体验。 如今,玩家期望获得一些功能(尤其是社交和联机功能),而这些功能是有代价的,需要对资源独占的保证做出一定妥协,才能支持这些功能。这使得 XBOX 这样的服务和平台提供商可以在游戏之间以一致的方式实现这些功能。 Microsoft 游戏开发工具包 (GDK) 为游戏开发者提供了高性能、确定性、可预测的物理内存访问能力。虽然我们此前的 XBOX One ERA OS 内存管理器满足了游戏开发者的许多需求,但我们也收到了大量关于如何改进它的反馈。例如,从历史上看,游戏代码与平台服务之间的内存资源共享并不像它本可以做到的那样具有确定性。 我们重建了内存管理器以解决这些问题,同时保留了原本最成功的方面。 新的架构提供了游戏开发者所期望的、更加具体和确定的保证,同时保留了 XBOX One 游戏所依赖的性能优化和灵活性。架构示意图
下图展示了 Microsoft 游戏开发工具包 (GDK) 的内存架构。关键特性
- 与 XBOX One ERA 系统具有高度相似性,以便沿用现有的开发者知识和经验:
- 包括针对 64 KB/2 MB 页作为未初始化内存分配的优化
XMemAllocAPI 系列- 以 64 KB 粒度进行物理页分配和映射
- 游戏组件与非游戏(平台)组件之间的内存消耗硬隔离
- 在运行时跟踪标题分区空间中的所有内存消耗
- 所有 Win32 堆使用 2 MB 页以获得更好性能
[!NOTE]XMemAlloc和XMemFree默认实现的源代码作为 Microsoft 游戏开发工具包 (GDK) 的一部分进行安装。参见 \GXDK\gameKit\Source\amd64\heap.c。
概述
内存分区
Microsoft 游戏开发工具包 (GDK) 内存架构延续了为 XBOX One ERA OS 创建的“三池”模型。在该架构中,每个池都对特定类别的内存使用拥有明确的所有权。- 系统分区: 负责系统进程和平台分配以及平台可执行文件页
- 标题分区: 负责由游戏进程驱动的所有内存消耗以及游戏可执行文件页
- 工具分区: 一个可选的内存池,可用于将扩展/调试内存与零售内存隔离(仅在开发套件上可用)
- 通常在分配期间,Windows 内存管理器出于安全考虑会将内存页零填充。对于标题分区,此功能被禁用,将这部分性能还给你的游戏。
标题与系统内存分配的分离
Microsoft 游戏开发工具包 (GDK) 游戏 OS 通过内存分区来保证系统和游戏内存使用的隔离。所有进程在启动时都会被分配一个内存分区。由于所有系统进程都在系统内存分区内启动,因此这些进程不能从游戏所使用的标题分区中分配任何内存。而标题进程则使用标题分区,从该专用池获取其内存。 在标题进程启动时会对其应用一些定制,以实现标题与系统代码之间内存分配的隔离。这些定制包括:- 一个文件系统 mini-filter 驱动会监视每个文件映射,并将文件分类为系统文件(例如 kernelbase.dll)或游戏文件。系统文件被标记为对系统分区计费,而游戏文件则对标题分区计费。
- 在系统分区和标题分区中分别创建独立的 Win32 堆(标题堆在首次使用时创建),它们分别拥有系统代码与标题代码所做的堆分配。
- 通过每个模块导入地址表调用的与分配相关的 API 会在加载时被重定向到不同的实现,从而根据源 DLL 从系统或标题分区中提供内存分配。
计入标题的内存开销
标题分区仍然负责承担以下方面:- 游戏进程特有的代码和数据/内容的内存占用。
- 由游戏进程加载的模块中所有已修改的数据段(即写时复制段)。
- 线程栈空间。
- 游戏进程虚拟地址到物理地址转换所需的页表项。
- 用于创建传递给系统 API 调用的缓冲区所需的内存。
- 用于捕获系统 API 调用、异步操作和通知结果所需的内存。
- 使用某些功能所需的其他元数据。例如,堆需要用于跟踪分配的元数据,这些开销会由堆执行的所有分配计入标题分区。
监控内存使用与分配调用
Microsoft 游戏开发工具包 (GDK) 内存系统对运行时的内存使用监控与跟踪提供了广泛支持。XMEM_SET_ALLOCATION_HOOKS 宏可启用对通过 XMemAlloc 调用返回的内存的跟踪。此外,所有 Win32 堆分配都可以通过配置的跟踪回调进行监控(参见 XMemSetWin32HeapTrackingHooks),从而捕获任何 malloc/new/HeapAlloc 的使用。
最后,可以使用 XMemGetWorkingSetStatistics 和 XMemVirtualQuery API 提供物理内存和虚拟内存使用情况的详细快照。XMemVirtualQuery 与 VirtualQuery 非常相似,但会返回一些 VirtualQuery 无法提供的附加信息,包括内存的页大小和归属(系统或游戏)。
有关可用于运行时内存跟踪的 API 的更多信息,请参阅 将游戏移植到使用 Microsoft GDK 游戏 OS 内存管理器 中的“跟踪内存”一节。
分区大小
与之前版本相比,此版本的一项重要变化是主机被配置为提供与游戏在 零售消费者 环境中所面对的相同内存配置。 此外,还新增了对工具分区的支持。将游戏移植到使用 Microsoft GDK 游戏 OS 内存管理器 主题介绍了为提供确定性内存计费模型所做的更改。开发者现在可以获得一致的代码内存池,同时确保平台二进制文件与短暂分配从与标题可寻址内存空间分离的系统内存池中计费。Profiling 模式
Profiling 模式是一个可选项,它会将系统 OS 的部分资源转让给游戏,是 PIX 等工具全力工作所必需的。启用 Profiling 模式后,某些功能(例如 Hub Apps、Game DVR 和 Microsoft Edge)可能会出现体验下降或完全无法工作。可以使用 XBOX Manager、xbconfig.exe(Windows PC 上)、wdconfig.exe(主机上)或主机上的 Developer Home Shell 启用或禁用它,以恢复这些功能。 启用 Profiling 模式后,如有需要,还可以选择性地向标题池追加额外的扩展/调试内存。若要向标题空间添加更多内存,可使用:内存配置
下表描述了内存配置。上表中的工具内存仅在启用 Profiling 模式时可用。
