本文提供有关从 Windows 10 开始的 GPU 虚拟内存管理(WDDM 2.0)的详细信息。 它描述了 WDDM 2.0 为何更改为支持 GPU 虚拟寻址以及驱动程序如何使用它。
介绍
在 WDDM 2.0 之前,设备驱动程序接口(DDI)的设计使得 GPU 引擎要通过段物理地址来引用内存。 在应用程序之间共享段且资源过度分配时,资源在其生命周期内被重新定位,并且分配的物理地址发生了变化。 此过程需要在命令缓冲区内通过分配列表和修补位置列表跟踪内存引用。 然后,在提交到 GPU 引擎之前,需要用正确的物理内存引用修补这些缓冲区。 这种跟踪和修补成本高昂。 它基本上强加了一个计划模型,其中视频内存管理器(VidMm)必须检查每个数据包,然后才能将其提交到引擎。
随着时间的推移,更多的硬件供应商转向基于硬件的计划模型。 在此模型中,工作直接从用户模式提交到 GPU,而 GPU 自行管理各种工作队列。 这种演变使得有必要消除 VidMm 在提交到 GPU 引擎之前检查和修补每个命令缓冲区的需求。
为此,WDDM 支持从 WDDM 2.0 开始的 GPU 虚拟寻址。 在此模型中,每个进程都会分配一个唯一的 GPU 虚拟地址(GPUVA)空间,每个 GPU 上下文都可以在其中执行。 在进程的 GPU 虚拟地址空间中,由进程创建或打开的资源被分配一个独特的 GPUVA。 此分配的 GPUVA 在分配的生存期内保持不变且唯一。 因此,用户模式显示驱动程序(UMD)能够通过其 GPU 虚拟地址引用分配,而无需担心在整个生命周期内基础物理内存发生变化。
GPU 的各个引擎可以在物理模式或虚拟模式下运行:
在物理模式下,计划模型与 WDDM v1.x 相同。 UMD 继续生成分配和修补位置列表。 这些分配列表使用命令缓冲区提交,用于在提交到引擎之前将命令缓冲区修补到实际物理地址。
在虚拟模式下,引擎通过 GPU 虚拟地址引用内存。 UMD 直接从用户模式生成命令缓冲区,并使用新服务将这些命令提交到内核。 UMD 不会生成分配或修补位置列表,但它仍负责管理分配的宿主位置。 有关驱动程序驻留的详细信息,请参阅 WDDM 2.0 中的驱动程序驻留。
GPU 内存模型
WDDM v2 支持两个不同的 GPU 虚拟寻址模型, GpuMmu 和 IoMmu。 驱动程序必须选择“支持”任一模型或两种模型。 单个 GPU 节点可以同时支持这两种模式。
GpuMmu 模型
在 GpuMmu 模型中,VidMm 管理 GPU 内存管理单元和基础页表。 VidMm 还会向 UMD 公开服务,使得它可以管理 GPU 虚拟地址映射到分配。 GpuMmu 表示 GPU 使用 GPU 页表访问数据。 页表可能指向系统内存或本地设备内存。
有关详细信息,请参阅 GpuMmu 模型。
IoMmu 模型
在 IoMmu 模型中,CPU 和 GPU 共享公共地址空间和 CPU 页表。 在这种情况下,只能访问系统内存,因此 IoMmu 适用于集成 GPU。 IoMmu 提供了更简单的编程模型,GPU 和 CPU 可以使用同一指针来访问内存。 无需在 GPU 可访问的内存中管理一组单独的页表。 也就是说,IoMmu 模型可能会导致性能下降,因为地址转换和管理带来的额外开销。
有关详细信息,请参阅 IoMmu 模型。