Unity を検索

2021 年は Burst 1.5 でコードを高速化しよう

2021年4月14日 カテゴリ: Engine & platform | 5 分 で読めます
Screenshot of gameplay
Screenshot of gameplay
取り上げているトピック
シェア

Is this article helpful for you?

Thank you for your feedback!

Unity のハイパフォーマンス C#(HPC#)コンパイラー技術である Burst はますます進化しています。そこで今回は、最新バージョンである Burst 1.5 で行われた主要な改良点をご紹介します。この記事では、皆さんのプロジェクトで Burst を最大限に活用していただくために、主な機能とそのメリットをご紹介します。

Arm Neon ハードウェアの組み込み関数

Arm のパートナーの協力により、Arm Neon ハードウェア組み込み関数(intrinsics) のサポートが Burst 1.5 に追加されました。これにより、Arm プラットフォームで利用可能な特定のハードウェア命令セットをターゲットにすることができ、優れたベクトル演算技術である Neon もフル活用することができます。

Arm Neon の組み込み関数は、Burst 1.4 で実験的機能として導入されていましたが、Burst 1.5 では完全にサポートされます。また、Armv8.1-RDMA、Armv8.2-DotProd、Armv8.2-Crypto の組み込み関数を含む、すべての Armv8-A の組み込み関数は、Burst 1.5 では実験的機能として提供されます。これらは、次期バージョンの Burst で完全にサポートされる予定です。

Arm Neon の組み込み関数では、Intel の組み込み関数でもおなじみの v128 型と v64 型を使います。これらの型は、それぞれ 128 ビットまたは 64 ビットのデータの受け入れ場所を構成します。ベクトル要素の型と個数を確認し、正しく処理する責任はユーザーに委ねられます。結局のところ、これらのベクトルは、CPU 上の実際の SIMD レジスタを表現しているのです。

使用例を見てみましょう。

IsNeonSupported の値は、ターゲット CPU に基づいてコンパイル時に評価されるため、実行時のパフォーマンスには影響しないことに注意してください。また、Arm および Intel をターゲット CPU として、複数の組み込み関数による実装を提供したい場合は、IsXXXSupported(XXX はターゲット CPU に応じた名称)で分岐するブロックをさらにコードに加える必要があります。

Neon の組み込み関数は Armv8-A ハードウェア(64 ビット版)でのみサポートされていることにも注意が必要です。Armv7-A(32 ビット版)では、IsNeonSupported は常に false になります。古い 32 ビットの Arm デバイスをターゲットにしている場合、Neon の組み込み関数を直接使用しなくても、Burst を使用してマネージドコードを自動的に最適化することができます。

Arm の組み込み関数に関するフォローアップ、および Neon の組み込み関数に関する詳細は、今後のブログで紹介する予定です。

ハードウェアの組み込み関数は、コンパイラーの性能を最大限に引き出したい、コードを微調整して CPU サイクルを少しでも減らしたいと考えている上級者をターゲットとした機能です。この難しい課題に挑戦された方からのご意見をお待ちしています。

Direct Call

Burst 1.5 の新機能のうち特筆するべきものに、Direct Call(直接呼び出し)と呼ばれるものがあります。Burst では、HPC#コンパイラを使って Unity のジョブシステム上で実行されるタスクを高速化するために、まずジョブに注目しました。その後、関数ポインターを追加し、Burst のコードの一部をどこからでも管理・呼び出しできるようにしました。

コードは Burst を通して実行されていきます。Direct Call メソッドは、メインスレッドから呼び出された場合にのみ、ここまで説明したように動作することに注意してください。

新しく加わった強力な最適化機能

Burst 1.5 では、強力な最適化能力を実現するために、新機能や興味深い機能がいろいろと追加されています。

Hint.Likely、Hint.Unlikely、および Hint.Assume

ずっと挙げられていた重要な要望の 1 つに、何らかの処理が行われる起こる可能性が高いのか低いのかをコンパイラーに知らせるために組み込み関数を使いたいというものがありました。Burst 1.5 では、Unity.Burst.CompilerServices に Likely と Unlikely という 2 つの新しい組み込み関数が追加されました。

これらの組み込み関数を使うと、ブーリアンで書かれた条件(if 分岐の条件など)がヒットする可能性が高いか低いかをコンパイラに伝えることができます。これにより、コンパイラーは出力するコードを最適化することができます。

また、Assume 組み込み関数も追加されました。

この組み込み関数は、ある特定の、常に発生する状況をコンパイラーに知らせるものです。例えば、Assume を使って、ポインターは絶対に NULL にならない、インデックスは絶対に負にならない、値は絶対に NaN(非数)にならない、などをコンパイラーに伝えることができます。ただし、コンパイラーはコードに書かれた Assume が実際に正しいかどうかはチェックしませんので、Assume で伝える情報が実際に正しいことはユーザー側で確かめておく必要があります。

IsConstantExpression

また、コンパイル時に式が定数式として評価されるかどうかを問い合わせる組み込み関数も追加されました。

このクエリは、上記のように、ある値が定数であることを確認するために使用できます。それ以外にも、たとえばある値が確実に NaN や NULL ではない場合に、高速なパスを使えるアルゴリズムに使用することができます。

[SkipLocalsInit]

C#では、すべてのローカル変数はデフォルトでゼロに初期化されます。この初期化のコストを省きたい開発者向けに、[SkipLocalsInit] という属性を追加しました。使い方は、この属性を初期化をさせたくない関数に適用するだけです。これは、.NET 5 の SkipLocalsInitAttribute の機能を反映したものですが、Burst ではいち早く取り入れています。

その他の改善点

ここまで紹介したもの以外にも、Burst 1.5 では細かいながらも効果の大きな改善が行われています。

  • Burst の機能を使うコード内で ValueTuple 構造体((int, float))をサポートするようになりました。ただし、エントリーポイントの境界を越えない使い方に限定されます。例えば、ジョブの構造体に格納したり、関数ポインターから返したりすることはできません。
  • Burst 1.5 では、x86 組み込み関数の BMI1 と BMI2 を追加しました。AVX2 をサポートしている CPU であれば、これらのビット演算命令をコード内で直接使用できるようになります。
  • Unity 2020.2 以降のバージョンでは、Burst を使うコードから new ProfilerMarker("<マーカー名>") と呼び出すことができるようになりました。
  • プレイヤーのビルドに限定して、Burst の警告 BC1370 を再度有効化しました。この警告は、プレイヤーのビルドではサポートされていない、[Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS")] でガードされていない関数内での例外のスローが発生した場合に表示されます。
  • LLVM 11 をデフォルトのコード生成器として使用することで、stackalloc の巻き上げの最適化、無限ループの除去、コンパイル時間の改善などと共に、パフォーマンスの大幅な改善が図られています。

Unity 2018.4 をサポートする最終バージョン

Burst 1.5 は、Unity 2018.4 をサポートする最後のバージョンです。次期バージョンでは、Unity 2019.4 が最低要件となります。

Burst の使用を始める

Burst は、Unity の技術スタックの中核をなすもので、今すぐにでも使い始めることができます。Burst は、安定した検証済みのパッケージであり、すでに何千ものプロジェクトで採用され、またその採用実績を伸ばし続けています。DOTS 技術スタックは Burst を活用して高度に最適化されたコードを提供しますが、Burst は DOTS を使わず、独立したパッケージとしても利用できます。

デスクトップ、コンソール、モバイルの主要なプラットフォームをすべてサポートし、Unity 2018.4以降に対応しています。

ご意見、ご質問、また Burst を使って開発しているプロジェクトについての情報は、ぜひ Burst フォーラムまでお寄せください。

2021年4月14日 カテゴリ: Engine & platform | 5 分 で読めます

Is this article helpful for you?

Thank you for your feedback!

取り上げているトピック
関連する投稿