哪些阻止Vulkan功能?

时间:2018-02-06 02:57:15

标签: multithreading vulkan

在Vulkan中,建议将API调用分解为单独的线程以获得更好的吞吐量。我不确定哪种类型的调用是计算成本高的调用会导致线程阻塞,因此应该异步使用。

正如我所看到的,这些是可能需要很长时间才能执行的潜在呼叫/呼叫系列。

  • vkAcquireImageKHR()
  • vkQueueSubmit()
  • vkQueuePresentKHR()
  • memcpy到映射内存
  • vkBegin / EndCommandBuffer
  • vkCmd *要求绘图和计算

但是,我越是想到它们,越多看起来就越便宜。我会解释我的理性,这可能是有缺陷的。

vkAcquireImageKHR()

如果你选择超时,这可能会阻止。但是,一个充分优化的应用程序可能会在0超时时调用此函数,如果图像尚不可用,则可以执行其他工作。因此,这个功能可以立即生效。如果应用程序足够智能,则无需等待。

vkQueueSubmit()

此函数采用栅栏,当GPU完成执行命令缓冲区时将发出信号。因此,当GPU执行工作时,它实际上并没有等待。我假设这个函数是启动命令缓冲区数据到GPU的物理移动的函数,但我假设它告诉硬件从某个内存位置读取,然后函数尽快返回。因此,当命令缓冲区被发送到GPU时,它不会等待。

vkQueuePresentKHR()

向GPU发送信号,将一些图像发送到窗口/监视器。它不需要等待太多,是吗?

memcpy到映射内存

这可能很慢。

vkCmd *调用

这一系列的电话是我最不确定的。当我读到线程和Vulkan时,通常会将这些调用放到线程上。但是,这些呼叫到底在做什么呢?他们是否正在构建一些由一些整数和指针组成的操作码缓冲区,以便发送到GPU?如果是这样,那应该非常快。实际工作将执行那些操作码所描述的操作。

1 个答案:

答案 0 :(得分:2)

定义"阻止"。 traditional definition of "block"ing将等待一些内部同步,从而花费的时间比操作所需的时间长。执行memcpy没有进行任何同步;它只是复制数据。

所以你似乎并不关心"阻止" ing;你只是在讨论哪些操作昂贵

vkQueueSubmit不会阻止。但这并不意味着它不是昂贵的。它不是“告诉硬件从某个存储器位置读取”#34;只要看看它的界面。它不需要一个命令缓冲区;它需要一个任意数量的,它们被分组成批,每个批处理在执行前等待信号量,在执行后发出信号信号,整个操作用信号通知一个围栏。

你无法合理地期望实现这样的事情只是复制一些指针。

这甚至不会涉及不同类型的命令缓冲区问题。提交SIMULTANEOUS_USE命令缓冲区可能需要创建其缓冲数据的临时副本,以便不同的批处理可以包含相同的命令缓冲区。

现在很明显,vkQueueSubmit将在它提交的任何工作实际执行之前返回。但是,不要错误地认为它可以自由地将工作交付给GPU。 Vulkan规范在注释中花费时间直接告诉您不要再频繁地调用该函数:

  

提交可能是高开销操作,应用程序尝试批量合作,尽可能少地调用vkQueueSubmit

在提交生成所呈现图像的CB的同一线程上呈现的原因并不是因为任何这些操作都必然很慢。这是简单的实用主义;这三个操作(获取,提交,呈现)必须按顺序发生。确保这一点的最简单,最简单的方法是在同一个线程上执行它们。

在获取交换链图像之前,您无法提交呈现给交换链图像的作品。因此,要么在同一个线程上执行,要么必须有一些线程间通信管道来告诉线程等待构建主要CB所获取的图像是什么。 这两个进程不能重叠。

与acquire不同,present是一个队列操作。 vkQueueSubmitvkQueuePresent都要求对VkQueue参数的访问权限必须是"外部同步"。这当然意味着你不能同时在同一VkQueue的不同线程上调用它们。因此,如果您尝试并行执行这些操作,则需要使用互斥锁或某些内容来同步访问VkQueue

然而,如果你在同一个帖子上进行,那就不需要了。

此外,为了呈现图像,您必须提供当前将等待的信号量。此信号量将由生成图像数据的批处理信号通知。 Vulkan要求信号量信号/等待对有序;您不能执行等待信号量的队列操作,直到提交信号表示该信号量的操作为止。因此,要么是按顺序在同一个线程上执行,要么使用一些线程间通信管道来告诉正在等待呈现呈现给它的提交操作的图像的任何线程。

那么通过将这些操作分成不同的线程可以获得什么?它们必须按顺序发生,所以你也可以按顺序执行它们存在的最简单方法:在同一个线程上。

最终,我们不清楚这项工作的重点是什么。是的,个人vkCmd*电话会很快。所以呢?在真实场景中,您将每帧调用次这些函数。将它们均匀地分布在4个核心上可以节省大约4倍的性能。