Mais conteúdo relacionado Semelhante a 【GTMF2018TOKYO】ハードウェアの性能を活かす為の、Unityの新しい3つの機能 (20) Mais de Unity Technologies Japan K.K. (20) 【GTMF2018TOKYO】ハードウェアの性能を活かす為の、Unityの新しい3つの機能25. public struct Engine : IComponentData {
public float power;
}
IComponentDataを継承
値のみ持つ
何もデータを持たない事もある
public class Engine : MonoBehaviour {
public float power;
}
MonoBehaviour
ComponentData
定義の違い
構造体
26. var entity_manager = World.Active.GetOrCreateManager<EntityManager>();
var entity = entity_manager.CreateEntity(typeof(Engine));
EntityManagerで生成
var obj = new GameObject(“obj”, typeof(Engine));
MonoBehaviour
ComponentData
生成の違い
40. NativeArray
var a = new NativeArray<MyStruct>(32, Allocator.Persistent);
生成
解放
Allocator.Persistent
Allocator.Temp
Allocator.TempJob
永続的に使用可能
同じフレームで解放しないとエラー
4フレーム以内に解放しないとエラー
ジョブ終了時に自動開放させるオプション有
a.Dispose();
41. オブジェクトの増減が低コスト
POS POS POS POS POS POS POS POS POS POS POS POS
POS POS POS POS POS POS POS POS POS POS
最後の要素で塗り直すだけ
ガベージコレクションは発生しない
要素を削除したときは
POS
42. GameObject 1 Data Renderer Data
Data Data Data Data Data Data Data Data Data Data Data Data
Data Data Data
手続き的な手法を踏まずにオブジェクトをロード
Entity Entity Entity Entity Entity
Data Data Data Data
レイアウトが確定しているので、
ロードしたデータをそのまま
メモリに展開
Data Entity Entity
Data Data Data Data Entity Entity
ちょっと未来話
File
46. 一つのコアで複数の処理を実行
Core 0 Core 1
Work Work Work Work Work Work
index[0] index[1] index[2] index[3] index[4] index[5]
ZZZzzz
一つのコアが作業している間、他のコアは仕事が無い
50. High Performance C# (C# Job Systemの制約)
Class Type無し
Boxing無し
GC Allocation無し
Exception無し
大丈夫!
まだ (一応) C#
All Basic Types
Struct
Enum
Generic
Properties
Safe Sandbox
高速なC#を組む為のルール
54. C# Job Systemの基本的な流れ(1/3)
pos[0] pos[1] pos[2] pos[3] pos[4] pos[5]
res[0] res[1] res[2] res[3] res[4] res[5]
3つのバッファーを用意する
Jobの処理は全て確保したバッファーに対して行う
NativeArray <float3>
NativeArray <int>
座標データとか
座標的に接触したか
NativeArray <int>
結局、接触したのか ans[0]
55. C# Job Systemの基本的な流れ(2/3)
pos[0] pos[1] pos[2] pos[3] pos[4] pos[5]
res[0] res[1] res[2] res[3] res[4] res[5]
複数のコアで担当する要素を処理し
結果をバッファに格納する
NativeArray <float3>
NativeArray <int>
計算に利用するデータ
結果を格納する
Core 1 で処理 Core 3 で処理Core 2 で処理
56. C# Job Systemの基本的な流れ(3/3)
res[0] res[1] res[2] res[3] res[4] res[5]
ans[0]
結果をまとめて最終的な判定を行う
NativeArray <int>
最終的な結果
Core 1 で処理
NativeArray <int>
結果を格納する
ココを見て接触したか判定
57. pos[0] pos[1] pos[2] pos[3] pos[4] pos[5]
res[0] res[1] res[2] res[3] res[4] res[5]
Core 1 で処理 Core 3 で処理Core 2 で処理
ans[0]
Core 1 で処理 IJob
IJobParallelFor
弾が特定の場所に接触したかを
全てのコアを使って並列処理
やってみる並列処理(1)
59. IJobParallelForを定義(2/3)
struct 弾の判定ジョブ : IJobParallelFor {
public void Execute(int id) {
}
}
Jobが使用するバッファを定義
入出力のバッファ
public NativeArray<Vector3> pos;
public NativeArray<int> res;
C# Job Systemは
入出力を明確にする
60. IJobParallelForを定義(3/3)
struct 弾の判定ジョブ : IJobParallelFor {
public NativeArray<Vector3>pos;
public NativeArray<int> res;
public void Execute(int id) {
}
}
Jobの処理をExecuteに記述
idは供給される
Jobが実行する処理 res[id] = (Vector3.Distance(
Vector3.zero, pos[id]) < 1) ? 0 : 1;
61. IJobParallelForを使う(1/4)
struct 弾の判定 : IJobParallelFor {
public NativeArray<Vector3>pos;
public NativeArray<int> res;
public void Execute(int id) {
pos[id] = (Vector3.Distance(
Vector3.zero, res[id]) < 1) ? 0 : 1;
}
}
Jobを生成
void Update() {
}
生成
var ajob = new 弾の判定ジョブ(){} ;
62. IJobParallelForを使う(2/4)
struct 弾の判定 : IJobParallelFor {
public NativeArray<Vector3>pos;
public NativeArray<int> res;
public void Execute(int id) {
pos[id] = (Vector3.Distance(
Vector3.zero, res[id]) < 1) ? 0 : 1;
}
}
Jobにバッファを登録
void Update() {
var ajob = new 弾の判定ジョブ(){
}
}
データ参照
pos = positions,
res = results1
63. IJobParallelForを使う(3/4)
struct 弾の判定 : IJobParallelFor {
public NativeArray<Vector3>pos;
public NativeArray<int> res;
public void Execute(int id) {
pos[id] = (Vector3.Distance(
Vector3.zero, res[id]) < 1) ? 0 : 1;
}
}
void Update() {
var ajob = new 弾の判定ジョブ(){
pos = positions,
res = results1
}
}
実行指令
1ジョブでまとめて
実行する回数
毎フレームScheduleを呼ぶ
var handle = ajob.Schedule(positions.Length, 8);
64. IJobParallelForを使う(4/4)
struct 弾の判定 : IJobParallelFor {
public NativeArray<Vector3>pos;
public NativeArray<int> res;
public void Execute(int id) {
pos[id] = (Vector3.Distance(
Vector3.zero, res[id]) < 1) ? 0 : 1;
}
}
void Update() {
var ajob = new 弾の判定ジョブ(){
pos = positions,
res = results1
}
var handle = ajob.Schedule(positions.Length, 8);
}
即時ジョブ起動
完了まで待つ
以下は必要に応じて
JobHandle.ScheduleBatchedJobs();
handle.Complete();
67. pos[0] pos[1] pos[2] pos[3] pos[4] pos[5]
res[0] res[1] res[2] res[3] res[4] res[5]
Core 1 で処理 Core 3 で処理Core 2 で処理
ans[0]
Core 1 で処理 IJob
IJobParallelFor
やってみる並列処理(2)
69. IJob
struct 結果を受け取るジョブ : IJob {
public void Execute() {
}
}
入出力
public NativeArray<int> res;
public NativeArray<int> ans;
70. IJob
struct 結果を受け取るジョブ : IJob {
public NativeArray<int> res;
public NativeArray<int> ans;
public void Execute() {
}
}
ジョブの実行内容
var length = res.Length;
for(var i=0; i<length; i++){
if( res[i] == 1){}
}
71. IJob
struct 結果を受け取るジョブ : IJob {
public NativeArray<int> res;
public NativeArray<int> ans;
public void Execute() {
var length = res.Length;
for(var i=0; i<length; i++){
if( res[i] == 1){ return ;}
}
}
}
結果を格納
ans[0] = 1;
ans[0] = 0;
72. IJob
struct BJob : IJob {
public NativeArray<int> res;
public NativeArray<int> result;
public void Execute() {
for (var i = 0; i < positions.Length; ++i) {
var pos = positions[i];
if( pos.x > -0.5f && pos.x < 0.5f){
result[0] = 1; return;
}
}
}
}
要素への参照なので危険がつきまとう
読込専用なら兎も角、読み書きするジョブが複数同時に同じ要素を操作するとヤバイ
[ReadOnly]や[WriteOnly]属性をつける
データの読取専用 データの書込専用
73. IJob
struct 結果を受け取るジョブ : IJob {
public NativeArray<int> res;
public NativeArray<int> ans;
public void Execute() {
var length = res.Length;
for(var i=0; i<length; i++){
if( res[i] == 1){ans[0] = 1; return ;}
}
ans[0] = 0;
}
}
読取専用・書込専用の
属性を付ける
[ReadOnly]
[WriteOnly]
79. ECSとのC# Job Systemの連携(1)
public struct RigidbodyPositionJob
: {
}
[Inject]無しにComponentData注入、若干効率的
Injectの代わりにジェネリックでComponentDataを要求
IJobProcessComponentDataを使う
IJobProcessComponentData<Position, RigidbodyPosition>
80. ECSとのC# Job Systemの連携(2)
public struct RigidbodyPositionJob
: IJobProcessComponentData<Position, RigidbodyPosition> {
}
[Inject]無しにComponentData注入、若干効率的
[ReadOnly][WriteOnly]属性で、
競合しないように、ジョブの実行順を
自動調整してくれる機能付
IJobProcessComponentDataを使う
public void Execute(ref Position pos, ref RigidbodyPosition rot) {
// 処理
}
88. struct 弾の判定 : IJobParallelFor {
public NativeArray<Vector3>pos;
public NativeArray<int> res;
public void Execute(int id) {
pos[id] = (Vector3.Distance(
Vector3.zero, res[id]) < 1) ? 0 : 1;
}
}
使い方
IJob系のインターフェースに
BurstCompile属性をつける
[Unity.Burst.BurstCompile]