vulkan之同步


两个level的同步:within a single queue和across multiple queues

单个device queue内的同步

vulkan允许我们发送cmdbuffer到queue中,去处理graphics 操作。这个进程被设计成线程友好的,这样我们就可以使用来自任何CPU thread 的cmd buffer提交工作,并最终将它们insert到同一个GPU queue中。这使我们能够在Vulkan运行其命令(通常也是并行的)时执行自己的多线程,计算vetices或加载纹理以最大限度地利用所有CPU核。

请注意,即使在同一queue中,我们的命令也可能依赖于其他命令的完成,它们不需要在同一个cmdbuffer中。命令保证按插入的确切顺序start,但由于它们并行运行,因此不能保证命令按相同的顺序完成。

确保这些cmd正确等待的in-queue工具有:pipeline barriers,events,subpass dependencies;


Barriers

管道障碍指定要等待的数据或渲染管道的哪个阶段,以及要阻止哪个阶段,直到上一个命令中的其他指定阶段完成。

请记住,这些barriers只用于GPU,所以我们无法从在cpu上运行的程序来check when a barrier has been executed;如果我们需要向CPU上的应用程序发回信号,那么可以使用另一个称为fence或event的工具(后面介绍)

两种barriers:

  • 执行barriers(execution)
  • 内存barriers(memory)

我们可以在a single call中创建一个execution barrier,或者一个execution barrier和一个或多个类型的memory barrier;

在这里插入图片描述


execution barriers

当我们想要控制命令流并使用pipeline barriers来强制执行命令(execution)的顺序时,我们可以在Vulkan操作命令之间插入一个barrier,并指定prerequisite 管道阶段,在此期间,前面的cmd需要在继续之前完成。我们还可以指定在此barrier之后应保持的管道阶段。

这些选项是使用vkCmdPipelineBarriersrcStageMask(barrier的等待阶段)和dstStageMask(之后阶段)参数设置的。因为它们是位标志bit flags,所以我们可以在这些mask中指定多个阶段。srcStageMask在允许dstStageMask中给定的阶段在后续命令中执行之前,标记要在前面的命令等待的阶段。

对于execution barriers,srcStageMask被扩展为包含逻辑上earlier的stages。类似的,dstStageMask被扩展以包括逻辑上later的stages。在dstStageMask(以及之后)的阶段将等待srcStageMask(以及之前)的阶段完成后,才开始。这足以保护srcstagemak中的stage读取访问和dststagemak中的stage写入访问。

为了避免a common pitfall(陷阱),请注意,stage mask扩展不适用于下面定义的memory barrier。


Memory Barriers

为了提高引擎盖(hood)下的性能,Vulkan在CPU和GPU内核上的快速一级/二级缓存内存和相对较慢的主RAM内存之间使用了一系列缓存机制。

当一个内核写入内存(例如,写入渲染目标RT)时,更新仍然只能存在于缓存中,并且对于准备使用它的另一个核心不可用或不可见。

(之后学到了进行补充)

execution和memory dependency

我们可能需要设置pipeline barrier的一种情况是,在compute shader中写入纹理图像buffer,然后在片段着色器中使用它。

(之后补充)

Events

subpass denpendencies

在设备队列中进行同步的另一种方法是通过subpass依赖关系。这和pipeline barriers很像,但专门用于表示呈现子过程之间的依赖关系,以及renderpass实例内的cmd与实例外的cmd之间的依赖关系(在之前或之后)。

这些可能be a bit tricky(有些棘手),因为它们有很多限制。但是,如果我们在渲染过程中处理数据,比如渲染阴影或反射,或者需要等待外部资源或事件,它们会come in handy(派上用场)。

使用subpass denpendencies,需要注意:

  • 对于使用srcAccessMasksrcAccessMask 指定的附件,它们只包含一个memory barrier
  • subpass可以使用管道阶段标志srcStageMaskdstStageMask等待完成。
  • 它们只能向前推进,subpass可以在早期阶段或同一阶段wait,但不能依赖于同一渲染过程中的后期阶段。

多个device queue间的同步

现在我们已经介绍了一些在单个设备队列中设置依赖项的机制,让我们看看如何在不同的队列之间协调同步。

使用:信号量fence

请注意,vulkan1.2引入了timeline信号量,这是未来信号量的新的首选方法。它们还没有在移动设备上广泛使用,所以我们将首先讨论原始的方法,然后看看新的时间轴信号量如何能够取代这两个原始选项。

信号量

理解和使用信号量的关键在于认识到它们只用于在GPU任务之间跨多个queue进行同步(graphics和present),而不用于在GPU和CPU任务之间进行同步。

如果多个命令正忙于跨核心和线程处理它们的任务,那么一个信号量就像一组命令已经完成的公告。信号量只有在批处理batch中的所有命令完成后才发出信号。

它们保证了implict memory guarantees,所以我们可以访问信号量后面的任何内存,而不需要考虑在它们之间添加memory barrier。

Fences

fence是为GPU到CPU的同步而设计的。
fence可以附加到queue submission,并允许应用程序使用vkGetFenceStatus检查fence状态,或使用vkWaitForFences等待队列完成。

Fences make the same implicit memory guarantee as semaphores, and if we want to present the next frame in a swap buffer, we can use fences to know when to swap and start the render of the next frame.

原文链接:
https://www.khronos.org/blog/understanding-vulkan-synchronization

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值