在Vulkan中执行并行计算着色器?

时间:2018-06-19 11:32:54

标签: c++ parallel-processing glsl vulkan compute-shader

我有几个计算着色器(我们称它们为compute1compute2等),它们具有几个输入绑定(在着色器代码中定义为layout (...) readonly buffer)和几个输出绑定(定义为layout (...) writeonly buffer)。我将带有数据的缓冲区绑定到其描述符集,然后尝试并行执行这些着色器


我尝试过的事情:

  1. vkQueueSubmit(),其中VkSubmitInfo.pCommandBuffers拥有几个主要命令缓冲区(每个计算着色器一个);
  2. vkQueueSubmit(),其中VkSubmitInfo.pCommandBuffers持有一个主命令缓冲区,该缓冲区是使用vkCmdExecuteCommands()记录的,而pCommandBuffers持有几个辅助命令缓冲区(每个计算着色器一个);
  3. vkQueueSubmit() + vkQueueWaitIdle()与不同的std::thread对象分开(每个计算着色器一个)-每个命令缓冲区都分配在单独的VkCommandPool中,并提交给自己的{{1 }}拥有自己的VkQueue,主线程正在等待使用VkFence,依此类推;
  4. 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上运行。

1 个答案:

答案 0 :(得分:1)

这取决于要在其上执行应用程序的硬件。硬件导出队列处理已提交的命令。顾名思义,每个队列依次执行命令。因此,如果将多个命令缓冲区提交到单个队列,则将按提交顺序执行它们。在内部,GPU可以尝试并行执行所提交命令的某些部分(例如可以同时处理图形流水线的各个部分)。但是通常,单个队列按顺序处理命令,无论您提交图形还是计算命令都没有关系。

为了并行执行多个命令缓冲区,您需要将它们提交到单独的队列中。但是硬件必须支持多个队列-它必须具有单独的物理队列,以便能够同时处理它们。

但是,更重要的是-我读过一些图形硬件供应商通过图形驱动程序模拟多个队列。换句话说-它们在Vulkan中公开了多个队列,但是在内部它们是由一个物理队列处理的,我认为您的问题就是这种情况,您的实验结果可以证实这一点(尽管我不确定,当然)。