脏位跟踪
本文介绍从 Windows 11 版本 24H2 (WDDM 3.2) 开始支持的脏位跟踪功能。 支持 GPU 并行化设备上的实时迁移的驱动程序还必须支持脏位跟踪。
介绍
随着云方案中的 GPU 越来越受欢迎,越来越需要确保将虚拟机从一个物理主机迁移到另一个物理主机保持合理的性能。 这不仅仅是为了减少用户的影响,也是为了避免在迁移 VM 时出现 TCP 请求超时等问题。
在物理主机之间传输内存内容是在两次总体传递中完成的:
部分中断:在部分中断期间,虚拟机仍在运行,但系统会执行任何脏数据的迭代保存。 目标是,每次迭代期间脏化的数据量会变少,直到它聚合到可以快速复制的较小数据子集。 此数据量会因计算机的工作负荷而异,不保证聚合到任何特定大小。
完全中断:在完全中断期间,虚拟机将被暂停,并且会复制所有剩余脏数据。 此复制可确保目标计算机上生成的数据与源处于相同状态。
如果没有脏位跟踪,系统必须在完全中断期间依赖 GPU 帧缓冲区 (VRAM) 的单个完整复制。 为了支持部分中断传递,硬件必须能够主动跟踪脏内存页并将其报告回 OS,以便 OS 仅知道要复制的内存。
详细设计
报告功能
在适配器初始化期间,Dxgkrnl 会查询驱动程序,询问硬件使用的脏位平面的格式;即每个位所表示的页面大小(或数据量)。
启动和停止脏捕获
如果跟踪脏信息对硬件的性能具有很高的成本,那么在部分中断期间仅启用脏跟踪是有意义的。 在此期间,将迁移成本降到最低比跟踪的潜在性能影响更重要。
但是,如果对性能没有任何影响或根本没有影响,始终启用此行为有好处。 某些用户可能不会在其 VM 上执行繁重的 GPU 工作负荷,因此内存可能不会一开始就严重脏化。 通过在启动时启用脏位跟踪,则部分中断的第一次迭代可以立即使用脏数据,而无需完整复制帧缓冲区。 如果用户脏内存量很少(例如,用户主要执行 CPU 工作负荷),则迁移成本节省量可能会很明显。
查询脏位
脏信息表示为脏页的位平面。 位平面中的每个位都表示内存的一“页”。 脏数据的页面大小不需要与 GPU 上虚拟寻址的自然页面大小对齐(例如 4KB/64KB)。 它可以是最适合特定硬件的任何内容。 驱动程序会在初始化期间报告此页面大小。
在部分中断期间,Dxgkrnl 会在每次迭代之间查询硬件来获取脏数据。 此时,驱动程序必须能够以原子方式查询和重置位平面数据。 也就是说,硬件必须能够在单个原子操作中查询值并将其重置为零,以防止脏信息中发生数据丢失。
虚拟机不一定全部迁移到同一目标,因此每个虚拟 GPU 实例都会迁移帧缓冲区。 因此,驱动程序必须能够查询表示该特定虚拟 GPU 实例的总体帧缓冲区的指定子范围的位平面信息。 例如,8-GB GPU 拆分四种方法必须能够单独查询和重置每个 2-GB VRAM 范围的位平面位,而不会影响其他脏位数据。
DDI 更改
功能
以下上限已添加到 DXGK_QUERYADAPTERINFOTYPE。
DXGKQAITYPE_DIRTYBITTRACKINGCAPS
系统现在会调用 KMD 的 DxgkDdiQueryAdapterInfo 函数,并在适配器初始化期间使用 DXGKQAITYPE_DIRTYBITTRACKINGCAPS 的 DXGK_QUERYADAPTERINFOTYPE 来确定用于脏位跟踪的驱动程序和硬件功能。
KMD 应填写 pOutputData 指向的提供的 DXGK_DIRTY_BIT_TRACKING_CAPS 结构。
DXGKQAITYPE_DIRTYBITTRACKINGSEGMENTCAPS
如果 KMD 将 DirtyBitTrackingSupported 设置为 TRUE,则系统将调用 KMD 的 DxgkDdiQueryAdapterInfo 函数,并针对系统上的每个内存段使用 DXGKQAITYPE_DIRTYBITTRACKINGSEGMENTCAPS 的 DXGK_QUERYADAPTERINFOTYPE,查询有关脏位跟踪支持的信息。
KMD 应填写 pOutputData 指向的提供的 DXGK_DIRTY_BIT_TRACKING_SEGMENT_CAPS 结构。
内存基础 DDI
跟踪 VRAM 上的修改操作适用于可能不连续支持的分配。 例如,实时迁移中的初始用途适用于虚拟函数的帧缓冲区保留的跟踪。 因此,在跟踪脏位时表示的物理地址由表示所操作分配的范围集合组成。
务必确保操作与相同的范围匹配。 在许多情况下,此匹配需要是接口的强制固定,以确保正确跟踪状态。 为了帮助使用 KMD 进行此跟踪,引入了以下接口: