見出し画像

Unity DOTS の概要

以下の記事を参考にして書いてます。

What is DOTS and why is it important?

1. DOTS

DOTS」(Data-Oriented Tech Stack)は、Unityの新技術の組み合わせによる、Unityの新しい基盤です。「オブジェクト指向」から「データ指向」にアプローチが大きく変化します。これによって、マルチコアプロセッサによるデータ処理の並列化が可能になり、Unityプロジェクトのパフォーマンスを向上させることができます。

最終的にUnityは完全に「DOTS」に移行しますが、今のところ、「DOTS」は従来のアプローチ(GameObject)と共存させることができるため、Unityエンジンの拡張機能と考えることができます。

「DOTS」はまだプレビュー段階ですが、「DOTS」があなたにとって重要になると判断した場合、できるだけ早く学び始めることをお勧めします。「DOTS」のAPIは今後も変更されますが、「データ指向」の基本原則と「DOTS」のプロジェクトに対するアプローチは変わりません。

3. DOTSの構成要素

「DOTS」は、次の要素で構成されています。

(1) ECS(Entity Component System)
「データ指向」を使用してコーディングするためのフレームワークを提供します。 PackageManagerの「Entities」パッケージ経由で提供します。

(2) C# Job System
マルチスレッドコードを生成する簡単な方法を提供します。PackageManagerの「Jobs」パッケージ経由で提供します。

(3) Burstコンパイラ
最適化された高速なネイティブコードを生成します。 PackageManagerの「Burst」パッケージ経由で提供します。

「ECS」「C# Job System」「Burst」は、「DOTS」の3本柱と呼ばれ、個別のUnityパッケージとして利用できます。これらを組み合わせて、高性能な「データ指向」を実現するための基盤を構築します。

画像1

「DOTS」をはじめるための入口は、「ECS」です。「ECS」は、コードを構造化して記述するフレームワークです。これにより、CPUによるキャッシュミスを減らし、高速アクセスを実現する論理的な方法で、メモリにデータを配置できます。多くの場合、「DOTS」なしでは実現できないような、大幅なパフォーマンスの向上が得られます。

「ECS」は、メモリ内でのデータ配置と、CPUによるデータアクセス方法を簡単に定義することができます。これは、DOTS以前からUnityで使用されていたデータ構造とは大きく異なります。単一の「MonoBehavior」の代わりにデータセットを処理する線形データとシステムを連携させることにより、将来に向けて、よりスケーラブルな基盤を提供できます。つまり、「ECS」は、「オブジェクト指向」から「データ指向」に移行しています。

「ECS」の概要については、チュートリアル「Entity Component System」とブログ記事「On DOTS Entity Component System」を参照してください。

軽量バージョンの「DOTS」も作成しました。具体的には、モバイルデバイスなど、ハードウェアの制限が大きいデバイスを対象としています。「Project Tiny」は、エディタでDOTSモードを提供しています。

4. DOTSはなぜ重要なのか?

「DOTS」は、開発者が大なり小なり象徴的な体験を開発することを可能にします。

Unityは、リアルタイム進化の次の波をサポートするための体制を整えたいと考えています。Unityエンジンは、最大限に次世代のハードウェアを活用して、最先端のコンテンツを制作できるように、準備をしておく必要があります。

テクノロジーの変化は急速です。歴史が示すように、今日のAAAゲームは、近い将来には時代遅れの遺物とみなされるようになるでしょう。その時には、Unityエンジンが次世代のリアルタイム3D開発をサポートする準備ができていることを確認する必要があります。

アプリのニーズに合わせてCPUやメモリの性能が上がっているわけではありません。「DOTS」のように、ハードウェアの特性と制約を最大限に活用できるアーキテクチャは、これらのニーズを満たす方法を提供します。

画像2

5. DOTSがパフォーマンスを向上させる方法

Unityは、様々なハードウェア向けに構築されていますが、全てのハードウェアに共通の問題と、対処できる領域があります。 

・CPUの処理速度が相対的に遅くなっている。
過去20年間に見られた増加率が再現される可能性は低いです。

・メモリアクセス速度は、処理速度に合わせて向上していない。
 Unityは非常に高速にメモリアクセスする必要があります。メモリ内のデータを、高速アクセスできるように、配置する必要があります。

・GPUは比較的未開発のリソース。
並列処理を提供することでパフォーマンスを向上させるソリューションを提供しますが、GPUを使用するための専用ツールがなければ、比較的未開発のリソースになります。

ソフトウェアは、このようなハードウェアの制約を回避してパフォーマンスを向上させるための鍵を握っています。実際には、これは消費電力の削減とバッテリー寿命の延長につながります。

これらの問題に対して、以下のように対処します。

・ECS(Entity Component System)
コーディングに対する「データ指向」のアプローチを提供します。「データ指向」のアプローチでは、データ構造が整理されて、キャッシュミスを回避し、データへのアクセスをより効率的かつ高速にします。オ「ブジェクト指向」はこのデータ配置に焦点をあててないため、キャッシュミスがよく発生し、CPUによるデータアクセスが遅くなります。

・C# Job System
高速で並列化されたコードをC#で簡単に記述することで、現在利用可能なマルチコアプロセッサを十分に活用します。

・Burstコンパイラ
コンパイル対象のハードウェアに最適化されたコードを生成します。

以下は、UnityのMegacityプロジェクトを紹介するビデオです。Megacityは「DOTS」を活用したデモになります。

6. データ指向とは何か?

データ指向」では、メモリ内のデータに効率的にアクセスできるように、データに優先順位を付けて整理します。これは、コード設計が作成している世界モデルによって導かれるべきという「オブジェクト指向」の原則と矛盾しています。

オブジェクト指向」のワークフローは、次のとおりです。

(1) GameObjectの作成
(2) GameObjectにComponentを追加。
(3) Componentのプロパティを変更するスクリプトを記述。

実行時、GameObjectはComponentの参照に依存します。スクリプトがComponentのデータを探す時、それらはメモリに分散しているため、アクセス時間がかかります。

データ指向」では、全てを「オブジェクト」ではなく「データ」と見なす必要があります。これにより、すべてのデータに簡単にアクセスできます。

データ指向」のワークフローは、最初に「最も一般的なタスク」を特定して、そのデータを整理することです。「最も一般的なタスク」は、実行時に最も頻繁に解決する必要があるタスクになります。データを整理することで、実行時のデータアクセスが、複数のクラスを介してデータアクセスするよりも、はるかに効率的になります。

画像3

7. DOTSは私 / 私のチーム / 私のプロジェクトに適しているか?

短期的・中期的にパフォーマンスの改善を求めているのでない限り、「DOTS」に移行するかどうかを判断するのは困難です。

「DOTS」は、ほとんどのアプリでパフォーマンス向上をもたらす可能性が高いです。対象には、パフォーマンスバッテリー消費反復スケーラビリティが含まれます。特に、大量のデータを扱うのに適しています。「DOTS」への移行によるパフォーマンスの低下は見られませんが、「DOTS」への移行のコストを評価することは重要です。

8. DOTSの利点とリスク

「DOTS」は、Unityプロジェクトのパフォーマンスを向上させる大きな可能性を持っています。ただし、「DOTS」を使用する際には、プロジェクトのタイムラインや予算など、開発チームに影響を与える考慮事項があります。 これらは、プロジェクトの優先順位と比較する必要があるものになります。

◎ 利点
・性能の向上
「DOTS」はメモリ、ランタイム、およびバッテリーのパフォーマンスを飛躍的に向上させることができます。 ゲームに表示されるアイテムの数が増えると、パフォーマンスが向上する可能性が高くなります。 逆に、アイテム数が少ないゲームでは、劇的なパフォーマンスの向上は見られません。

・コード制御
「DOTS」は、プロジェクトのサイズが大きくなるにつれて、コードの複雑さをより適切に制御します。「DOTS」用に作成されたコードは、一般的に問題の分離がより優れています。このため、コードのリファクタリング、単体テストの記述、開発者間の作業の分散は、「DOTS」で作業する方が簡単です。

◎ リスク
・学習コスト
「データ指向」に慣れていない場合、「DOTS」の利用には学習コストがかかります。現時点では、「DOTS」を使いこなすまでには、平均的なUnity開発者で1ヶ月かかると想定しています。

・サポート制限
「DOTS」は最終的に全てのUnityの機能と互換性を持つようになりますが、今のところ限られた機能セットとのみになります。ただし「DOTS」は、プロジェクト内で「GameObject」「DOTS」を両方同時に使用できるため、最も頻繁に処理されるタスクに「DOTS」を使用し、残りには「GameIObject」を使用することができます。

9. DOTSを準備する方法は?

「DOTS」への移行には、学習コストがかかります。「DOTS」とは何かを理解し、「DOTS」の使用を開始する前に、「DOTS」が必要なメリットをもたらす領域を確認することが重要です。 プロジェクトの特定の部分のみ変換して「DOTS」を使用する場合や、多くの重要な領域で「DOTS」を適用する場合があります。

「DOTS」の準備、「データ指向」の学習、およびAPIを使用した「DOTS」の実装方法の学習には、2つの側面があります。「DOTS」の使用を開始する前に、準備のために実行できることが、いくつかあります。

◎ すべての人
「オブジェクト指向」から「データ指向」に移行することは、新しいプログラミング言語や新しいコーディング方法を学ぶこととは異なります。代わりに、コーディングへのアプローチ方法と、コードを通じて構築している情報が、どのように表現されるかが変わります。

経験豊富な開発者であっても、「データ指向」の考え方への移行は困難な場合があります。これは、コード設計の練習と、第二の性質となった動作を抽象化する方法を再イメージ化する必要があるためです。「データ指向」のアプローチでは、コードを別の方法で考える必要があり、オブジェクト、クラス、ビヘイビアを必要なデータにまで減らし、このデータを効率的に整理して、「最も一般的なタスク」に変換します。実際には、これは簡単な作業ではありません。データを理解し、「DOTS」を使用してデータを最大限に活用する方法を習得するために、時間をかけて改善する必要があります。

「データ指向」の詳細については、「Data-Oriented Design」や「外部リソースのリスト」を参照してください。

◎ プログラマ
「データ指向」の設計はアプローチです。Unityでのコーディングの経験がある場合、変更する必要があるのはコーディングスキルではなく、それらをデータ中心のアプローチにどのように適用するかです。

Unityでコードを記述する方法にいくつかの重要な変更があり、これらのパフォーマンスの向上を達成するために行う必要があります。1つ目は、データの整理方法です。計算中にメモリ内の複数の場所からプルするのではなく、データをクリーンでリニアな配列でCPUに提供することで、パフォーマンスが大幅に向上します。メモリ管理で積極的な役割を果たすことで、パフォーマンスに最適な方法でメモリが管理されるようにします。UnityのAPIに追加された一連の新しいツールにより、データレイアウトを管理したり、明示的かつ詳細な方法でメモリを管理したりできます。

全てのコードを書き換える必要はありません。Unityで他の人が常に使用している方法でC#コードを記述しながら、コードのパフォーマンスが重要な領域のみを書き換えることができます。

「ECS」の基本について学ぶには、チュートリアル「Entity Component System」や「ECS samples project」を参照してください。

10. DOTSの未来とは?

「DOTS」はUnityの未来です。Unityのアーキテクチャは、あらゆる面で「DOTS」を採用しようとしています。これはゆっくりと起こっていますが、今「DOTS」について学ぶことで、Unityの機能全体に「DOTS」を展開していくうちに移行が容易になるでしょう。

「データ指向」はリアルタイム3D業界の未来です。特にゲーム業界では、問題解決や複雑なソリューションの開発に「データ指向」の原則や実装を活用する傾向が高まっています。

例えば、スウェーデンのゲームスタジオ「Far North Entertainment」は、「DOTS」を使用してパフォーマンスの懸念に対処しています。これについては、Unity Blogで解説されています。

「データ指向」の使用は、「Frostbite」や「Unreal」などの他のゲーム エンジンでも検討されています。「DOTS」を Unity に持ち込むことで、AAA ゲーム開発のベストプラクティスをより多くのユーザーに提供できるようにしています。

Unity以外で「データ指向」の使用が報告されているゲームの例としては、「Blizzard’s OverWatch」や「CD Projekt’t The Witcher 3.」などがあります。



いいなと思ったら応援しよう!