Vulkan 多个逻辑设备来自一个物理设备的后果

问题描述

在创建逻辑设备时,我们可以为一个族队列索引指定多个队列,如我们在 VkDeviceQueueCreateInfo 中看到的,我们可以在 VkDeviceCreateInfo 中传递这个结构的数组。

所以我的第一个线索,例如,创建一个传输队列和一个图形队列,是在设备创建时使用相同的逻辑设备和两个不同的 VkDeviceQueueCreateInfo。

但是,我可以使用不同的 VkDeviceQueueCreateInfo(一个用于图形,一个用于传输)从同一物理设备创建两个逻辑设备吗?

如果是,那么制定一种或另一种解决方案的好处或坏处是什么?

解决方法

一般来说,在评估在 Vulkan 中做事的可能方式时,您应该选择似乎需要最少东西的方式。

在这种情况下,您尝试在多个队列和多个设备之间进行选择。嗯,多队列方法显然需要更少的东西;你有一个有很多队列的设备(理论上),而不是很多设备有很多队列(每个设备一个)。队列数量相同,但设备更多。所以选择少的那个。

Vulkan API 不会试图欺骗您走较慢的路径。如果使用多个设备,每个设备一个队列是最好的选择,那么 Vulkan 根本不会有多个队列作为选项。

为了更详细地了解,您说您想要在图形操作之外进行内存传输。好的,好的。

物理设备不必提供多个队列。一些设备只提供一个队列族,可以从中创建一个 VkQueue。显然,如果设备允许多个队列,您应该使用它们。但如果它只允许一个,那么你可能有理由认为你应该创建多个设备并以这种方式工作。

即使在这种情况下,也不要这样做。

事情是这样的:如果一个 GPU 可以实际上独立地执行多个操作,这样它们就会重叠……它们会暴露多个队列。因此,物理设备不这样做的事实表明,在 GPU 级别根本不可能独立执行不同的操作。

这意味着,即使您使用多个设备,传输和图形操作几乎肯定会以某种顺序执行。也就是说,先发出 vkQueueSubmit 的将是最先完成工作的那个。

因此,使用多个设备不会给您带来实际的 GPU 执行重叠(理论上)。您一无所获,并且失去了对发出这些操作的顺序的明确控制。

现在,在图形队列上执行传输操作可能不会禁止在同一队列上执行渲染命令。也就是说,传输操作可以开始,然后渲染命令可以在传输完成时通过 DMA 或其他方式开始。所以他们开始按顺序执行,但以任意顺序结束执行。

即使是这样,跨设备工作也不会给您带来任何优势。如前所述,您无法控制提交这些命令的顺序。图形命令往往会占用命令队列,而单个传输命令可以(在这样的系统上)被处理,然后在处理无关命令的同时在后台执行。在这种情况下,重要的是在特定帧的图形命令之前发送任何传输命令。

如果您有两台设备,则必须有 2 个 vkQueueSubmit 调用,而不是一个。并且 vkQueueSubmit 调用并不以速度快着称。

不尝试多设备的东西还有很多其他的原因。例如,如果以后的渲染操作需要访问传输的数据,这意味着您需要外部存储器 外部同步原语来同步设备之间的访问。等等。