如何在 Vulkan 中跨多个计算队列执行并行计算着色器?

axs*_*uze 7 c++ gpu gpgpu compute-shader vulkan

更新:此问题已解决,您可以在此处找到更多详细信息:https ://stackoverflow.com/a/64405505/1889253

之前曾提出过类似的问题,但该问题最初集中在使用多个命令缓冲区,并触发跨不同线程的提交以实现着色器的并行执行。大多数答案表明解决方案是使用多个队列。使用多个队列似乎也是各种博客文章和 Khronos 论坛答案的共识。我已经尝试了跨多个队列运行着色器执行的这些建议,但无法看到并行执行,所以我想问一下我可能做错了什么。正如所建议的,这个问题包括提交到多个队列的多个计算着色器的可运行代码,这希望对其他想要做同样事情的人有用(一旦这个问题得到解决)。

当前的实现是在这个 pull request/branch 中,但是我将介绍 Vulkan 的主要具体点,以确保只需要 Vulkan 知识来回答这个问题。还值得一提的是,当前的用例专门针对计算队列和计算着色器,而不是图形或传输队列(尽管跨这些队列实现并行性的见解/经验仍然非常有用,并且很可能也能找到答案)。

更具体地说,我有以下内容:

有几点在上面的示例中不可见但很重要:

  • 所有 evalAsync 都在同一应用程序、实例和设备上运行
  • 每个 evalAsync 都使用自己单独的 commandBuffer 和缓冲区,并在单独的队列中执行
  • 如果您想知道内存屏障是否有作用,我们已尝试完全删除所有内存屏障(例如,在着色器执行之前运行),但这对性能没有任何影响

基准测试中使用的测试可以在此处找到,但是需要了解的唯一关键事项是:

运行测试时,我们首先在同一队列上运行一组“同步”着色器执行(数量是可变的,但我们使用 6-16 进行了测试,后者是队列的最大数量)。然后我们以异步方式运行它们,运行所有它们并 evalAwait 直到它们完成。比较两种方法的结果时间时,即使它们运行在不同的计算队列上,它们也花费相同的时间。

我的问题是:

  • 我当前在获取队列时是否遗漏了某些内容?
  • vulkan 设置中是否还需要配置其他参数以确保异步执行?
  • 是否存在我可能不知道的潜在操作系统进程只能以同步方式向 GPU 提交 GPU 工作负载的限制?
  • 在处理多个队列提交时,是否需要多线程才能使并行执行正常工作?

此外,我在各种 reddit 帖子和 Khronos Group 论坛上找到了一些有用的资源,这些资源提供了有关该主题的非常深入的概念和理论概述,但我还没有遇到显示着色器并行执行的端到端代码示例。如果您可以分享任何具有着色器并行执行功能的实际示例,那将非常有帮助。

如果有更多细节或问题可以帮助提供更多背景信息,请告诉我,我很乐意回答和/或提供更多细节。

为了完整性,我的测试使用:

  • Vulkan SDK 1.2
  • Windows 10
  • 英伟达1650

类似帖子中共享的其他相关链接:

axs*_*uze 3

我已经能够使用这个建议来解决。为了提供进一步的背景信息,我试图将命令提交到同一系列中的多个队列,但是在链接的建议中指出,NVIDIA(和其他 GPU 供应商)在命令并行处理方面具有不同的功能范围意见书。

在我的特定情况下,我正在测试的 NVIDIA 1650 卡仅在不同队列系列中提交工作负载时支持并发处理 - 更具体地说,它只能支持跨一个图形队列和一个计算系列队列提交一个并发命令。

我重新实现了代码,以允许为特定命令分配系列队列,并且能够实现并行处理(通过跨两个队列系列提交,速度提高了 2 倍)。

以下是有关实现的更多详细信息https://kompute.cc/overview/async-parallel.html