更新:此问题已得到解决,您可以在此处找到更多详细信息:https://dev59.com/8b3pa4cB1Zd3GeqPkb0R#64405505
之前也有人提出了类似的问题,但那个问题最初侧重于使用多个命令缓冲区,在不同的线程上触发提交以实现着色器的并行执行。大多数答案建议使用多个队列来解决问题。使用多个队列似乎也是各种博客文章和Khronos论坛回答中的共识。我尝试了那些建议,在多个队列上运行着色器执行,但没有看到并行执行效果,所以我想问一下我可能做错了什么。正如建议的那样,这个问题包含了多个计算着色器的可运行代码被提交到多个队列,并希望对其他正在寻求实现相同功能的人有用。
当前实现位于此拉取请求/分支中,但我将涵盖主要的Vulkan特定点,以确保只需要Vulkan知识来回答这个问题。还值得一提的是,当前用例特别针对计算队列和计算着色器,而不是图形或传输队列(尽管实现跨这些队列实现并行性的见解/经验仍将非常有用,并且很可能也会导致答案)。
更具体地说,我有以下内容:
- 首先获取多个队列——我的设备是NVIDIA 1650,支持在队列族索引0中有16个图形+计算队列,以及在队列族索引2中有8个计算队列。 - evalAsync执行提交(其中包含记录的着色器命令)——您应该注意到创建了一个能够使用的障碍。此外,提交没有任何waitStageMasks(PipelineStageFlags)。 - evalAwait允许我们等待障碍——在调用evalAwait时,我们能够通过创建的几何图形来等待提交完成。
还有一些在上面的示例中看不到但很重要的点:
当前实现位于此拉取请求/分支中,但我将涵盖主要的Vulkan特定点,以确保只需要Vulkan知识来回答这个问题。还值得一提的是,当前用例特别针对计算队列和计算着色器,而不是图形或传输队列(尽管实现跨这些队列实现并行性的见解/经验仍将非常有用,并且很可能也会导致答案)。
更具体地说,我有以下内容:
- 首先获取多个队列——我的设备是NVIDIA 1650,支持在队列族索引0中有16个图形+计算队列,以及在队列族索引2中有8个计算队列。 - evalAsync执行提交(其中包含记录的着色器命令)——您应该注意到创建了一个能够使用的障碍。此外,提交没有任何waitStageMasks(PipelineStageFlags)。 - evalAwait允许我们等待障碍——在调用evalAwait时,我们能够通过创建的几何图形来等待提交完成。
还有一些在上面的示例中看不到但很重要的点:
- 所有的evalAsync都在同一个应用程序、实例和设备上运行。
- 每个evalAsync都使用自己独立的commandBuffer和缓冲区,在单独的队列中执行。
- 如果你想知道内存屏障是否有关系,我们已经尝试通过完全删除所有memoryBarriers (例如在shader执行之前运行的这个),但是这对性能没有产生任何影响。
在基准测试中使用的测试可以在此处找到,不过需要理解的关键要点如下:
- 这是我们用于测试的着色器,你可以看到,我们只是添加了一堆原子加步骤来增加处理时间。
- 目前的测试具有小缓冲区大小和很高的着色器循环迭代次数,但我们还测试过大缓冲区大小(即100,000而不是10),以及更小的迭代次数(即1,000而不是100,000,000)。
运行测试时,我们首先在同一队列上运行一组“同步”shader执行(数量可变,但我们已经测试了6-16个,后者是最大队列数)。然后我们以异步方式运行它们,当所有evalAsync都完成时,我们才运行evalAwait。当比较两种方法得到的时间时,它们花费相同的时间,即使它们在不同的计算队列中运行。
我的问题是:
- 我在获取队列时是否有遗漏?
- Vulkan设置中是否有进一步的参数需要配置以确保异步执行?
- 可能有任何限制吗,比如操作系统进程只能以同步方式向GPU提交工作负载?
- 在处理多个队列提交时,是否需要使用多线程才能使并行执行正常运行?
此外,我在网上找到了许多有用的资源,涉及Reddit帖子和Khronos Group论坛,提供了非常详细的概念和理论概述,但我没有找到端到端代码示例显示着色器的并行执行。如果您有任何实际示例可以分享,并具有功能并行执行着色器,则会非常有帮助。
如果有进一步的细节或问题可帮助提供更多背景,请告知,我很乐意回答这些问题并/或提供更多细节。
为了完整起见,我的测试使用:
- Vulkan SDK 1.2
- Windows 10
- NVIDIA 1650
其他相关链接:
- 关于异步计算着色器的类似讨论,建议提供示例链接,但该链接似乎已经消失了......
- 关于利用异步队列进行并发执行的帖子(不幸的是没有示例代码)
- (相对较旧-5年)这篇文章表明NVIDIA卡不能并行执行着色器,但似乎没有决定性的答案
- Nvidia演示文稿关于使用多个队列执行Vulkan多线程的说明 (因此我上面问了关于线程的问题)