Vulkan 多线程综述

大家好,接下来将为大家介绍Vulkan 多线程综述。

一、Vulkan多线程支持

Vulkan多线程支持示意图如下图所示:

        Vulkan作为一个直接提供GPU硬件功能的接口,而不再负责多线程渲染的调度,以及线程并发访问的安全保护等工作,这意味着Vulkan接口内部不再像OpenGL ES一样有过度的线程同步,CPU/GPU之间的同步等操作。这些操作会为渲染接口的运行效率带来不可预测的影响。

        如上图所示,每个独立的CPU线程都可以并行地生成请求渲染的command buffer,这些command buffer最后会被提交给一个统一的command queue,GPU会按照command buffer提交的先后顺序来执行。任何需要跨线程访问的资源,都需要开发者自己在应用层面保证访问的一致性。

二、Vulkan多线程释义

1、Vulkan基于Queue的API设计对多线程非常友好,同时也提供了多种Synchronization的方法。常见的并行方法有两种。

        第一种是在CPU端并行的更新一些Buffer中的数据。这里要注意的是,多线程的情况下更新资源要保证安全。如果你的程序渲染的非常高效,通常在CPU端会同时有好几帧的数据要处理。所以程序会可以Round Robin的方法更新并且使用这些资源。这个时候要是别的线程写的前面某一帧还没有被读取完的数据则会造成错误。Vulkan的Event可以被插入在Command Buffer中,在使用指定资源的调用后面。这样App回一直等到SetEvent被调用之后才会更新指定的资源。
        另一种并行的方式带来的性能提升更加显著,尤其是在渲染非常复杂的场景的时候。这也是Vulkan相比传统API最能体现提高的情况。那就是并行的在不同线程上生成场景不同部分的渲染任务,并且生成自己的Command Buffer,不用任何线程间的Synchronization。最后,不同的线程可以将Command Buffer的Handle传给主线程然后由主线程将它们写入Queue中,也可以直接写入子线程中的per-thread Queue递交给GPU。不过Queue的任务递交时间并不是完全可以忽略的,所以这里还是建议将Command传给主线程一起递交。这样的模式达到了计算资源利用的最大化,多个CPU核都参与了场景的渲染,并且有大量的渲染任务同时递交给GPU最大化了GPU的吞吐量。下图说明了这种模式。

        最后值得注意的是, Queue,是Vulkan中唯一给GPU递交任务的渠道。Vulkan将Queue设计成了完全透明的对象,所以在驱动里没有任何其他的隐藏Queue,也不会有任何的Synchronization发生。在Vulkan中,给GPU递交任务不再依赖于任何所谓的绑定在单一线程上的Context,Queue的API极其简单,你向它递交任务(Command Buffer),然后如果有需要的话,你可以等待当前Queue中的任务完成。这些Synchronization操作是由Vulkan提供的各种同步组件完成的。例如Samaphore可以让你同步Queue内部的任务,程序无法干预。Fence和Event则可以让程序知道某个Queue中指定的任务已经完成。所有这些组件组合起来,使得基于Command Buffer和Queue递交任务的Vulkan非常易于编写多线程程序。Queue不光接收图形渲染的调用,也接受计算调用和内存操作。

发布了57 篇原创文章 · 获赞 66 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/u010281924/article/details/105378580