Multithreaded Rendering & Graphics Jobs 多线程渲染与图形Jobs 性能系列7

Multithreaded Rendering & Graphics Jobs 多线程渲染与图形Jobs 性能系列7

本文档主要是对Unity官方手册的个人理解与总结(其实以翻译记录为主:>)
仅作为个人学习使用,不得作为商业用途,欢迎转载,并请注明出处。
文章中涉及到的操作都是基于Unity2018.3版本
参考链接:https://unity3d.com/cn/learn/tutorials/topics/best-practices/multithreaded-rendering-graphics-jobs?playlist=30089

Unity supports several modes of rendering depending on platform availability and graphics API:
Unity支持多种基于平台可用性和图形API的渲染模式:

  • Singlethreaded Rendering 单线程渲染
  • Multithreaded Rendering 多线程渲染
  • Jobified Rendering Jobified 渲染
  • Graphics Jobs 图形Jobs

If you do not select one of these modes in the Player Settings, Unity uses singlethreaded rendering.
如果你没有在Player 设置中选择其中一种模式,Unity会使用单线程渲染。

Singlethreaded Rendering (single client, no worker thread)
单线程渲染(一个客户端,没有工作线程)

Unity uses singlethreaded rendering by default if none of the other modes are enabled.
如果没有其他模式可用,Unity默认情况下使用单线程渲染。
This causes the single client to occupy the main thread while executing the high-level rendering commands.
这将导致单个客户端在执行高级渲染命令时占用主线程。

The single client executes all the rendering commands (RCMD) on the main thread. The client also owns the real graphics device GfxDevice and performs the actual rendering through the underlying graphics API (GCMD) on the main thread. This is suboptimal, because all commands you execute on the main thread subtract from important frametime which you could use for other subsystems running on the main thread.
单个客户端执行主线程上的所有渲染命令(RCMD)。客户端还拥有真正的图形设备GfxDevice,并通过主线程上的底层图形API (GCMD)执行实际的渲染。这不是最优的,因为您在主线程上执行的所有命令都会从重要的frametime中减去可以用于在主线程上运行的其他子系统的frametime。
Multithreaded Rendering & Graphics Jobs 多线程渲染与图形Jobs 性能系列7
Multithreaded Rendering (single client, single worker thread)
多线程渲染(一个客户端,一个工作线程)

Unity enables Multithreaded Rendering by default if the graphics API permits it. To disable Multithreaded Rendering (generally for profiling purposes), go to the Player Settings (menu: Edit > Project Settings > Player) window, scroll down and uncheck the Multithreaded Rendering checkbox.
如果图形API允许的话,Unity默认情况下支持多线程渲染。若要禁用多线程渲染(通常用于分析目的),请转到Player Settings(菜单:Edit > Project Settings > Player)窗口,向下滚动并取消选中多线程渲染复选框。

Multithreaded rendering in Unity is implemented as a single client, single worker thread. This works by taking advantage of the abstract GfxDevice interface in Unity. The different graphics API implementations, (such as Vulkan, Metal, and GLES) inherit from the GfxDevice.
Unity中的多线程渲染是作为一个一个的客户端对应一个的工作线程来实现的。这是通过利用Unity中的抽象GfxDevice接口来实现的。不同的图形API实现(如Vulkan、Metal和GLES)继承自GfxDevice。

Renderthread 渲染线程
When you enable multithreaded rendering you can spot the GfxDeviceClient class functions in call-stacks on a native platform profiler such as XCode. In the Unity Timeline Profiler, it is called the Renderthread.
当您启用多线程渲染时,您可以在本地平台分析器(如XCode)的调用堆栈中找到GfxDeviceClient类函数。在Unity时间线分析器中,它被称为渲染线程。
Multithreaded Rendering & Graphics Jobs 多线程渲染与图形Jobs 性能系列7
The high-level rendering code of the client, which executes on the main thread, uses the renderthread.
客户端的高级渲染代码(在主线程上执行)使用渲染线程。

The single client forwards all the rendering commands (RCMD) to the renderthread - a special worker thread only for rendering - which owns the real graphics device GfxDevice and performs the actual rendering through the underlying graphics API (GCMD).
单个客户端将所有的渲染命令(RCMD)转发给渲染线程:一个只用于渲染的特殊工作线程——它拥有真正的图形设备GfxDevice,并通过底层图形API (GCMD)执行实际的渲染。
Multithreaded Rendering & Graphics Jobs 多线程渲染与图形Jobs 性能系列7
Availability 可用性

Unity enables or disables Multithreaded Rendering conditionally, depending on the graphics API and target platform. For example, on iOS, Multithreaded Rendering is always enabled when running under Metal, but OpenGLES 2.0/3.0 does not support Multithreaded Rendering and Unity executes everything on the main thread only. The following table provides an overview of what platforms and Graphics API you can enable or disable Multithreaded Rendering.
Unity可启用或禁用多线程渲染的条件,取决于图形API和目标平台。例如,在iOS上,在Metal下运行时总是可启用多线程渲染,但是OpenGLES 2.0/3.0不支持多线程渲染,Unity只在主线程上执行所有东西。下表概述了可以启用或禁用多线程呈现的平台和图形API。

Graphics API iOS Android Desktop
OpenGLES 2/3 Always off Configurable N/A
Metal Configurable N/A Configurable
Vulkan N/A Configurable Configurable

Performance Considerations 性能方面的考虑

You should enable Multithreaded Rendering whenever possible, as it usually benefits performance greatly. Tip: You should also profile the use of Multithreaded Rendering, and be aware that on very low-end devices there might be little to no benefit.
您应该尽可能地启用多线程渲染,因为它通常极大地提高了性能。提示:您还应该分析多线程渲染的使用情况,并注意在非常低端的设备上可能没有什么好处。

Profiling Multithreaded Rendering 剖析多线程渲染

Often, you need to profile Multithreaded Rendering to improve rendering performance, and it’s necessary to disable the Multithreaded Rendering setting to get correct results (see the later section on Profiling Rendering). You can also use the script-only player setting PlayerSettings.MTRendering to change Multithreaded Rendering. Alternatively, disable this in the Player Settings of the relevant platforms (see the earlier section on Availability). To disable Multithreaded Rendering in the Editor, use the following command line option: -force-gfx-direct. If you need the client device enabled (for example, to use display lists) use -force-gfx-st instead.
通常,您需要分析多线程渲染来提高渲染性能,并且有必要禁用多线程渲染设置来获得正确的结果(请参阅后面关于分析渲染的部分)。您还可以使用脚本化player 设置PlayerSettings.MTRendering调整多线程渲染。或者,在相关平台的Player 设置中禁用此功能(请参阅前面关于可用性的部分)。要在编辑器中禁用多线程渲染,请使用以下命令行选项:-force-gfx-st

Jobified Rendering (multiple clients, single worker thread)
Jobified 渲染(多客户端,一个工作线程<应该指渲染线程>)

This render mode was available in Unity 5.4, 5.5 and 5.6, but has since been replaced by Graphics Jobs.
这个渲染模式在Unity 5.4, 5.5和5.6中都可以使用,但是后来被图形作业所取代。

Multiple jobs, each of them running on its own thread, generate intermediate graphics commands (IGCMD). Afterwards, similar to Multithreaded Rendering (single client, single worker thread), a worker thread processes the buffered intermediate graphics commands and submits graphics commands (GCMD) to the real graphics device GfxDevice.
多个作业(每个作业在自己的线程上运行)生成中间图形命令(IGCMD)。然后,类似于多线程渲染(一个客户端,一个工作线程),工作线程处理缓冲的IGCMD,并将图形命令(GCMD)提交给实际图形设备GfxDevice。

These jobs have clearly defined inputs (RCMD) because they can run at the same time as user script code, which potentially changes the state of any object in the world. Jobs output commands (RCMD) to a different GfxDeviceClient per thread, and they write into their own block-allocating buffers, which the worker thread then executes.
这些作业具有明确定义的输入(RCMD),因为它们可以与用户脚本代码同时运行,这可能会改变世界上任何对象的状态。Jobs为每个线程向不同的GfxDeviceClient输出命令(RCMD),并将其写入自己的块分配缓冲区中,然后工作线程执行这些缓冲区。
Multithreaded Rendering & Graphics Jobs 多线程渲染与图形Jobs 性能系列7
Note: The worker thread does not wait until a job finishes before it starts executing its commands (IGCMD), but it always executes them in the same order they are scheduled.
注意:工作线程不会等到作业完成后才开始执行它的命令(IGCMD),但是它总是按照计划的顺序来执行。

Graphics Jobs (multiple clients, no worker thread)
图形作业(多客户端,无工作线程<应该指渲染线程>)

Unity disables Graphics Jobs by default, but you can enable them in the Player Settings. Multiple native command generation threads take advantage of the graphics APIs that support recording graphics commands (GCMD) in a native format on multiple threads. This removes the performance impact of writing and reading commands in a custom format before submitting them to the API. Similar to the other modes, Graphics Jobs generate commands by calling GfxDevice functions. However, since the devices are now platform-specific, Graphics Jobs translate the commands directly into, for example DirectX 12 or Vulkan command buffers.
Unity默认情况下禁用图形作业,但是你可以在Player 设置中启用它们。多个由本机命令生成的线程利用多个线程支持的特性以本机格式记录图形命令(GCMD)的图形api。这消除了在将命令提交给API之前以自定义格式写入和读取命令对性能的影响。与其他模式类似,图形作业通过调用GfxDevice函数生成命令。然而,由于设备现在是特定于平台的,图形作业将命令直接转换为,例如DirectX 12或Vulkan的命令缓冲区。
Multithreaded Rendering & Graphics Jobs 多线程渲染与图形Jobs 性能系列7
Note: Currently, Graphics Jobs do not have a renderthread to schedule jobs, causing a small amount of overhead on the main thread for scheduling.
注意:目前,图形作业没有用于调度作业的渲染线程,这在用于调度作业的主线程上造成了少量的开销。

Note: GPU profiling is automatically disabled when you enable Graphics Jobs.
注意:当您启用图形作业时,GPU分析将自动禁用。

Availability 可用性

Graphics Jobs are available depending on the graphics API and target platform. The following table gives an overview of the availability of Graphic Jobs on each platform and Graphics API.
图形作业取决于图形API和目标平台。下表概述了每个平台和图形API上图形作业的可用性。

Graphics API iOS Android Desktop
OpenGLES 2/3 Not Supported Not Supported N/A
Metal N/A N/A N/A
Vulkan N/A Configurable Configurable

Profiling Rendering分析渲染

When you investigate the rendering system while profiling, disable Multithreaded Rendering, Jobified Jobs, and Graphics Jobs to see the whole render queue executed on the main thread in singlethreaded rendering mode. This makes it easier to measure the timing and see the command queue easier.
在分析渲染系统时,禁用多线程渲染、Jobified作业和图形作业,以查看在主线程上以单线程渲染模式执行的整个渲染队列。这使得测量时间和查看命令队列变得更容易。

Note: When you run in singlethreaded rendering mode to execute everything on the main thread, you get different timing, because the overhead of managing the other modes doesn’t appear in the profiler.
注意:当您以单线程渲染模式运行以执行主线程上的所有内容时,您会得到不同的计时,因为管理其他模式的开销不会出现在分析器中。

GfxThreadableDevice Functions

When you look at GfxDeviceClient functions in a native call stack while profiling, it often adds extra virtual functions from the GfxThreadableDevices class.
在分析本机调用堆栈中的GfxDeviceClient函数时,通常会从GfxThreadableDevices类中添加额外的虚拟函数。

These extra functions are variations of the GfxDevice functions that take data that isn’t thread-safe (for example, ShaderLab::PropertySheet) and convert them to data that is thread-safe. When you call SetShaders() in Multithreaded Rendering, the main thread takes a ShaderLab::PropertySheet and turns it into plain serialized data that GfxDevice feeds to SetShadersThreadable() on the renderthread. When you investigate shader performance, measure the timing of the SetShadersThreadable() method to gain information on how long it takes to set actual shaders and compare them to their non-threaded equivalent.
这些额外的函数是GfxDevice函数的变体,这些函数获取非线程安全的数据(例如,ShaderLab::PropertySheet),并将它们转换为线程安全的数据。在多线程渲染中调用SetShaders()时,主线程获取ShaderLab::PropertySheet并将其转换为普通的序列化数据,GfxDevice将这些数据提供给渲染线程上的SetShadersThreadable()。在研究着色器性能时,测量SetShadersThreadable()方法的计时,以获得关于设置实际着色器所需的时间的信息,并将其与非线程进行比较。

上一篇:【翻译自mos文章】DBA_JOBS 和 DBA_JOBS_RUNNING 不同的结果的解释


下一篇:Java并发编程之闭锁与栅栏