最大化利用 Smart Access Memory (SAM)

发布日期:
Oskar Homburg's avatar
Oskar Homburg

通过使用 Smart Access Memory (SAM) 提高 CPU 和 GPU 性能的指南

过去,CPU 对 GPU 内存的访问受到很大限制。只有驱动程序可以直接访问;应用程序必须使用特定的函数。通过显式 API,内存分配和使用得到了更严格的控制。

随着 Smart Access Memory (SAM) 的推出,CPU 现在可以 D 访问所有视频内存。在本文中,我们将提供使用此功能提高 CPU 和 GPU 性能的指南。

背景

在带有独立 GPU 的系统中,内存分布在两个位置:系统内存 (RAM),靠近 CPU;以及视频内存(也称为 GPU 内存、VRAM 或帧缓冲区),位于显卡上,针对 GPU 典型访问模式进行了优化。

显式 API 通常会暴露四种内存类型,如下表所示

标识符内存类型
D3D12_HEAP_TYPE_DEFAULTVK_MEMORY_PROPERTY_DEVICE_LOCAL_BITCPU 无法访问的视频内存。
D3D12_HEAP_TYPE_UPLOADVK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT系统内存,CPU 和 GPU 均可见。

CPU 不会缓存此内存,因此读取速度很慢,但使用写组合可以快速写入。GPU 可以通过 PCIe® 读取此内存。
D3D12_HEAP_TYPE_READBACKVK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BITCPU 缓存的系统内存。

CPU 访问速度很快,但 GPU 访问速度较慢,因为它必须嗅探 CPU 缓存。
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BITCPU 可通过 PCIe® D 访问的视频内存。

从 CPU 的角度来看,这类似于 UPLOAD 内存:它不被缓存且采用写组合。由于用于访问它的机制,它也被称为 BAR(基地址寄存器)。DirectX® 12 目前不直接公开此功能。

BAR 已存在很长时间,并被驱动程序用于各种目的。用于 Vulkan® 的 Radeon™ 驱动程序也将其暴露给应用程序使用。然而,直到最近,CPU 任何时候只能看到 256MiB 的地址空间。

使用 SAM 时,新硬件支持根据一种标准的 PCIe® 功能(通常称为 Resizable BAR 或 ReBAR)调整此内存段的大小,以覆盖整个帧缓冲区。有关 AMD 硬件上启用此功能的系统要求和步骤列表,请参阅 amd.com:系统要求和启用步骤

启用 SAM 后,Vulkan 应用程序不再仅限于小的地址空间,可以使用显著更多的本地可见内存。

对于 DirectX®12,Radeon 驱动程序可以在分配时应用一项优化,将 UPLOAD 堆中的某些资源放置在 BAR 中,而不是在分配后。

指南

我们为开发人员提供了一套指南,以最佳地利用 Smart Access Memory。尽管这是 PC 领域的新功能,但其中许多要点也适用于过去更传统的内存访问类型,以及 Smart Access Memory 被禁用时。

内存分配和组织

由于每次操作的开销,以更多的小块处理相同数量的数据通常速度较慢。请勿使用许多小缓冲区,而是将数据分组到较大的缓冲区中,并使用偏移量来标识部分。每个缓冲区至少包含 64KiB 的有效数据。这也有助于避免因对齐要求而导致的内存使用增加。我们的 Vulkan® Memory Allocator (VMA) 和 Direct3D®12 Memory Allocator (D3D12MA) SDK 可用于此目的。

由于我们的驱动程序优化会将 UPLOAD 资源放置在 VRAM 中,因此请勿在 UPLOAD 堆中分配超过需要的内存。这可能导致内存超额订阅。

为了在驱动程序优化下提高将正确资源分配到 VRAM 中的几率(即使只有 256MiB 的 BAR),请分配小型堆或已提交资源,并首先执行最受益于 VRAM 放置的分配。这些通常是 GPU 经常读取的资源。

CPU 访问

UPLOAD 和 BAR 内存段都采用非缓存和写组合。这意味着 CPU 读取此内存的速度很慢。由于与 CPU 的距离增加,从 BAR 读取会引入大量的额外延迟。

从 CPU 写入时,避免大跨度和随机访问。请顺序写入,或者至少具有高度的局部性。如果可能,将数据起始位置对齐到 64 字节,以最大限度地减少使用的写组合缓冲区数量。在通过 PCIe® 写入时,这一点变得更加重要。您可以在 AMD 处理器软件优化指南中阅读有关写组合的更多信息。

用于映射和取消映射内存的函数(ID3D12Resource::Map / UnmapvkMapMemory / vkUnmapMemory)具有应避免的开销。通常可以安全地并将缓冲区保持为持久映射。请注意,这可能会干扰捕获工具(如 PIX 或 RenderDoc)的性能,因此在调试版本中取消映射不需要的内存可能是有益的。

复制

将数据从 UPLOAD 内存复制到 DEFAULT 内存时,请遵循以下规则:

  1. 如果数据需要立即使用,请使用使用它的队列进行复制,以避免同步开销。
  2. 如果图形或计算队列另外空闲,请使用它进行复制。
  3. 如果在复制后不久不再使用结果,并且图形和计算队列都有并发工作,请使用复制/传输队列。

如果资源通过我们的驱动程序优化放置在 VRAM 中,图形/计算队列的复制速度可以是复制/传输队列的 5 倍。如果不是,复制/传输队列速度最快,尽管仅以微弱优势。

DirectX12 中的着色器可以直接访问 UPLOAD 内存。如果数据被写入并立即使用,并且在 GPU 上只访问一次且具有高度的局部性,那么跳过复制并直接使用 UPLOAD 内存中的缓冲区可能会有益。如果驱动程序将资源放置在 BAR 内存中,这可能比单独复制快得多。如果不是,不复制所节省的时间通常仍大于在着色器中通过 PCIe 读取所花费的额外时间。但是,这仅适用于无法在另一个队列或并发工作中隐藏复制延迟的情况。

我们已在 RDNA™ 2 性能指南中添加了这些建议的摘要。

相关内容

Oskar Homburg's avatar

Oskar Homburg

Oskar 是核心技术组的一名实习生,该小组隶属于游戏工程团队。第三方网站链接以及对第三方商标的引用仅为方便和说明之用。除非另有明确说明,AMD 对此类链接的内容概不负责,也不暗示任何第三方对 AMD 或其任何产品的认可。

相关新闻和技术文章

© . This site is unofficial and not affiliated with AMD.