内存分配

在 Vulkan 中管理设备内存对某些开发人员来说可能是新的概念,理解一些基础知识非常重要。

Khronos 关于 Vulkan 内存管理的两个非常棒的演示文稿,来自 Vulkan 开发日蒙特利尔视频)和 2018 Vulkanised视频)是学习一些主要概念的好方法。

还值得注意的是,管理内存并不容易,开发人员可能希望选择使用诸如 Vulkan Memory Allocator 之类的库来提供帮助。

子分配

在 Vulkan 中工作时,子分配被认为是一流的方法。 同样重要的是要意识到存在一个 maxMemoryAllocationCount,它限制了应用程序可以同时使用的活动分配的数量。在操作系统/驱动程序级别进行内存分配和释放可能非常慢,这是进行子分配的另一个原因。 Vulkan 应用程序应旨在创建大型分配,然后自行管理它们。

memory_allocation_sub_allocation.png

传输

VkPhysicalDeviceType 公布了两种主要的 GPU 类型,即独立显卡和集成显卡(也称为 UMA(统一内存架构))。为了获得性能,了解两者之间的差异非常重要。

独立显卡在其设备上包含自己的专用内存。 数据通过总线(例如 PCIe)传输,由于数据传输的物理速度限制,这通常是一个瓶颈。 一些物理设备将公布一个带有 VK_QUEUE_TRANSFER_BIT 的队列,该队列允许专用队列用于传输数据。 通用做法是创建一个暂存缓冲区,在通过命令缓冲区发送到设备本地内存之前,将主机数据复制到该缓冲区中。

UMA 系统在设备和主机之间共享内存,并通过 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT 组合进行公布。 缺点是系统内存必须与 GPU 共享,这需要注意内存压力。 主要优点是不需要创建暂存缓冲区,并且传输开销大大减少。

memory_allocation_transfer.png

延迟分配的内存

在基于瓦片的架构(几乎所有移动 GPU)上,LAZILY_ALLOCATED_BIT 内存类型没有实际内存支持。 它可以用于可以保存在瓦片内存中的附件,例如子通道之间的 G 缓冲区、深度缓冲区或多采样图像。 这节省了将图像写回内存的一些显著带宽成本。 你可以在 Khronos 的关于 渲染通道子通道的教程中找到更多信息。