这篇文章介绍了 NVIDIA GPU s 上内存和资源的最佳实践。要在应用程序中获得高且一致的帧速率,请参阅所有高级 API 性能提示.
内存
DirectX 12 中的最佳内存管理对于高性能应用程序至关重要。为了在避免口吃的同时获得最佳表现,应遵循以下建议。
推荐
- 视频内存管理:
- 使用
IDXGIAdapter3:: QueryVideoMemoryInfo
可以获得有关可用视频内存的准确信息,因为前台应用程序不一定分配全部甚至高百分比的视频内存。 - 使用
IDXGIAdapter3::RegisterVideoMemoryBudgetChangeNotificationEvent
响应操作系统的预算更改。 - 使用
ID3D12Device1::SetResidencyPriority
向操作系统提供有关哪些堆应保留在内存中以及在视频内存有限时应首先降级哪些堆的信息。- 最高优先级应给予 GPU – 书面资源,如渲染目标、深度缓冲区和无人机。
- 使用
MakeResident
和Evict
保持在预算范围内- 根据需要删除平铺资源的
mip
级别。 - 在执行
vidmem
预算时,在执行命令列表之前或之后考虑使用MakeResident
或Evict
。 - 应用程序必须处理
MakeResident
失败的情况。
- 根据需要删除平铺资源的
- 批处理
MakeResident
调用,但页面表更新需要 CPU 和 GPU 成本。这降低了驱动器和 GPU 内部的开销。
- 使用
- 资源创建:
- 资源创建应在关键路径之外完成,并在需要分配之前完成
- 在应用程序运行时,将
CreateHeap
与CreatePlacedResource
和CreateReservedResource
一起使用,以最大限度地提高内存重用并减少内存分配调用的数量。 - 请注意,某些资源类型在堆中具有不同的对齐规则。
- 检查资源堆层功能,并设计方法来处理设备功能级别内的各种资源绑定。
- 以 2 MB 的粒度将任何更新与放置或平铺的资源对齐,以获得最佳性能。
- 内存别名:
- 为了在对资源进行别名处理时获得最佳性能,请将可在 GPU 硬件上压缩的资源组合在一起,而不是与无法压缩的资源组合在一起。反之亦然。
- 未压缩资源:
- 大小小于 512 × 512 像素的任何资源
- 所有块压缩资源
- 不符合压缩资源要求的所有其他纹理和无人机
- 压缩资源:
- 所有深度缓冲区
- 渲染大于 512 × 512 像素的目标
- 纹理和无人机大于 512 × 512
- 本机支持算术压缩的格式( 8-8-8-8 、 16-16 等)
- 64-KB 对齐缓冲区,开始时未压缩。
- 未压缩资源:
- 对于未压缩的资源,首选在堆上使用提交的资源。这消除了在与压缩资源对齐时跟踪这些资源的 CPU 成本。
- 如果这是不可能的,那么所有未压缩的纹理都应该有自己的堆,因为它们可以在它们之间进行别名
- 如果应用程序内存不足,则可以将堆拆分为未压缩段和压缩段,并将资源映射到适当的区域。
- 为了在对资源进行别名处理时获得最佳性能,请将可在 GPU 硬件上压缩的资源组合在一起,而不是与无法压缩的资源组合在一起。反之亦然。
- 保留或平铺资源:
- 将所有
UpdateTileMapping
调用移动到异步复制队列以隐藏操作系统调度和提交成本。 - 只要重新映射相同的分片,就不需要显式的
unmap
调用。 - 使用可在 GPU 硬件上压缩的资源;纹理、渲染目标和无人机。
- 以 2-MB 的粒度将更新与磁贴资源对齐,以实现最佳压缩。
- 将所有
不推荐
- 不要依赖平铺资源的可用性。检查盖位。
- 您仍然需要考虑不同的 DX12 硬件类。
- 不要依赖于能够一次性分配所有 GPU 内存。
- 不要指望打
Evict
电话会立即产生费用。成本 MIG 不能延迟,直到另一个MakeResident
调用使用内存。 - 不要使用创建和破坏资源的模式。
- 尽可能使用
MakeUnresident
和MakeResident
,因为这样可以节省创建和销毁资源的开销
- 尽可能使用
- 当
pHeap
为 NULL 或设置D3D12_TILE_RANGE_FLAG_NULL
时,避免通过updateTileMapping
进行显式取消映射调用。它强制驱动程序遍历所有映射并移除不再映射的分幅。相反,请切换到其他磁贴。
资源
应根据应用程序的要求和性能仔细考虑资源格式和类型的选择。这些建议不可能适用于所有应用程序,因为它们依赖于工作负载和限制。例如,对于很少使用的小型缓冲区,首选 D24 深度格式可能并不重要。但是,对于 8k 阴影贴图来说,这可能非常关键。以下建议应与使用 NVIDIA NSight 诊断性能问题和验证改进相结合。
推荐
- 使用 32 位颜色格式(
DXGI_FORMAT_R11G11B10_FLOAT
)而不是 64 位颜色格式(DXGI_FORMAT_R16G16B16A16_FLOAT
),以减少所需的带宽。 - 使用 D24 或 D16 深度格式可获得最佳性能。
- 在顶点数允许的情况下使用 16 位索引。
- 使用
CopyTextureRegion
时,复制深度模具纹理时要小心,因为仅复制资源的深度部分可能会遇到缓慢的路径。 - 常量缓冲区和结构缓冲区在现代 GPU 上的性能类似,但请注意,只有在统一访问缓冲区内容时,才应使用常量缓冲区
致谢
感谢帕特里克·尼尔、迪拉杰·库马尔、伊万·费多洛夫和朱哈·斯霍姆的建议和帮助