IL2CPP (Intermediate Language to C Plus Plus)
以前IL2CPPについての記事を書こうと思って、とっていたメモがあったので公開。 メモ書きなのでわかりづらいのはご容赦ください。
本当は内部実装の話も含めて、シリーズで書こうと思っていたのですが、 英語を読むのと元記事の古い部分の修正が面倒になったので中断中。 いつの日か、またやる気がでたら書くかも?
IL2CPPについて
本記事は以下のUnity公式ブログの内容をまとめたものです。
けっこう古い記事なので、現在の内容とは異なる可能性があります。
https://blogs.unity3d.com/2014/05/20/the-future-of-scripting-in-unity/
現状の問題点
- C#の実行速度はまだC/C++に劣る
- Unity内部のMonoのバージョンが上げられない
- つまり、最新の.NETの機能が使えない
- プラットフォームごとの調整コストが高い
- ガベージコレクション(GC)によって処理落ちが発生しうる
IL2CPPの構成
事前(AOT)コンパイラとバーチャルマシン(VM)から成る。 これらが現在.NETやMonoの提供しているものに変わる共通言語基盤の実装となる。
.NETアセンブリ
-> C++ソースコード [AOTコンパイラ]
-> ネイティブバイナリ [プラットフォーム標準のC++コンパイラ]
GCやメタデータ、プラットフォーム固有のリソースなどのサービスはVMによって提供される。
IL2CPPの利点
パフォーマンス
『C#の生産性とC++のパフォーマンスを』
- C++のコンパイラとリンカならではの最適化
- 静的解析によるサイズと速度の最適化
- Unityに特化したスクリプトの最適化
.NETのアップグレード
現状はコンパイラ・クラスライブラリともに.NET3.5相当(2010年前後のやつ)。
※コンパイラは変更可能。ただし、場合によっては動かないことも(CompareAndExchangeを使ってる部分とか)
IL2CPPの技術が十分に成熟したら.NETのバージョンを上げられる。
可搬性と保守性
MonoのVMは大量のプラットフォームおよびアーキテクチャ依存コードを含んでいる。
Unityが新たなプラットフォームに対応するコストが高い。
機能やバグがプラットフォームによってあったりなかったり。
IL2CPPによって、
- アーキテクチャ固有の機械語ではなくC++に対してコード生成できる。
- 機能追加やバグ修正がC++で可能になる。新たなプラットフォームの追加も容易になる。
C++コンパイラの最適化機能も利用できるようになるので、 コード生成時に車輪の再発明する必要がなくなる。
Unity開発側の都合にみえるが、 ある機能の開発コストが減るということは、 別の機能の開発にリソースを割けるということなので、 結果としてユーザにとってもプラス (Unity自体のバグが減るという利点も)。
ガベージコレクション
特定のガベージコレクタに縛られることがなくなる。 またコンパイラの段階での解析によりGCの対象を減らせる (C++では独自にメモリ管理ができるため、C#ではガベージコレクタにまかせるしかない場面でも、C++ではユーザコード内でメモリ解放ができる場合がある)。
注意
MonoのVMとAOTコンパイラを置き換えるものであって、 C#コンパイラやクラスライブラリを置き換えるものじゃない。 つまり、Monoで動くコードは引き続き動作する。
IL2CPPの内部について
内部実装に関するメモも途中まではあるのですが、 あまりまとまっていないというのと、 内部実装を理解しようとするような人はだいたい英語で読めると思うので元記事へのリンクのみとしておきます。
内部実装は日々進化しているので、記事の内容と現在の実装は異なります。 実際に実行しながら確認していくことをおすすめします。
https://blogs.unity3d.com/2015/05/06/an-introduction-to-ilcpp-internals/