我想在我的Vulkan应用程序中的两个GPU /物理设备之间复制图像/缓冲区(一个vkInstance
,两个vkDevice
)。是否可以在不将映像暂存到CPU上的情况下实现此功能,或者是否具有CUDA p2p之类的功能?看起来如何?
如果需要在主机上暂存,那么最佳的方法是什么?
答案 0 :(得分:4)
有像CUDA p2p这样的功能吗?
Vulkan 1.1支持device groups的概念来解决这种情况。 它使您可以将一组物理设备视为单个逻辑设备,还可以查询如何在设备组中操纵内存,以及在诸如设备子集上分配内存等操作。检查规格以获取全部功能。
是否可以在不将映像暂存到CPU上的情况下
如果您的设备不支持扩展VK_KHR_device_group
,则否。您必须通过CPU和系统内存传输内容。
由于每个设备都有缓冲区,因此您将需要两个主机可见的暂存缓冲区,一个用于读操作,另一个用于写操作。您还需要两个队列,两个命令缓冲区等,等等。
您必须通过手动同步执行3个操作。
在源GPU上,执行从设备本地缓冲区到同一设备的主机可见缓冲区的复制。
在从源GPU主机可见缓冲区到目标GPU主机可见缓冲区的CPU副本上
在目标GPU上,从主机可见缓冲区复制到设备本地缓冲区
请确保检查您的设备队列系列属性,并在可能的情况下使用标记为可传输但不具有图形或计算能力的队列系列中的队列。 Vulkan队列系列拥有的标志越少,它就更适合其具有的标志的操作。大多数modern discrete GPUs都有专用的传输队列,但是同样,该队列是特定于设备的,因此您需要与一个队列进行交互才能使每个设备执行传输。
如果需要在主机上暂存,那么最佳的方法是什么?
具体如何执行此操作取决于您的用例。如果您想在单个线程中同步执行整个事情,那么您将只执行一堆提交,然后在栅栏上等待。如果您想在继续渲染帧的同时在后台异步执行操作,那么您仍将继续进行提交,但是您必须对栅栏进行非阻塞检查,以查看操作何时完成,然后再移至下一部分。
如果要传输缓冲区,就最佳传输而言,可能没有什么可担心的,但是如果要处理图像,则必须深入了解整个线性与最佳图像拼接的混乱。为了避免这种情况,我建议使用主机可见的缓冲区进行暂存,而不管是否要传输图像或缓冲区,因此,请使用vkCmdCopyImageToBuffer
和vkCmdCopyBufferToImage
在本地设备之间进行传输和主机可见的内存