Vulkan 中的设备到设备复制

Device to device copy in Vulkan

我想在我的 Vulkan 应用程序中的两个 GPUs/physical 设备之间复制一个 image/buffer(一个 vkInstance,两个 vkDevice)。如果不在 CPU 上暂存图像,这是否可能,或者是否有像 CUDA p2p 这样的功能?这看起来如何?

如果需要在主机上暂存,最佳方法是什么?

is there a feature like CUDA p2p?

Vulkan 1.1 支持 device groups 的概念来涵盖这种情况。 它允许您将一组物理设备视为单个逻辑设备,还允许您查询如何在设备组内操作内存,以及执行诸如在设备子集上分配内存等操作。检查全套功能的规格。

Is this possible without staging the image on the CPU

如果您的设备不支持扩展 VK_KHR_device_group,则不支持。您必须通过 CPU 和系统内存传输内容。

由于缓冲区是按设备分配的,因此您需要两个主机可见的暂存缓冲区,一个用于读取操作,另一个用于写入操作。您还需要两个队列、两个命令缓冲区等...

您必须执行 3 个手动同步操作。

  • 在源 GPU 上执行从设备本地缓冲区到同一设备的主机可见缓冲区的复制。

  • 上CPU从源GPU主机可见缓冲区复制到目标GPU主机可见缓冲区

  • 在目标 GPU 上从主机可见缓冲区复制到设备本地缓冲区

确保检查您的设备队列系列属性,如果可能,使用来自标记为传输能力但图形或计算能力的队列系列的队列。 Vulkan 队列系列的标志越少,它就越适合它 确实 具有标志的操作。大多数 modern discrete GPUs 都有专用的传输队列,但同样,队列是特定于设备的,因此您需要与每个设备的一个队列进行交互才能执行传输。

If staging on the host is required, what would be the optimal method for this?

具体如何执行取决于您的用例。如果你想在一个线程中同步执行整个事情,那么你将只做一堆提交,然后在栅栏上等待。如果您想在继续渲染帧的同时在后台异步执行此操作,那么您仍然会进行提交,但您必须在移至之前对围栏进行非阻塞检查以查看操作何时完成下一部分。

如果您正在传输缓冲区,就最佳传输而言可能没有什么可担心的,但如果您正在处理图像,那么您必须进入整个线性与最佳图像平铺的混乱局面。为了避免这种情况,我建议使用主机可见缓冲区进行暂存,无论您是传输图像还是缓冲区,因此使用 vkCmdCopyImageToBuffervkCmdCopyBufferToImage 进行设备本地之间的传输和主机可见内存