Unity-NativeContainer 官方文檔譯文

NativeContainer(本地容器)

Unity Safety system(安全系統)數據拷貝的缺點之一,是將每個Job的計算結果也相互隔離,爲了解決這個限制,需要將Job結果存儲在一種共享內存類型的容器NativeContainer。


 

什麼是NativeContainer?

NativeContainer是一個對Unity本地內存進行相對安全的封裝並且接受管理的值類型。在使用Unity JobSystem時,NativeContainer允許job和主線程訪問共享內存,而不是通過內存拷貝。


 

有哪些NativeContainer可以用?

Unity提供了一個NativeContainer叫做NativeArray,你可以通過NativeSlice從特定位置開始操作固定長度操作NativeArray的數據子集。

注意:Unity ECS系統拓展了Unity.Collection命名空間下的NativeContainer類型:
        *    NativeList - 可變長度的NativeArray
        *    NativeHashMap - 鍵值對
        *    NativeMultiHashMap - 一鍵多值的哈希表
        *    NativeQueue    - 先入先出列表


NativeContainer和Safety System之間的關係

SF是在所有NativeContainer類型中內置的,它追蹤了是誰在讀寫NativeContainer。
注意:
    所有NativeContainer的安全類型檢查(如:越界檢查、釋放檢查、依賴檢查),都只在Editor和PlayMode下有效。

SF中的部分概念DisposeSentinel和AtomicSafetyHandle

*    DisposeSentinel可能會在內存泄露後很久,纔會觸發並給出內存泄漏的錯誤日誌

*    在代碼中使用AtomicSafetyHandle移交NativeContainer的權限, 比如:如果兩個Job同時寫入NativeArray,SF在你調度Job的時候就會拋出清晰的異常日誌來告訴你怎麼去解決這個問題。因此你可以根據Job的依賴關係來調度,在第一個job完成nativeContainer的寫入之後,第二個Job可以安全的讀寫同一個NativeCondition,當然主線程讀寫的時候一樣需要嚴格限制。SF也允許多個並行Job的讀取同一個數據。

一個Job在默認情況下擁有NativeContainer的讀寫權限,這有可能會拖累性能表現,C# 的SF不允許一個Job在另一個Job寫入數據的時候擁有寫入權限,如果不需要寫入權限,可以在NativeContainer上添加[ReadOnly]標籤,比如:
    [ReadOnly]
    public NativeArray<int> input;
這樣其他Job就可以在當前job執行的時候,獲得NativeArray的只讀權限

注意:在訪問靜態數據的時候是不會有SF的安全保護的,靜態數據繞過了所有的SF,因此可能導致Unity崩潰。


NativeContainer 的分配

*    Allocator.Temp 分配速度最快,試用於生命週期在一幀以內的job,你需要在方法結束之前調用Dispose方法
*    Allocator.TempJob 分配速度比Temp慢,但是比Persistent快,適用於生命週期在四幀以內的Job,是線程安全的,如果你沒有手動調用Dispose方法,會在四幀之後輸出一條警告日誌,大部分小Job會採用這種類型

*    Allocator.Persistent 分配速遞最慢,但是可以存在任意長的時間,必要的話可以貫穿整個應用的生命週期。本質上是malloc的直接封裝,其他更長的Job可以用這種類型,當然性能有壓力的時候,還是不要使用


如有錯誤,歡迎指正!

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