Multithreaded Rendering & Graphics Jobs 多線程渲染與圖形Jobs 性能系列8

Multithreaded Rendering & Graphics Jobs 多線程渲染與圖形Jobs

本文檔主要是對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 (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時間線分析器中,它被稱爲渲染線程。
在這裏插入圖片描述
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)執行實際的渲染。
在這裏插入圖片描述
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),並將其寫入自己的塊分配緩衝區中,然後工作線程執行這些緩衝區。
在這裏插入圖片描述
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的命令緩衝區。
在這裏插入圖片描述
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()方法的計時,以獲得關於設置實際着色器所需的時間的信息,並將其與非線程進行比較。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章