JobSystem初次見面

什麼是JobSystem

一般用unity製作遊戲,如果沒有特別去開線程的話,都是交由一個主線程去控制整個遊戲運行,但現在遊戲越做越大,不只需要性能強的設備,如果在製作遊戲上只使用主線程去做各項事情的話,負載過高也會導致FPS降低,而JobSystem目的就是可以讓設計師去使用更多的cpu的資源,來降低主線程的工作量進而讓整體遊戲效能優化。使用多線程可以讓原本擠在一起的任務分散到各個執行續上去執行,可以更有效的利用cpu的多核。

不過有一點需要注意的是,UnityAPI必須在主線程中使用。
https://blogs.unity3d.com/2018/10/22/what-is-a-job-system/

Race conditions & safety system

競爭(Race conditions)

在編寫多線程的code時,總會存在(Race condition)競爭的風險,假設現在有兩條線程:A線程和B線程,在A設定了數據,在B也設定了,而兩個線程之間對這個數據進行搶奪,就是資源競爭,這一點會讓編寫多線程的代碼變得困難。

安全系統(safety system)

而這一點Unity會幫你解決! Job System它會檢測所有潛在的競爭條件並保護你免受它們可能導致的bug。
Job System解決這個問題的方式是:如果你在主線程要丟數據給job,那就傳遞一個複製的數據過去,而不是傳遞數據的引用給Job。這個數據複製的,不管怎麼操控都不會影響到主線程的數據,所以可以避免資源競爭的問題。以這種方式複製數據意味著Job只能訪問blittable數據,而不是管理(託管)類型。這會導致很大限制,因為你不能從任務中返回任何結果,而為了解決不能返回任何結果的問題,就得需要使用到NativeContainer了!

NativeContainer

NativeContainer都受safety system保護,Unity會追蹤所有使用到NativeContainer的對象,檢查是否有錯誤(safety checks),但這僅在Editor模式跟Play模式下可以使用

而NactiveContainer包含了:
NativeArray,NativeList,NativeHashMap和NativeQueue。

NativeContainer Allocator

建立 NativeContainer時,必須指定所需的記憶體分配類型。分配類型取決於Job執行的時間長度。通過這種方式,可以定製分配器以在每種情況下獲得最佳效能。 NativeContainer記憶體分配和釋放有三種類型:

  • Allocator.Temp :有最快的記憶體分配速度,適用於分配一個生命週期只有一幀或更短時間的操作,
  • Allocator.TempJob :是相比於Temp是一個較慢的分配類型但它比Persistent要快。這是一個生命週期爲四幀的內存分配而且它是線程安全的。如果你在四幀之內沒有調用Dispose,控制台會打印一個由原生代碼生成的警告信息。絕大部分小jobs使用這種類型的NativeContainer分配器。
  • Allocator.Persistent :速度最慢,可以持續整個應用程式的生命週期,它是直接呼叫malloc的包裝器。

另外還有關於Jobsystem重要的點

C# Job System tips and troubleshooting
這個也蠻重要的,我就是說明書都沒看完就跑進去使用的那種人,結果才會跑出另外一篇Jobsystem的NativeArray效能測試XD

JobSystemNativeContainer

What is a Job System?