在 Vulkan 中执行并行计算着色器?
Parallel compute shaders execution in Vulkan?
我有几个计算着色器(我们称它们为compute1
、compute2
等(,它们具有多个输入绑定(在着色器代码中定义为layout (...) readonly buffer
(和多个输出绑定(定义为layout (...) writeonly buffer
(。我将缓冲区与数据绑定到其描述符集,然后尝试并行执行这些着色器。
我尝试过:
vkQueueSubmit()
,VkSubmitInfo.pCommandBuffers
包含多个主命令缓冲区(每个计算着色器一个(;vkQueueSubmit()
VkSubmitInfo.pCommandBuffers
保存一个使用vkCmdExecuteCommands()
记录的主命令缓冲区,pCommandBuffers
保存多个辅助命令缓冲区(每个计算着色器一个(;- 来自不同
std::thread
对象的分离vkQueueSubmit()
+vkQueueWaitIdle()
(每个计算着色器一个( - 每个命令缓冲区在单独的VkCommandPool
中分配,并使用自己的VkFence
提交到自己的VkQueue
,主线程正在使用threads[0].join(); threads[1].join();
等待,依此类推;
将 vkQueueSubmit()
与不同的分离std::thread
对象分开(每个计算着色器一个( - 每个命令缓冲区在单独的VkCommandPool
中分配,并使用自己的VkFence
提交到自己的VkQueue
,主线程正在使用vkWaitForFences()
等待pFences
保持围栏,用于vkQueueSubmit()
和waitAll
保持true
。
我得到了什么:
在所有情况下,结果时间几乎相同(差异小于 1%(,就像调用vkQueueSubmit()
+vkQueueWaitIdle()
表示compute1
,然后调用compute2
等。
我想绑定相同的缓冲区作为多个着色器的输入,但如果每个着色器都使用自己的VkBuffer
+VkDeviceMemory
对象执行,则根据时间,结果是相同的。
所以我的问题是:
是否可以以某种方式同时执行多个计算着色器,或者命令缓冲区并行性仅适用于图形着色器?
更新:測試應用程式使用 LunarG Vulkan SDK 1.1.73.0 編譯,並在 Windows 10 上運行 NVIDIA GeForce GTX 960。
这取决于您在其上执行应用程序的硬件。硬件导出处理已提交命令的队列。顾名思义,每个队列按顺序一个接一个地执行命令。因此,如果将多个命令缓冲区提交到单个队列,则它们将按提交顺序执行。在内部,GPU 可以尝试并行执行已提交命令的某些部分(例如可以同时处理图形管道的单独部分(。但通常,单队列按顺序处理命令,提交图形命令还是计算命令并不重要。
为了并行执行多个命令缓冲区,您需要将它们提交到单独的队列。但是硬件必须支持多个队列 - 它必须具有单独的物理队列才能同时处理它们。
但是,更重要的是 - 我读到一些图形硬件供应商通过图形驱动程序模拟多个队列。换句话说 - 它们在 Vulkan 中公开了多个队列,但在内部它们由单个物理队列处理,我认为您的问题就是这种情况,您的实验结果将证实这一点(尽管我不能确定,当然(。
- 我们如何并行运行算法的 n 个实例并以有效的方式计算结果函数的平均值?
- 使用与 openmp C++并行的循环计算矩阵中每一行的最小值
- 在 Vulkan 中执行并行计算着色器?
- C++ openmp 并行计算计算错误的结果
- 使用 OpenMP 并行执行比串行执行 c++ 花费更长的时间,我计算执行时间是否正确?
- 指针警告(并行计算)
- C++:快速/并行计算两个"std::vector<double>"向量之间的L1距离
- 使用C 中的线程并行计算
- 并行计算奇偶校验
- 三任务并行计算
- 使用OpenMP C++并行计算程序的积分
- 并行计算一个大矢量的和
- 用于并行计算的C++代码优化示例
- 通过集成与OpenMP并行计算
- 并行计算--混乱的输出
- 并行计算内存访问瓶颈
- 并行计算的二次形式在RcppParallel
- 分区是一个类似生活游戏的程序,用于负载平衡的并行计算
- 使用虚幻引擎4进行并行计算
- 编译器本身使用并行计算方法运行