Vulkan与OpenGL的对比

Vulkan与OpenGL的对比,Vulkan相比OpenGL有了不少的新特性和性能提升,如下所示:

  • 降低驱动负载和CPU的使用量:Vulkan在设计上更为接近于底层的图形硬件。因此,它可以向应用程序的开发者提供更为直接的控制权力,来操作宿主机上的计算资源,使用GPU来尽可能高效地完成渲染工作。这一特性使得相关软件可以直接访问图形处理器,从而达到更好的性能要求。

  • 多线程的可扩展性:OpenGL中的多线程扩展能力是非常有限的,所以很难利用多线程的各种优势来管理CPU资源。不过,Vulkan在设计时特别考虑了终端用户对于多线程功能的迫切需求,并且通过非常透明的方式予以支持(并不会隐含任何的全局状态变化)。不同线程下的任务、任务的创建过程,以及任务提交执行的过程之间都是完全独立的,不存在数据耦合。

  • 显式的API定义:OpenGL的API是隐式的,资源管理的工作交给驱动层去完成。驱动层负责读取应用程序端的提示参数并跟踪资源的处理,这样带来了很多不必要的负担。

  • Vulkan采用了显式的API定义,驱动并不负责资源以及资源之间相互关系的管理。这些工作由应用程序处理。这种清晰的实现方式更容易预测,驱动层也不需要在用户场景的后面偷偷做资源管理的小动作了(这正是OpenGL的弊端)。这样的结果是,用户任务的处理可以直截了当地以流水线的方式完成,从而获得最佳性能和可预测的行为模式。

  • 预编译的中间级着色语言:OpenGL需要使用OpenGL着色语言(GLSL)源代码的形式来实现着色器,而Vulkan使用可移植的标准化中间级语言(SPIR-V)作为中间级语言标准,为并行计算和图形处理提供了着色器支持。

其他源代码语言的编译器(例如GLSL、HLSL或者LLVM)必须将SPIR-V作为输出的目标语言,并且提供工具来实现SPIR-V输入数据的支持。Vulkan可以读取这种能够马上执行的二进制中间数据,并且在着色器执行阶段直接使用。

  • 驱动层和应用程序层:OpenGL中的应用程序层相比驱动层而言要单薄得多,因为驱动层会自动完成资源管理和状态跟踪的工作。Vulkan与之相反。它的驱动层更为接近硬件底层,负载较小。而应用程序层需要负责逻辑、资源和状态的管理。下图给出了这两个API各自的驱动层和应用程序层代码的总量对比。

Vulkan与OpenGL的对比

  • 内存的控制:Vulkan暴露了系统当中的多种不同类型的内存接口,交由应用开发者去选择适合自己的内存类型,实现各种资源的管理和使用。与之相反,OpenGL是通过驱动层的内部处理机制来完成资源存储的,不同的供应商可能因此有完全不同的实现,并且当驱动层改变了资源的存储位置时。很可能产生预期之外的内存碎片,或者降低存储效率。

  • 可预测行为:Vulkan与OpenGL相比,其行为具有很高的可预测性,它不会在渲染时产生任何延迟或者抖动。用户任务传递到驱动层之后会被立即提交,而OpenGL的任务提交过程不是立即完成的,它需要等待驱动层再去进行调度。

  • 单一的API:OpenGL有多个独立的版本,包括桌面端的API(OpenGL)和嵌入式系统的API(OpenGL ES)。Vulkan相比之下更为清晰,它只提供了单一的API接口来面对所有类型的系统平台。Vulkan会优先支持移动平台,这一点与OpenGL也是不一样的。OpenGL通常会优先实现某个功能的桌面端版本,然后再将它更新到OpenGL ES API当中。

  • 直接访问GPU:Vulkan暴露了自己的底层功能和硬件特性,从而给应用层用户提供了大量的控制手段。它提供了多种不同类型的物理设备、内存类型、指令缓存队列,以及功能扩展。这样的模式确保软件层更接近实际硬件的特性。

  • 错误检查和验证:我们使用OpenGL进行开发的时候,即使已经实现了非常优化的应用程序,本身运行时不会有任何错误发生,我们也依然需要强制进行错误检查并有所损耗。与之对应的是,Vulkan通过插件服务的形式提供了错误检查和验证的支持,因此可以根据实际需要随时开启或者关闭。这样的检查是可选的,可以在程序运行时再开启错误检查和验证功能。由于避免了非必需的检查过程,因此CPU的负载也就更低。事实上,在理想状态下,错误检查和验证功能只需要在开发阶段启用,从而完成功能的调试;而程序发布之后该功能即可关闭。

  • 支持多种类型的GPU硬件:Vulkan已经将移动端和桌面端的光栅化操作集成到自己的实现当中。它也可以在嵌入式系统上支持基于瓦片的光栅化或者延迟渲染光栅化,同时也支持基于瓦片的本地前向渲染光栅化操作。

赞(12)

评论 抢沙发

评论前必须登录!