Vulkan 队列的底层硬件映射

Yaa*_*aaZ 4 gpu vulkan

Vulkan 旨在为用户提供精简和明确的内容,但队列是此规则的一个很大例外:队列可能由驱动程序复用,并且使用一个系列的多个队列是否会提高性能并不总是很明显。

在驱动程序更新之一之后,我有 2 个仅传输队列而不是一个,但我很确定与仅使用其中一个相比,并行使用它们进行数据流传输没有任何好处(会很高兴被证明是错误的)

那么为什么不直接说“我们有 N 个单独的硬件队列,如果您想并行使用其中的一些队列,只需自己互斥它”?现在看起来没有办法知道,家庭中的独立队列到底有多独立。

Nic*_*las 6

如今,GPU 不得不应对多处理世界。不同的程序可以访问相同的硬件,而 GPU 必须能够处理这个问题。因此,为单个实际硬件提供并行输入流与能够创建比实际 CPU 内核更多的 CPU 线程没有什么不同。

也就是说,来自家庭的队列可能不会“互斥”对实际硬件的访问。至少,不是以 CPU 方式。如果来自一个系列的多个队列是在同一硬件上执行内容的不同路径,那么从这些多个队列填充硬件的方式可能发生在 GPU 级别。也就是说,它是一个实际的硬件功能。

并且您永远无法通过“自己互斥”来获得与该硬件功能相当的性能。例如:

我有 2 个仅传输队列而不是一个,但我很确定与仅使用其中一个队列相比,并行使用它们进行数据流传输没有任何好处

让我们假设在该传输队列后面确实只有一个具有固定带宽的硬件 D​​MA 通道。这意味着,在任何时候,一次只能将一件事从 CPU 内存 DMA 到 GPU 内存。

现在,假设您有一些 DMA 工作要做。你想上传一堆东西。但时不时,您需要下载一些渲染产品。该下载需要尽快完成,因为您需要重用存储这些字节的图像。

使用优先队列,您可以赋予下载传输队列比上传队列更高的优先级。如果硬件允许,则可以中断上传执行下载,然后返回上传。

按照您的方式,您必须定期上传每个项目。必须能够被可能的下载中断的过程。要做到这一点,您基本上必须有一个重复出现的任务来执行并将单个上传提交到传输队列。

将工作交给 GPU 并让其优先级系统处理它会更有效率。即使没有优先级系统,它也可能会执行循环操作,在输入传输队列操作之间来回跳跃,而不是等待一个队列耗尽后再尝试另一个队列。

但当然,这都是假设。您需要进行分析工作以确保这些事情成功。

家族内队列的主要问题是它们有时代表具有自己专用资源的不同硬件,有时则不代表不同的硬件。例如,AMD 的硬件提供两个传输队列,但它们实际上使用单独的 DMA 通道。诚然,它们可能仍然共享相同的总带宽,但这不是一个队列必须等待另一个队列执行传输命令才能执行工作的简单情况。