前言
創建一個Job,使用NativeArray儲存一個整數,然後呼叫了1億次加法,發現對比於使用int來呼叫1億次,相差了10倍左右,呼叫1億次加法大概花了600毫秒,但是使用NativeArray來算1億次加法會花大概6000毫秒,於是就有個疑問了 – NativeArray呼叫太多次是不是會造成cpu處理過大?
結論
Editor模式中,NativeContainer會有Safety check,但在建置完後的程式是沒有Safety check的,所以!!! 在Editor模式如果呼叫了過多次NativeContainer造成遊戲之中有延遲,很有可能是因為Safety check造成的,實際上性能消耗還是build出來測試會比較準確!
測試幾種可能
1. 在Job中int計算1億次
先創建一個Job,用它來計算一般用int的性能消耗
1 | public struct OnlyCalculateJob : IJob |
並在Start時呼叫
1 | private void Start() |
可以看到大約消耗了600毫秒
2. 在Start中int計算1億次
1 | private void Start() |
也是差不多600毫秒 ((這個測試好像沒什麼意義XD))
3. NativeArray< int> 執行一億次
1 | private void Start() |
這個就有差了,整整會卡住七秒左右
這邊推論應該是NativeArray造成的,測看看如果減少NativeArray次數,試試看會不會減少處理速度!
3.使用另外一個int運算,再將結果丟給NativeArray
1 | public struct NativeCalculateJob : IJob |
這邊比上面第2點還少呼叫了一次NativeArray,所以如果處理速度增加,那應該很確定是NativeArray造成的了
花了3800毫秒,看來的確是少差不多一半,那現在如果增加呼叫NativeArray的次數,那應該時間也會加倍吧?!
4. 增加NativeArray呼叫次數試試看
1 | public struct NativeCalculateJob : IJob |
超級沒意義的增加XD
而結果果然處理速度也是倍增
花了將近10秒!!!
測試到這邊的時候,我以為結論是NativeArray要小心地增加他的呼叫次數,不能像上面那樣隨意的亂放((一般也不會有人這樣寫)),然後想來想去都覺得不對,就去查詢了一下為什麼NativeArray會消耗這麼多性能,才發現!!!
其實並不是NativeArray會消耗很多性能,而是在編輯器(Editor)模式下,會有Safety checks,一種安全檢查,他會消耗很多效能,但在build出來後會disable掉這個safety checks.
Safety checks in the editor have a significant performance cost.
The safety checks are disabled in the standalone player completely and in IL2CPP there is a fast path making builtin arrays and NativeArrays equally fast.
The real performance gains of NativeArray are leveraged from the burst compiler, when writing primarily jobified code with the [ComputeOptimization] attribute. We expect that for any code that is performance sensitive that developers will write it to run in a job in burst.
In burst the speed gains from using NativeArray are very significant. Usually on the order of 5-15x compared to il2cpp / mono.
因此我就又測試了一下,同樣一段CODE,在編輯器模式跟在Android裝置上測出來的性能
放在編輯器下
放在android裝置下
有興趣的可以看下方連結
How NativeContainer are so fast even it is allocated in every frame?
NativeArray vs DynamicBuffer : Which access data faster?
Why am I not seeing a performance increase with the Job System?
Job System not as fast as mine, why not?
Native Arrays approximately an order of magnitude slower than arrays