はじめに
Unity 6.7 Alpha 2で、CoreCLR Playerが実験的に使えるようになりました。
公式リリースノートはこちらです。
CoreCLRというのは、普段の.NETで使われているランタイムです。
UnityではこれまでMonoかIL2CPPを使うのが基本でしたが、今回からWindows、macOS、Linux向けにCoreCLRのPlayerビルドが追加されました。
ということで、さっそくCPUパストレーサーを動かしてみました。
比較したもの
今回は以下の3つで比較しました。
- Mono (6.13.0)
- IL2CPP
- CoreCLR(.NET 10)
ベンチマークでは、以下の処理時間を測っています。
- シーン生成
- BVH構築
- シングルスレッド・パストレーシング
- マルチスレッド・パストレーシング
コードはこちらです:https://gist.github.com/hez2010/353e5fe25ce7eb772cac07e3c86a0829
ランタイムのパフォーマンスを測定したいので、Job System、NativeArray や Compute Shader などは使っていません。普通のC#コードをそのまま動かしています。また、unsafe も一切使用していません。
結果
Mono
| 項目 | 結果 |
|---|---|
| シーン生成 | 4.969 ms |
| BVH構築 | 12.445 ms |
| シングルスレッド | 101,041.867 ms |
| シングルスレッド性能 | 7.2万 rays/s |
| マルチスレッド | 7,119.707 ms |
| マルチスレッド性能 | 101.8万 rays/s |
シングルスレッドは約101秒で、マルチスレッドでも約7.1秒かかりました。結果が出るまで待ちくたびれるほどでした。
IL2CPP
| 項目 | 結果 |
|---|---|
| シーン生成 | 0.819 ms |
| BVH構築 | 3.829 ms |
| シングルスレッド | 15,862.338 ms |
| シングルスレッド性能 | 45.7万 rays/s |
| マルチスレッド | 1,350.007 ms |
| マルチスレッド性能 | 536.7万 rays/s |
IL2CPPはさすがにMonoよりかなり速いです。マルチスレッドは約1.35秒でした。
この時点では、まあこんなものかなという感じでした。
CoreCLR(.NET 10)
そしてCoreCLRです。
| 項目 | 結果 |
|---|---|
| シーン生成 | 0.089 ms |
| BVH構築 | 1.424 ms |
| シングルスレッド | 8,775.239 ms |
| シングルスレッド性能 | 82.6万 rays/s |
| マルチスレッド | 758.274 ms |
| マルチスレッド性能 | 955.5万 rays/s |
マルチスレッドが758.274 msでした。1秒切っています。
マルチスレッド
並べるとこうです。
| バックエンド | マルチスレッド実行時間 |
|---|---|
| Mono | 7,119.707 ms |
| IL2CPP | 1,350.007 ms |
| CoreCLR | 758.274 ms |
CoreCLRは、Mono比では約9.4倍高速、IL2CPP比では約1.78倍高速です。
CoreCLRが速すぎて普通に笑いました。
シングルスレッド
シングルスレッドの結果はこちらです。
| バックエンド | 実行時間 | 性能 |
|---|---|---|
| Mono | 101,041.867 ms | 7.2万 rays/s |
| IL2CPP | 15,862.338 ms | 45.7万 rays/s |
| CoreCLR | 8,775.239 ms | 82.6万 rays/s |
CoreCLRはシングルスレッドでも、Monoより約11.5倍高速で、IL2CPPより約1.81倍高速でした。
マルチスレッドだけが速いわけではなく、普通に単体性能も高いです。
シーン生成
| バックエンド | 時間 |
|---|---|
| Mono | 4.969 ms |
| IL2CPP | 0.819 ms |
| CoreCLR | 0.089 ms |
CoreCLRは0.089 msです。
この項目は処理時間が短すぎるので、測定誤差の影響はかなりあると思います。
とはいえ、数字だけ見るとかなり強いです。
BVH構築
| バックエンド | 時間 |
|---|---|
| Mono | 12.445 ms |
| IL2CPP | 3.829 ms |
| CoreCLR | 1.424 ms |
BVH構築でもCoreCLRが最速でした。
パストレーシング本体だけでなく、前処理も速いです。
メモリ使用量
ゲーム起動後のメモリ使用量も見てみました。
| バックエンド | メモリ使用量 |
|---|---|
| Mono | 556.8 MB |
| IL2CPP | 504.0 MB |
| CoreCLR | 501.7 MB |
CoreCLRが一番少ないです。
IL2CPPとの差はほとんどありませんが、少なくとも「JITだからメモリを大量に食う」という感じではありませんでした。
MonoだけChecksumが違う理由
結果画像を見ると、MonoだけChecksumがちがうぞって思う方もいらっしゃると思いますが、これはMonoだけ結果がおかしいわけではありません。
これは単純にMonoが遅すぎたので、Monoだけウォームアップ回数をかなり減らしました。同じ回数で回すとなかなか終わりません。
ウォームアップ結果もChecksumに含まれているため、その分だけ値が変わっています。
まとめ
今回の結果をまとめると、こうなりました。
| 指標 | Mono 6.13.0 | IL2CPP | CoreCLR(.NET 10) |
|---|---|---|---|
| シーン生成 | 4.969 ms | 0.819 ms |
0.089 ms Mono比 約55.8倍高速 IL2CPP比 約9.2倍高速 |
| BVH構築 | 12.445 ms | 3.829 ms |
1.424 ms Mono比 約8.7倍高速 IL2CPP比 約2.7倍高速 |
| シングルスレッド実行時間 | 101,041.867 ms | 15,862.338 ms |
8,775.239 ms Mono比 約11.5倍高速 IL2CPP比 約1.81倍高速 |
| シングルスレッド性能 | 7.2万 rays/s | 45.7万 rays/s |
82.6万 rays/s Mono比 約11.5倍 IL2CPP比 約1.81倍 |
| マルチスレッド実行時間 | 7,119.707 ms | 1,350.007 ms |
758.274 ms Mono比 約9.4倍高速 IL2CPP比 約1.78倍高速 |
| マルチスレッド性能 | 101.8万 rays/s | 536.7万 rays/s |
955.5万 rays/s Mono比 約9.4倍 IL2CPP比 約1.78倍 |
| メモリ使用量 | 556.8 MB | 504.0 MB |
501.7 MB Mono比 約9.9%削減 IL2CPP比 約0.5%削減 |
まだAlphaで実験的な機能ですが、普通のC#コードをそのまま動かしてこの結果なのはかなり面白いです。
CoreCLRがUnityの正式版で使えるようになるのがとても楽しみです!


