Vulkan中的队列家庭实际上是什么? [英] What is actually a Queue family in Vulkan?

查看:258
本文介绍了Vulkan中的队列家庭实际上是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在学习vulkan,现在我只是分解每个命令并检查结构以尝试理解它们的含义。

I am currently learning vulkan, right now I am just taking apart each command and inspecting the structures to try to understand what they mean.

现在我正在分析QueueFamilies,我具有以下代码:

Right now I am analyzing QueueFamilies, for which I have the following code:

vector<vk::QueueFamilyProperties> queue_families = device.getQueueFamilyProperties();
for(auto &q_family : queue_families)
{
    cout << "Queue number: "  + to_string(q_family.queueCount) << endl;
    cout << "Queue flags: " + to_string(q_family.queueFlags) << endl;
}

这将产生以下输出:

Queue number: 16
Queue flags: {Graphics | Compute | Transfer | SparseBinding}
Queue number: 1
Queue flags: {Transfer}
Queue number: 8
Queue flags: {Compute}

因此,我天真地理解了这一点:

So, naively I am understanding this like this:

有3个队列族,一个队列一家有16个队列,所有队列都能进行图形,计算,传输和稀疏绑定操作(不知道最后两个队列是什么)

There are 3 Queue families, one queue family has 16 queues, all capable of graphics, compute, transfer and sparse binding operations (no idea what the last 2 are)

另一个队列只有1个队列,只能传输(无论是什么)

Another has 1 queue, capable only of transfer (whatever that is)

最后一个有8个能够进行计算操作的队列。

And the final one has 8 queues capable of compute operations.

每个是什么排队的家人?我了解这是我们发送绘图和交换缓冲区之类的执行命令的地方,但这是一个较宽泛的解释,我希望获得更多知识的详细答案。

What is each queue family? I understand it's where we send execution commands like drawing and swapping buffers, but this is a somewhat broad explanation, i would like a more knoweledgeable answer with more details.

两个额外的标志是什么?

What are the 2 extra flags? Transfer and SparseBidning?

最后,为什么我们要/需要多个命令队列?

And finaly, why do we have/need multiple command queues?

推荐答案

要了解队列系列,您首先必须了解队列。

To understand queue families, you first have to understand queues.

队列是您要向其提交命令缓冲区,并且向其提交命令缓冲区的对象。队列相对于彼此以order [* 1]执行。除非您将它们与 VkSemaphore 显式同步,否则提交到不同队列的命令缓冲区彼此之间是无序的。您一次只能将工作从一个线程提交到队列,但是不同的线程可以同时将工作提交到不同的队列。

A queue is something you submit command buffers to, and command buffers submitted to a queue are executed in order[*1] relative to each other. Command buffers submitted to different queues are unordered relative to each other unless you explicitly synchronize them with VkSemaphore. You can only submit work to a queue from one thread at a time, but different threads can submit work to different queues simultaneously.

每个队列只能执行某些类型的操作。图形队列可以运行由 vkCmdDraw * 命令启动的图形管道。计算队列可以运行由 vkCmdDispatch * 开始的计算管道。传输队列可以从 vkCmdCopy * 执行传输(复制)操作。稀疏绑定队列可以使用 vkQueueBindSparse 更改稀疏资源到内存的绑定(请注意,这是直接提交给队列的操作,而不是命令缓冲区中的命令)。有些队列可以执行多种操作。在规范中,每个可以提交到队列的命令都有一个命令属性表,该表列出了可以执行该命令的队列类型。

Each queue can only perform certain kinds of operations. Graphics queues can run graphics pipelines started by vkCmdDraw* commands. Compute queues can run compute pipelines started by vkCmdDispatch*. Transfer queues can perform transfer (copy) operations from vkCmdCopy*. Sparse binding queues can change the binding of sparse resources to memory with vkQueueBindSparse (note this is an operation submitted directly to a queue, not a command in a command buffer). Some queues can perform multiple kinds of operations. In the spec, every command that can be submitted to a queue have a "Command Properties" table that lists what queue types can execute the command.

队列族仅描述了具有相同属性的一组队列。因此,在您的示例中,设备支持三种队列:

A queue family just describes a set of queues with identical properties. So in your example, the device supports three kinds of queues:


  • 一种可以进行图形处理,计算,传输和稀疏绑定操作,最多可以创建16个该类型的队列。

  • One kind can do graphics, compute, transfer, and sparse binding operations, and you can create up to 16 queues of that type.

另一种类型只能执行传输操作,并且只能创建一个这种队列。类。通常,这是用于离散GPU上主机和设备内存之间的DMA异步数据传输,因此可以通过独立的图形/计算操作同时进行传输。

Another kind can only do transfer operations, and you can only create one queue of this kind. Usually this is for asynchronously DMAing data between host and device memory on discrete GPUs, so transfers can be done concurrently with independent graphics/compute operations.

最后,您最多可以创建8个仅能进行计算操作的队列。

Finally, you can create up to 8 queues that are only capable of compute operations.

某些队列可能仅对应于其中的单独队列在主机端调度程序中,其他队列可能与硬件中的实际独立队列相对应。例如,许多GPU仅具有一个硬件图形队列,因此,即使您从具有图形功能的队列家族中创建了两个VkQueue,提交给这些队列的命令缓冲区也将独立地通过内核驱动程序的命令缓冲区调度程序进行处理,但会以某种串行方式执行在GPU上订购。但是某些GPU具有多个仅用于计算的硬件队列,因此,仅用于计算的队列族的两个VkQueue可能实际上一直独立地并发地通过GPU进行。 Vulkan不会公开这一点。

Some queues might only correspond to separate queues in the host-side scheduler, other queues might correspond to actual independent queues in hardware. For example, many GPUs only have one hardware graphics queue, so even if you create two VkQueues from a graphics-capable queue family, command buffers submitted to those queues will progress through the kernel driver's command buffer scheduler independently, but will execute in some serial order on the GPU. But some GPUs have multiple compute-only hardware queues, so two VkQueues for a compute-only queue family might actually proceed independently and concurrently all the way through the GPU. Vulkan doesn't expose this.

底线,根据您拥有多少并发性,确定可以有效使用的队列数。对于许多应用程序,它们只需要一个通用队列。更高级的服务器可能具有一个图形+计算队列,一个用于异步计算工作的单独的仅计算队列以及一个用于异步DMA的传输队列。然后将您想要的内容映射到可用的内容上;您可能需要进行自己的多路复用,例如在没有仅计算队列系列的设备上,您可以改为创建多个图形+计算队列,或者自己将异步计算作业序列化到单个图形+计算队列中。

Bottom line, decide how many queues you can usefully use, based on how much concurrency you have. For many apps, a single "universal" queue is all they need. More advanced ones might have one graphics+compute queue, a separate compute-only queue for asynchronous compute work, and a transfer queue for async DMA. Then map what you'd like onto what's available; you may need to do your own multiplexing, e.g. on a device that doesn't have a compute-only queue family, you might create multiple graphics+compute queues instead, or serialize your async compute jobs onto your single graphics+compute queue yourself.

[* 1]简化了一点。它们按顺序开始,但是之后可以独立进行,并且可以按顺序完成。但是不能保证不同队列的独立进度。对于这个问题,我将保留它。

[*1] Oversimplifying a bit. They start in order, but are allowed to proceed independently after that and complete out of order. Independent progress of different queues is not guaranteed though. I'll leave it at that for this question.

这篇关于Vulkan中的队列家庭实际上是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆