在我的机器上,我有两个队列系列,一个支持所有内容,另一个支持转移.
支持所有内容的队列系列的queueCount为16
.
现在规范说明了
提交给不同队列的命令缓冲区可以相互并行地执行,甚至可以不按顺序执行
这是否意味着我应该尝试使用所有可用的队列以获得最佳性能?
Nic*_*las 15
到底是什么?
采用延迟渲染器的典型结构.你可以构建你的g-buffers,做你的光照通道,做一些后期处理和色调映射,也可以投入一些透明的东西,然后呈现最终的图像.每个过程都取决于之前已完成的过程,然后才能开始.在完成g-buffer之前,你无法完成光照通道.等等.
你如何在多个执行队列中并行化?您无法并行化g-buffer构建或光照传递,因为所有这些命令都写入相同的附加图像(并且您无法从多个队列中执行此操作).如果他们没有写入相同的图像,那么您将不得不选择一个队列,将生成的图像合并到最终图像中.另外,我不知道深度缓冲如何在不使用相同深度缓冲区的情况下工作.
而这个组合步骤需要同步.
现在,有许多任务可以并行化.做截头剔除.粒子系统更新.记忆转移.像这样的东西; 用于下一帧的数据.但是你有多少队列可以实际上保持忙碌?3?也许4?
更不用说,你将需要构建一个可以扩展的渲染系统.Vulkan不要求实现提供多于1个队列.因此,您的代码需要能够在仅提供一个队列的系统以及提供16的系统上合理运行.并且要利用16队列系统,您可能需要以非常不同的方式呈现.
哦,请注意,如果你要求一堆队列,但不使用它们,性能可能会受到影响.如果您要求8个队列,则实现别无选择,只能假设您打算能够发出8个并发命令集.这意味着硬件无法将其所有资源专用于单个队列.因此,如果您只使用其中的3个......您可能会将超过50%的潜在性能丢失到实施等待您使用的资源上.
当然,实现可以动态扩展这些事情.但除非你描述这个特例,否则你永远不会知道.哦,如果它确实动态扩展...那么你也不会因为使用这样的多个队列而获得很多.
最后,已经有一些研究在多个平台(读取所有部分)上多个队列提交对于保持GPU馈送的有效性.它的一般长短似乎是:
krO*_*oze 14
是的,如果您具有高度独立的工作负载,请使用单独的队列.
如果队列之间需要大量同步,它可能会杀死您可能获得的任何潜在好处.
基本上你正在做的是为GPU提供它可以做的一些替代工作(并且在同一队列系列的情况下填充档位和气泡和空闲并给予GPU选择).并且有一些潜力可以更好地使用CPU(例如,单线程与每个线程一个队列).
使用单独的传输队列(或其他专业系列)似乎甚至是推荐的方法.
一般来说就是这样.SW和NB的答案已经提出了更现实,经验,怀疑和实践的观点.实际上,由于这些队列针对相同的资源,具有相同的限制和其他常见限制,因此必须更加谨慎,这限制了从中获得的潜在好处.值得注意的是,如果驱动程序使用多个队列做错了,那么缓存可能非常糟糕.
这个AMD 利用异步队列进行并发执行(2016)讨论了它如何映射到他们的HW \驱动程序.它显示了使用单独队列系列的潜在好处.它表示尽管他们提供了两个计算系列队列,但他们当时并未观察到应用程序的优势.他们说他们只有一个图形队列,为什么.
NVIDIA似乎也有类似"异步计算"的想法.显示在移动到福尔康:异步计算.
为了安全起见,我们似乎仍然应该只使用一个图形和一个异步计算队列,但在当前的硬件上.16个队列似乎是一个陷阱和伤害自己的方式.
使用传输队列并不像看起来那么简单.您应该使用专用的主机 - >设备传输.非专用应该用于设备 - >设备传输操作.
这在很大程度上取决于您的实际场景和设置.没有任何细节很难说清楚.
如果您将命令缓冲区提交给多个队列,您还需要进行适当的同步,如果这样做不正确,您可能会获得比仅使用一个队列更差的性能.
请注意,即使您只提交到一个队列,实现也可以并行执行命令缓冲区,甚至无序执行(也就是"在飞行中"),请参阅规格2.2章节或此AMD演示文稿中的详细信息.
如果您执行计算和图形,则使用具有同时提交(和同步)的单独队列将提高支持异步计算的硬件的性能.
因此,如果不了解您的实际用例,就没有明确的肯定或否定.