c++ - Vulkan 中的并行计算着色器执行?
问题描述
我有几个计算着色器(我们称它们为compute1
,compute2
等等),它们有几个输入绑定(在着色器代码中定义为layout (...) readonly buffer
)和几个输出绑定(定义为layout (...) writeonly buffer
)。我正在将带有数据的缓冲区绑定到它们的描述符集,然后尝试并行执行这些着色器。
我试过的:
vkQueueSubmit()
拥有VkSubmitInfo.pCommandBuffers
多个主要命令缓冲区(每个计算着色器一个);vkQueueSubmit()
VkSubmitInfo.pCommandBuffers
保存一个主命令缓冲区,该缓冲区是使用保存vkCmdExecuteCommands()
多个pCommandBuffers
辅助命令缓冲区(每个计算着色器一个)记录的;vkQueueSubmit()
将+vkQueueWaitIdle()
从不同的对象中分离出来std::thread
(每个计算着色器一个) - 每个命令缓冲区是单独分配的,VkCommandPool
并且正在使用 own 提交给自己VkQueue
,VkFence
主线程正在等待使用threads[0].join(); threads[1].join();
,依此类推;vkQueueSubmit()
与不同的分离 对象分开std::thread
(每个计算着色器一个) - 每个命令缓冲区是单独分配的,VkCommandPool
并且正在使用 own 提交给 ownVkQueue
,VkFence
主线程正在等待使用vkWaitForFences()
与hold 一起使用的pFences
栅栏,该栅栏在中使用vkQueueSubmit()
和与waitAll
holding一起使用true
。
我有什么:
在所有情况下,结果时间几乎相同(差异小于 1%),就好像调用vkQueueSubmit()
+ vkQueueWaitIdle()
for compute1
,然后 forcompute2
等等。
我想将相同的缓冲区绑定为多个着色器的输入,但根据时间,如果每个着色器都使用自己的VkBuffer
+VkDeviceMemory
对象执行,结果是相同的。
所以我的问题是:
是否有可能以某种方式同时执行多个计算着色器,或者命令缓冲区并行性仅适用于图形着色器?
更新:测试应用程序使用 LunarG Vulkan SDK 1.1.73.0 编译并在带有 NVIDIA GeForce GTX 960 的 Windows 10 上运行。
解决方案
这取决于您正在执行应用程序的硬件。硬件导出处理提交命令的队列。顾名思义,每个队列依次执行命令。因此,如果您将多个命令缓冲区提交到单个队列,它们将按提交顺序执行。在内部,GPU 可以尝试并行执行提交的命令的某些部分(例如可以同时处理图形管道的单独部分)。但一般来说,单队列按顺序处理命令,无论您是提交图形命令还是计算命令都没有关系。
为了并行执行多个命令缓冲区,您需要将它们提交到单独的队列。但是硬件必须支持多个队列——它必须有单独的物理队列,以便能够同时处理它们。
但是,更重要的是——我读过一些图形硬件供应商通过图形驱动程序模拟多个队列。换句话说 - 它们在 Vulkan 中公开了多个队列,但在内部它们由单个物理队列处理,我认为您的问题就是这种情况,您的实验结果将证实这一点(当然我不能确定)。
推荐阅读
- mysql - 如何将多行合并为一行?
- python - 使用python将HTML代码导入CSV
- integration - Activiti 框架和 teradata 兼容性
- html - 如果没有要显示的对象数据,如何在 Jinja (flask) 中显示消息
- python - 如何根据python中其他列的信息/条件将字符串放入新列
- java - 如何将 HTTP 响应作为字符串转换为数组?
- java - java.lang.NoSuchMethodError:使用詹金斯共享库时,在步骤中找不到这样的 DSL 方法“ci”
- javascript - 如何在使用事件侦听器单击特定 div 时隐藏它?
- javascript - 如何在jquery中使用数据属性隐藏tr
- python - 在python的for循环中合并数据帧