Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.
C#JobSystem & ECSでCPUを極限まで
使い倒そう
~C# JobSystem編~
2018/4/21
講演者名 黒河 優介
所属団体 Unity Technologies Japan
肩書・役職 Developer Relati...
• Unity
4
• Native Container
• 5.6 2018.1β
• C# JobSystem
• 2018.1 β
• Entity Conponent System(ECS)
• 2018.1.0 Experimenta...
• Unity
4
• Native Container
• 5.6 2018.1β
• C# JobSystem
• 2018.1 β
• Entity Conponent System(ECS)
• 2018.1β
• Burst Comp...
Unity
• GC
• C#
• Thread C# MainThread
NativeContainer
• GC
• new
• C#
•
GC
ManagedMemory
アプリで使用している全体メモリ
UnityメモリC#用に確保したメモリ
C#使用メモリ 未使用
NativeContainer
GC Memory
NativeContainer
• GC NativeArray
• Allocate Dispose(C++ new delete )
• JobSystem/ECS
• unsafe C#
NativeContainer
// Vector3 NativeArray
NativeArray<Vector3>array = new NativeArray<Vector3>(size, Allocator.Persistent);
/...
NativeContainer
int や float 等のプリミティブなタイプか、
Vector3等のstruct型のみが指定可能です。
class型は指定不可です
// Vector3 NativeArray
NativeArray<Vec...
// Vector3 NativeArray
NativeArray<Vector3>array = new NativeArray<Vector3>(size, Allocator.Persistent);
//
for( int i = 0...
NativeContainer
• 2018.1.0b
• NativeArray
• NativeSlice ( NativeArray )
•
• NativeList
• NativeHashMap
• NativeMultiHashMa...
NativeContainer
Memory Leak
MemoryLeak
• Dispose
• Editor
•
C# JobSystem
• Thread C# MainThread
• Unity WorkerThread
C#
Thread (1)
C#スクリプトの処理は基本的に
MainThread上で実行されます
Thread (2)
UnityではMainThreadだけが働いていて、
Worker ThreadはIdle状態になってしまい
何も仕事をしていない状態がよくあります
C# JobSystem
WorkerThread
C# JobSystem
• WorkerThread C# C#
WorkerThread
• C# Job
WorkerThread
• MainThread
UnityAPI
C# JobSystem
Idle状態で遊んでいたWorker ThreadにもC#スクリプト処理を
分担させることで全体の負荷を下げる事につながります
C# JobSystem
• 1
•
•
•
•
→ C# Thread
C# JobSystem
• C# Heap
• NativeContainer struct
• Unity API
• Math JobSystem API
Job
• 3 Job Unity
• IJob
• IJobParalellFor
• Transform
IJobParallelForTransform
IJob(1)
// Jobの定義部分
struct MyJob : IJob{
// Jobに渡したいパラメーター
public int param;
// 実際に実行する処理
public void Execute( ){
int sum ...
Jobを定義するには、structを作成します。
Job実行に必要なデータをメンバーに持たせます。
メンバーはint/float等のプリミティブな型もしくはstruct/
NativeArrayしか持てません。UnityEngine.Objec...
structをnewして、Schedule()メソッドを呼び出すこと
で、Jobの発行が出来ます。
Scheduleからの返り値のJobHandleオブジェクトで発
行したJobを待たせることが出来ます
IJob(2)
// Jobの定義部分
...
IJobParalellFor
NativeArray<Vector3 >position
[0]
( 0, 0, 10 )
[1]
( 0, 0, 20 )
[2]
( 0, 0, 30 )
[3]
( 0, 0, 40 )
[4]
( 0,...
MainThread
position [ 0~10 ]の更新処理
Worker position [ 11~20 ]の更新処理
Worker position [ 21~30 ]の更新処理
Jobの発行及び完了待ち
分散後
MainThrea...
// Jobの定義部分
struct MyPositionUpdate : IJobParallelFor{
// 更新対象をNativeArrayの形で保持します
public NativeArray<Vector3> positions;
...
// Jobの定義部分
struct MyPositionUpdate : IJobParallelFor{
// 更新対象をNativeArrayの形で保持します
public NativeArray<Vector3> positions;
...
// Jobの定義部分
struct MyPositionUpdate : IJobParallelFor{
// 更新対象をNativeArrayの形で保持します
public NativeArray<Vector3> positions;
...
複数のTransformに対して並行して処理を行うための
IJobParallelForTransform
IJobParallelForTransformを利用することで、このCubeの移
動や回転をWorkerThreadでもできるようにな...
// Jobの定義部分
struct MyTransformUpdateJob : IJobParallelForTransform{
// Jobに渡したいパラメーター
public int objNum;
public float time...
// MonoBehaviourのUpdate内等で実際にJobを発行するところ
Transform[] transformArray = "xxx";
// 並行して処理をしたいTransformのリストを定義します
var transfor...
Job API
• JobSystem API
• Raycast Job RayCastCommand
• NaviMesh Job NavMeshQuery
C JobSystem
https://github.com/wotakuro/UnityJobSystemTest
こちらで計測。GPU・通信の影響を抑えるため、機内モード/画面輝度最低固定、ゲームのFPSを10固定
にし、CPUでのバッテリー消費が顕著に出る環境に...
C# JobSystem
C# JobSystem
Q Job Priority( )
A Priority Job
Job B Job A Job B Job A
WorkerThread
WorkerThread
WorkerThreadの数はプラットフォーム・マシンの
ハードウェアによって変わってきます。
多くのプラットフォームでは、コア数 – 1 だけ
WorkerThreadに割り当てされます
Job
Job
Job.Schedule時に、InvalidOperationException等が出てしまうことがあります。
これはJobの実行タイミングで結果が異なりうる時にエラーとなってしまう可
能性があるのをUnityEditorが察知してエラ...
Job
Worker
Job A
NativeArray<Vector3 >positions
[0]
( 0, 0, 10 )
[1]
( 0, 0, 20 )
[2]
( 0, 0, 30 )
[3]
( 0, 0, 40 )
[4]
( ...
Job
Worker
Job A
NativeArray<Vector3 >positions
[0]
( 0, 0, 10 )
[1]
( 0, 0, 20 )
[2]
( 0, 0, 30 )
[3]
( 0, 0, 40 )
[4]
( ...
Job
Worker
Job A
NativeArray<Vector3 >positions
[0]
( 0, 0, 10 )
[1]
( 0, 0, 20 )
[2]
( 0, 0, 30 )
[3]
( 0, 0, 40 )
[4]
( ...
IJobParallelFor
Job.Schedule実行中に IndexOutOfRangeExceptionが出てきました。
しかし配列外のアクセスには心当たりがありません…。
とりあえず、ソースコードを見てみましょう…
IJobParallelFor
// Jobの定義部分
struct MyPositionUpdate : IJobParallelFor{
// 更新対象をNativeArrayの形で保持します
public NativeArray<Vect...
IJobParallelFor
// Jobの定義部分
struct MyPositionUpdate : IJobParallelFor{
// 更新対象をNativeArrayの形で保持します
public NativeArray<Vect...
IJobParallelFor
// Jobの定義部分
struct MyPositionUpdate : IJobParallelFor{
// 更新対象をNativeArrayの形で保持します
public NativeArray<Vect...
C# JobSystem
Update
class JobTest : MonoBehaviour{
privateJobHandlehandle;
public Transform[] transformArray;
void Update(){
//前のフレームで発...
Update
MainThread
Job更新処理
Worker Jobの更新処理
Jobの発行及び完了待ち エンジン側での描画等の更新処理
EngineのJob
EngineのJob
Worker Jobの更新処理 EngineのJob
Ma...
Work1.IJob Work2.IJobParallelFor
Work3.IJobParallelForTransform Work4.RayCastCommand
【Unite Tokyo 2018 Training Day】C#JobSystem & ECSでCPUを極限まで使い倒そう ~C# JobSystem 編~
Prochain SlideShare
Chargement dans…5
×

【Unite Tokyo 2018 Training Day】C#JobSystem & ECSでCPUを極限まで使い倒そう ~C# JobSystem 編~

15 133 vues

Publié le

Unite Tokyo 2018 Training Day「C#JobSystem & ECSでCPUを極限まで使い倒そう ~C# JobSystem 編~」の資料です。

講師:黒河 優介(ディベロッパーリレーションエンジニア|ユニティ・テクノロジーズ・ジャパン合同会社)

※【Unite Tokyo 2018 Training Day】C#JobSystem & ECSでCPUを極限まで使い倒そう ~Entity Component System 編~ の資料はこちら
https://www.slideshare.net/UnityTechnologiesJapan/unite-tokyo-2018-training-daycjobsystem-ecscpu-entity-component-system-1

■ワークショップで利用したUnityプロジェクト
https://wotakuro.github.io/JobSystemWorkshop/JobSystemWorkshop.zip

■ワークショップ内容
C# Job System、ECS(Entity Component System)がUnity2018で使えるようになりました。

C# Job SystemはUnityのシステムと親和性が高く、安全なマルチスレッドプログラミングを容易にする新機能です。ECSは非常に高速な、新しいオブジェクトの管理システムです。この二つを組み合わせて、CPUのパワーを非常に効率よく利用することができます。

※このセッションは、受講者がUnity上での基本的なC#プログラミング・マルチスレッドプログラミングに関する基本的な知識を持っている前提で行います。

※ECSは現在ベータ段階で今後も調整、変更が重ねられる予定です。

Publié dans : Technologie
  • Visit this site: tinyurl.com/sexinarea and find sex in your area for one night)) You can find me on this site too)
       Répondre 
    Voulez-vous vraiment ?  Oui  Non
    Votre message apparaîtra ici
  • Sex in your area for one night is there tinyurl.com/hotsexinarea Copy and paste link in your browser to visit a site)
       Répondre 
    Voulez-vous vraiment ?  Oui  Non
    Votre message apparaîtra ici
  • Girls for sex are waiting for you https://bit.ly/2TQ8UAY
       Répondre 
    Voulez-vous vraiment ?  Oui  Non
    Votre message apparaîtra ici
  • Meetings for sex in your area are there: https://bit.ly/2TQ8UAY
       Répondre 
    Voulez-vous vraiment ?  Oui  Non
    Votre message apparaîtra ici
  • Best site for flirting and sex in your area you can find there: https://bit.ly/2SlcOnO
       Répondre 
    Voulez-vous vraiment ?  Oui  Non
    Votre message apparaîtra ici

【Unite Tokyo 2018 Training Day】C#JobSystem & ECSでCPUを極限まで使い倒そう ~C# JobSystem 編~

  1. 1. C#JobSystem & ECSでCPUを極限まで 使い倒そう ~C# JobSystem編~ 2018/4/21 講演者名 黒河 優介 所属団体 Unity Technologies Japan 肩書・役職 Developer Relation Engineer
  2. 2. • Unity 4 • Native Container • 5.6 2018.1β • C# JobSystem • 2018.1 β • Entity Conponent System(ECS) • 2018.1.0 Experimental( ) • Burst Compiler • 2018.1.0 Experimental( )
  3. 3. • Unity 4 • Native Container • 5.6 2018.1β • C# JobSystem • 2018.1 β • Entity Conponent System(ECS) • 2018.1β • Burst Compiler • 2018.1β 私からの話はコチラになります。
  4. 4. Unity • GC • C# • Thread C# MainThread
  5. 5. NativeContainer • GC • new • C# •
  6. 6. GC
  7. 7. ManagedMemory アプリで使用している全体メモリ UnityメモリC#用に確保したメモリ C#使用メモリ 未使用
  8. 8. NativeContainer GC Memory
  9. 9. NativeContainer • GC NativeArray • Allocate Dispose(C++ new delete ) • JobSystem/ECS • unsafe C#
  10. 10. NativeContainer // Vector3 NativeArray NativeArray<Vector3>array = new NativeArray<Vector3>(size, Allocator.Persistent); // for( int i = 0; i < array.Length; ++i ){ array[ i ] = array[i] + Vector3.one; } // array.Dispose();
  11. 11. NativeContainer int や float 等のプリミティブなタイプか、 Vector3等のstruct型のみが指定可能です。 class型は指定不可です // Vector3 NativeArray NativeArray<Vector3>array = new NativeArray<Vector3>(size, Allocator.Persistent); // for( int i = 0; i < array.Length; ++i ){ array[ i ] = array[i] + Vector3.one; } // array.Dispose();
  12. 12. // Vector3 NativeArray NativeArray<Vector3>array = new NativeArray<Vector3>(size, Allocator.Persistent); // for( int i = 0; i < array.Length; ++i ){ array[ i ] = array[i] + Vector3.one; } // array.Dispose(); NativeContainer メモリの生存期間に合わせて、以下の三つの中から選択可能です。 Allocator.Temp ( そのフレームのみ有効) Allocator.TempForJob(そのJob中のみ有効) Allocator.Persistent(解放するまで有効) 下に行くほど、メモリ確保のコストが高くなります。
  13. 13. NativeContainer • 2018.1.0b • NativeArray • NativeSlice ( NativeArray ) • • NativeList • NativeHashMap • NativeMultiHashMap • NativeQueue ※ NativeContainer 自体は、unsafeなC#で書かれているため、 コンテナを新規に定義することも可能
  14. 14. NativeContainer Memory Leak
  15. 15. MemoryLeak • Dispose • Editor •
  16. 16. C# JobSystem • Thread C# MainThread • Unity WorkerThread C#
  17. 17. Thread (1) C#スクリプトの処理は基本的に MainThread上で実行されます
  18. 18. Thread (2) UnityではMainThreadだけが働いていて、 Worker ThreadはIdle状態になってしまい 何も仕事をしていない状態がよくあります
  19. 19. C# JobSystem WorkerThread
  20. 20. C# JobSystem • WorkerThread C# C# WorkerThread • C# Job WorkerThread • MainThread UnityAPI
  21. 21. C# JobSystem Idle状態で遊んでいたWorker ThreadにもC#スクリプト処理を 分担させることで全体の負荷を下げる事につながります
  22. 22. C# JobSystem • 1 • • • • → C# Thread
  23. 23. C# JobSystem • C# Heap • NativeContainer struct • Unity API • Math JobSystem API
  24. 24. Job • 3 Job Unity • IJob • IJobParalellFor • Transform IJobParallelForTransform
  25. 25. IJob(1) // Jobの定義部分 struct MyJob : IJob{ // Jobに渡したいパラメーター public int param; // 実際に実行する処理 public void Execute( ){ int sum = 0; for( int i = 0 ; i < param ; ++ i){ sum += i ; } Debug.Log( “sum “ + sum ); } } // MonoBehaviourのUpdate内等で実際にJobを発行するところ // Jobを作成します var job = new MyJob(){ param = 100 }; // Jobを発行してます JobHandlehandle= job.Schedule(); // 発行したJobが完了するのを待ちます handle.Complete();
  26. 26. Jobを定義するには、structを作成します。 Job実行に必要なデータをメンバーに持たせます。 メンバーはint/float等のプリミティブな型もしくはstruct/ NativeArrayしか持てません。UnityEngine.Objectのような参照型のメ ンバーは持つことが出来ません 実行そのものはExecuteメソッドに記述します IJob(1) // Jobの定義部分 struct MyJob : IJob{ // Jobに渡したいパラメーター public int param; // 実際に実行する処理 public void Execute( ){ int sum = 0; for( int i = 0 ; i < param ; ++ i){ sum += i ; } Debug.Log( “sum “ + sum ); } } // MonoBehaviourのUpdate内等で実際にJobを発行するところ // Jobを作成します var job = new MyJob(){ param = 100 }; // Jobを発行してます JobHandlehandle= job.Schedule(); // 発行したJobが完了するのを待ちます handle.Complete();
  27. 27. structをnewして、Schedule()メソッドを呼び出すこと で、Jobの発行が出来ます。 Scheduleからの返り値のJobHandleオブジェクトで発 行したJobを待たせることが出来ます IJob(2) // Jobの定義部分 struct MyJob : IJob{ // Jobに渡したいパラメーター public int param; // 実際に実行する処理 public void Execute( ){ int sum = 0; for( int i = 0 ; i < param ; ++ i){ sum += i ; } Debug.Log( “sum “ + sum ); } } // MonoBehaviourのUpdate内等で実際にJobを発行するところ // Jobを作成します var job = new MyJob(){ param = 100 }; // Jobを発行してます JobHandlehandle= job.Schedule(); // 発行したJobが完了するのを待ちます handle.Complete();
  28. 28. IJobParalellFor NativeArray<Vector3 >position [0] ( 0, 0, 10 ) [1] ( 0, 0, 20 ) [2] ( 0, 0, 30 ) [3] ( 0, 0, 40 ) [4] ( 0, 0, 50 ) ( 0, 0, 11) ( 0, 0, 21 ) ( 0, 0, 31 ) ( 0, 0, 41 ) ( 0, 0, 51 ) これに対して、(0,0,1 )を足していく IJobParallelForを使えば、この「(0,0,1) を足す作業」を 平行して処理させることが出来ます。 ... ...
  29. 29. MainThread position [ 0~10 ]の更新処理 Worker position [ 11~20 ]の更新処理 Worker position [ 21~30 ]の更新処理 Jobの発行及び完了待ち 分散後 MainThread position [ 0~30 ]の更新処理 分散前
  30. 30. // Jobの定義部分 struct MyPositionUpdate : IJobParallelFor{ // 更新対象をNativeArrayの形で保持します public NativeArray<Vector3> positions; public float deltaTime; // 実行部分 indexは、更新対象をする配列のindex値が入ります。 public void Execute( int index ){ positions[ index ] = positions[ index ] + Vector3.front * deltaTime; } } // MonoBehaviourのUpdate内等で実際にJobを発行するところ // Jobを作成します var job = new MyPositionUpdate(){ positions = bulletPositions,// <-NativeArray<Vector3> bulletPositions;が定義されているつもり deltaTime= Time.deltaTime,//<- Main以外からはTime.deltaTimeが呼べないので… }; // Jobを発行してます。対象の配列要素数・バッチ数を指定(0で良い感じに設定してくれる) JobHandlehandle= job.Schedule( positions.Length,0 ); // 発行したJobが完了するのを待ちます handle.Complete(); IJobParalellFor
  31. 31. // Jobの定義部分 struct MyPositionUpdate : IJobParallelFor{ // 更新対象をNativeArrayの形で保持します public NativeArray<Vector3> positions; public float deltaTime; // 実行部分 indexは、更新対象をする配列のindex値が入ります。 public void Execute( int index ){ positions[ index ] = positions[ index ] + Vector3.up * deltaTime; } } 更新の対象は、Nativeコンテナである必要があります。 IJobParalellFor // MonoBehaviourのUpdate内等で実際にJobを発行するところ // Jobを作成します var job = new MyPositionUpdate(){ positions = bulletPositions,// <-NativeArray<Vector3> bulletPositions;が定義されているつもり deltaTime= Time.deltaTime,//<- Main以外からはTime.deltaTimeが呼べないので… }; // Jobを発行してます。対象の配列要素数・バッチ数を指定(0で良い感じに設定してくれる) JobHandlehandle= job.Schedule( positions.Length,0 ); // 発行したJobが完了するのを待ちます handle.Complete();
  32. 32. // Jobの定義部分 struct MyPositionUpdate : IJobParallelFor{ // 更新対象をNativeArrayの形で保持します public NativeArray<Vector3> positions; public float deltaTime; // 実行部分 indexは、更新対象をする配列のindex値が入ります。 public void Execute( int index ){ positions[ index ] = positions[ index ] + Vector3.up * deltaTime; } } IJobParalellFor // MonoBehaviourのUpdate内等で実際にJobを発行するところ // Jobを作成します var job = new MyPositionUpdate(){ positions = bulletPositions,// <-NativeArray<Vector3> bulletPositions;が定義されているつもり deltaTime= Time.deltaTime,//<- Main以外からはTime.deltaTimeが呼べないので… }; // Jobを発行してます。対象の配列要素数・バッチ数を指定(0で良い感じに設定してくれる) JobHandlehandle= job.Schedule( positions.Length,0 ); // 発行したJobが完了するのを待ちます handle.Complete(); 予期せぬエラーを防ぐため、引数で渡された「index」以外に 書き込もうとすると、Editor上ではエラーメッセージが出るよ うになっています。
  33. 33. 複数のTransformに対して並行して処理を行うための IJobParallelForTransform IJobParallelForTransformを利用することで、このCubeの移 動や回転をWorkerThreadでもできるようになります。 (通常だとtransformへの書き込みはMainThread以外からでは できませんが、IJobParallelForTransformの TransformAccess経由ならば可能です)
  34. 34. // Jobの定義部分 struct MyTransformUpdateJob : IJobParallelForTransform{ // Jobに渡したいパラメーター public int objNum; public float time; // 実際に実行する処理 indexには配列の何個目であるか、transform に対して値をセットします public void Execute(int index, TransformAccesstransform){ transform.position = new Vector3( index – objNum / 2 , time , 0.0f); } } // MonoBehaviourのUpdate内等で実際にJobを発行するところ Transform[] transformArray = "xxx"; // 並行して処理をしたいTransformのリストを定義します var transformAccessArray = new TransformAccessArray(transformArray); // Jobを作成します var myTransformUpdateJob = new MyTransformUpdateJob(){ time= Time.deltaTime , objNum = transformArray.Length }; // Jobを発行して、直後で完了待ち JobHandlehandle= myTransformUpdateJob.Schedule( transformAccessArray ); handle.Complete(); 複数のTransformに対して並行して処理を行うための IJobParallelForTransform
  35. 35. // MonoBehaviourのUpdate内等で実際にJobを発行するところ Transform[] transformArray = "xxx"; // 並行して処理をしたいTransformのリストを定義します var transformAccessArray = new TransformAccessArray(transformArray); // Jobを作成します var myTransformUpdateJob = new MyTransformUpdateJob(){ time= Time.deltaTime , objNum = transformArray.Length }; // Jobを発行して、直後で完了待ち JobHandlehandle= myTransformUpdateJob.Schedule( transformAccessArray ); handle.Complete(); 複数のTransformに対して並行して処理を行うための IJobParallelForTransform 引数で渡ってくるTransformAccess経由でpositionやrotationを 設定します。 // Jobの定義部分 struct MyTransformUpdateJob : IJobParallelForTransform{ // Jobに渡したいパラメーター public int objNum; public float time; // 実際に実行する処理 indexには配列の何個目であるか、transform に対して値をセットします public void Execute(int index, TransformAccesstransform){ transform.position = new Vector3( index – objNum / 2 , time , 0.0f); } }
  36. 36. Job API • JobSystem API • Raycast Job RayCastCommand • NaviMesh Job NavMeshQuery
  37. 37. C JobSystem
  38. 38. https://github.com/wotakuro/UnityJobSystemTest こちらで計測。GPU・通信の影響を抑えるため、機内モード/画面輝度最低固定、ゲームのFPSを10固定 にし、CPUでのバッテリー消費が顕著に出る環境にして実験。 Android / iOS共に、JobSystemにして処理時間が減った結果結果、CPUの休む時間が増えたり、MainThreadへの負荷が減るので CPUの実行周波数を下げることが出来た等で、バッテリー消費が下がったと思われる。
  39. 39. C# JobSystem
  40. 40. C# JobSystem Q Job Priority( ) A Priority Job Job B Job A Job B Job A
  41. 41. WorkerThread
  42. 42. WorkerThread WorkerThreadの数はプラットフォーム・マシンの ハードウェアによって変わってきます。 多くのプラットフォームでは、コア数 – 1 だけ WorkerThreadに割り当てされます
  43. 43. Job
  44. 44. Job Job.Schedule時に、InvalidOperationException等が出てしまうことがあります。 これはJobの実行タイミングで結果が異なりうる時にエラーとなってしまう可 能性があるのをUnityEditorが察知してエラーを出しています。 異なる二つのJobが同じ参照先のデータを有していた場合等に発生します。
  45. 45. Job Worker Job A NativeArray<Vector3 >positions [0] ( 0, 0, 10 ) [1] ( 0, 0, 20 ) [2] ( 0, 0, 30 ) [3] ( 0, 0, 40 ) [4] ( 0, 0, 50 ) ... ... positions Worker Job B positions
  46. 46. Job Worker Job A NativeArray<Vector3 >positions [0] ( 0, 0, 10 ) [1] ( 0, 0, 20 ) [2] ( 0, 0, 30 ) [3] ( 0, 0, 40 ) [4] ( 0, 0, 50 ) ... ... positions Worker Job B positions 同時に走っているJobが同じ参照先( NativeContainer )を指 していた場合に複数のJobから同一のリソース書き込みを される可能性を考慮してEditor実行時にはエラーを出すよ うにしています。
  47. 47. Job Worker Job A NativeArray<Vector3 >positions [0] ( 0, 0, 10 ) [1] ( 0, 0, 20 ) [2] ( 0, 0, 30 ) [3] ( 0, 0, 40 ) [4] ( 0, 0, 50 ) ... ... positions Worker Job B positions 書き込みを行わないのであれば、Jobの変数宣言に[ReadOnly] 属性をつけて、 このpositionsへの書き込みは行わない事を明示的に教えます。 struct MyJob : IJob{ [ReadOnly] public NativeArray<Vector3>positions; } また[ReadOnly]の反対で、[WriteOnly]属性もあります。
  48. 48. IJobParallelFor Job.Schedule実行中に IndexOutOfRangeExceptionが出てきました。 しかし配列外のアクセスには心当たりがありません…。 とりあえず、ソースコードを見てみましょう…
  49. 49. IJobParallelFor // Jobの定義部分 struct MyPositionUpdate : IJobParallelFor{ // 更新対象をNativeArrayの形で保持します public NativeArray<Vector3> positions; // 敵のタイプ別の速度 public NativeArray<Vector3> velocityByEnemyType; // 敵のタイプ指定 public NativeArray<int> enemyType; // deltaTIme public float deltaTime; // 実行部分 indexは、更新対象をする配列のindex値が入ります。 public void Execute( int index ){ int enemyType = enemyType[index]; Vector3 velocity = velocityByEnemyType[ enemyType ]; positions[ index ] = positions[ index ] + Vector3.front * deltaTime; } }
  50. 50. IJobParallelFor // Jobの定義部分 struct MyPositionUpdate : IJobParallelFor{ // 更新対象をNativeArrayの形で保持します public NativeArray<Vector3> positions; // 敵のタイプ別の速度 public NativeArray<Vector3> velocityByEnemyType; // 敵のタイプ指定 public NativeArray<int> enemyType; // deltaTIme public float deltaTime; // 実行部分 indexは、更新対象をする配列のindex値が入ります。 public void Execute( int index ){ int enemyType = enemyType[index]; Vector3 velocity = velocityByEnemyType[ enemyType ]; positions[ index ] = positions[ index ] + Vector3.front * deltaTime; } } ここで実行時にエラーが出ます。 これは velocityByEnemyType[ enemyType ]と、引数「index」以外にアクセスし ているためです。 アクセスがReadなのかWriteなのかまでは判別は判別できませんが、指定され たindex以外にアクセスが起きている事だけは UnityEditor側で検知が出来ます。 なので、実行時にエラーを出します
  51. 51. IJobParallelFor // Jobの定義部分 struct MyPositionUpdate : IJobParallelFor{ // 更新対象をNativeArrayの形で保持します public NativeArray<Vector3> positions; // 敵のタイプ別の速度 [ReadOnly] public NativeArray<Vector3> velocityByEnemyType; // 敵のタイプ指定 public NativeArray<int> enemyType; // deltaTIme public float deltaTime; // 実行部分 indexは、更新対象をする配列のindex値が入ります。 public void Execute( int index ){ int enemyType = enemyType[index]; Vector3 velocity = velocityByEnemyType[ enemyType ]; positions[ index ] = positions[ index ] + Vector3.front * deltaTime; } } velocityByEnemyTypeに対して [ReadOnly]属性をつけてあげる事で、 velocityByEnemyTypeへの書き込みを行わないことを明示する事で実行時エラーが 回避できます。
  52. 52. C# JobSystem
  53. 53. Update class JobTest : MonoBehaviour{ privateJobHandlehandle; public Transform[] transformArray; void Update(){ //前のフレームで発行したJobが完了するのを待ちます jobHandle.Complete(); // 並行して処理をしたいTransformのリストを定義します var transformAccessArray = new TransformAccessArray(transformArray); // Jobを作成します var myTransformUpdateJob = new MyTransformUpdateJob(){ time = Time.deltaTime, objNum = transformArray.Length }; // Jobを発行してます。この時点では、Todo用のQueueに積まれるだけです JobHandlehandle= myTransformUpdateJob.Schedule( transformAccessArray ); // [重要] 実際に積まれたJobの実行を促します JobHandle.ScheduleBatchedJobs(); } }
  54. 54. Update MainThread Job更新処理 Worker Jobの更新処理 Jobの発行及び完了待ち エンジン側での描画等の更新処理 EngineのJob EngineのJob Worker Jobの更新処理 EngineのJob MainThread Job 発行 Worker Jobの更新処理 完了 待ち エンジン側での描画等の更新処理 EngineのJob EngineのJob Worker Jobの更新処理 EngineのJob Jobの更新処理 エンジンの処理の隙間にユーザーの処理を埋める 事で全体での処理時間を縮める事が可能です
  55. 55. Work1.IJob Work2.IJobParallelFor Work3.IJobParallelForTransform Work4.RayCastCommand

×