我有几个计算着色器(我们称它们为compute1
,compute2
等),它们具有几个输入绑定(在着色器代码中定义为layout (...) readonly buffer
)和几个输出绑定(定义为layout (...) writeonly buffer
)。我将带有数据的缓冲区绑定到其描述符集,然后尝试并行执行这些着色器 。
我尝试过的事情:
vkQueueSubmit()
,其中VkSubmitInfo.pCommandBuffers
拥有几个主要命令缓冲区(每个计算着色器一个); vkQueueSubmit()
,其中VkSubmitInfo.pCommandBuffers
持有一个主命令缓冲区,该缓冲区是使用vkCmdExecuteCommands()
记录的,而pCommandBuffers
持有几个辅助命令缓冲区(每个计算着色器一个); vkQueueSubmit()
+ vkQueueWaitIdle()
与不同的std::thread
对象分开(每个计算着色器一个)-每个命令缓冲区都分配在单独的VkCommandPool
中,并提交给自己的{{1 }}拥有自己的VkQueue
,主线程正在等待使用VkFence
,依此类推; threads[0].join(); threads[1].join();
与不同的分离的 vkQueueSubmit()
对象分开(每个计算着色器一个)-每个命令缓冲区均分配在单独的std::thread
中,并提交给自己的{ {1}}具有自己的VkCommandPool
,主线程正在等待使用VkQueue
,其中VkFence
持有在vkWaitForFences()
中使用的篱笆,并且pFences
持有{{1 }}。我所拥有的:
在所有情况下,结果时间几乎都是相同的(相差小于1%),就像为vkQueueSubmit()
然后waitAll
调用true
+ vkQueueSubmit()
上。
我想为多个着色器的输入绑定相同的缓冲区,但是根据时间,如果每个着色器都使用自己的vkQueueWaitIdle()
+ compute1
对象执行,结果是相同的。
我的问题是:
是否可以以某种方式同时执行多个计算着色器,或者命令缓冲区并行性仅适用于图形着色器?
更新:测试应用程序是使用LunarG Vulkan SDK 1.1.73.0编译的,并在Windows 10和NVIDIA GeForce GTX 960上运行。
答案 0 :(得分:1)
这取决于要在其上执行应用程序的硬件。硬件导出队列处理已提交的命令。顾名思义,每个队列依次执行命令。因此,如果将多个命令缓冲区提交到单个队列,则将按提交顺序执行它们。在内部,GPU可以尝试并行执行所提交命令的某些部分(例如可以同时处理图形流水线的各个部分)。但是通常,单个队列按顺序处理命令,无论您提交图形还是计算命令都没有关系。
为了并行执行多个命令缓冲区,您需要将它们提交到单独的队列中。但是硬件必须支持多个队列-它必须具有单独的物理队列,以便能够同时处理它们。
但是,更重要的是-我读过一些图形硬件供应商通过图形驱动程序模拟多个队列。换句话说-它们在Vulkan中公开了多个队列,但是在内部它们是由一个物理队列处理的,我认为您的问题就是这种情况,您的实验结果可以证实这一点(尽管我不确定,当然)。