ユーザ用ツール

サイト用ツール


it技術:dotnet:nativeaot

NativeAOT

.NETネイティブ

.NETネイティブ(Native) とは、.NET を対象とするアプリケーションは、特定のプログラミング言語で記述され、中間言語(IL)にコンパイルされます。この中間言語(IL)を完全にコンパイルして直接ネイティブコードを生成する技術となります。
実行時に中間言語(IL)からコンパイルするJIT(Just-In-Time)と違い、実行前にコンパイルするので事前コンパイラAOT(Ahead-Of-Time)と呼ばれます。

.NET の生産性の高さと、ネイティブコードのハイパフォーマンスを入手できることができる一挙両得の技術として注目されています。

NativeAOTとは

ILを完全にネイティブコードに落とし込むオープンソースプロジェクト
https://www.cnblogs.com/hez2010/p/dotnet-with-native-aot.html

2021年以降は、NativeAOTリポジトリ
https://github.com/dotnet/runtimelab/tree/feature/NativeAOT
※将来的にはメインプロジェクトに統合される予定

2020年以前は、corertリポジトリ(CoreRT)
https://github.com/dotnet/corert
※corert自体は実験的プロジェクトで、実用する際は注意が必要なものだった。

注意点

このテクノロジーは、リフレクションにあまり依存できないため少し制限があります。

NativeAOTの準備

C++ ビルドツール

マイクロソフト C++ ビルドツールのインストール
https://visualstudio.microsoft.com/ja/visual-cpp-build-tools/

C++ によるデスクトップ開発

Visual Studioのインストールする環境の選択画面にてワークロードタブに「C++によるデスクトップ開発」にチェックを入れ、「インストール」をクリックします。
https://sukkiri.jp/technologies/ides/visual-studio-community/vs_com_win_install.html

https://stackoverflow.com/questions/45702/how-to-compile-a-net-application-to-native-code

NativeAOTのメモ

イメージがネイティブか判断

対象のexeが、.NET(managed)で作られたか判断
イメージがネイティブであるか CLR であるかを確認する

cd "C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin"
dumpbin /clrheader xxxx.exe

dumpbinでは、mspdb80.dllが必用
mspdb80.dllは、”C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE“などにある。

結果
File Type: EXECUTABLE IMAGE
 
  Summary
 
       F1000 .data
      88B000 .managed
       BF000 .pdata
      AA9000 .rdata
       67000 .reloc
        1000 .rsrc
       D9000 .text
        1000 _RDATA

イメージサイズ縮小

TestIF.exe 21.9 MB(23,029,760 バイト)あるので、サイズを縮小する幾つかのオプションを追加した結果 8.81 MB (9,247,232 バイト)と減らすことが出来た。
ただし、最適化前の速度が平均 570ms に対して、最適化後の速度が平均 1660ms と約3倍遅くなった。

TestIF.csproj
<PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>disable</Nullable>
 
    <!-- https://github.com/dotnet/corert/blob/master/Documentation/using-corert/optimizing-corert.md -->
    <IlcOptimizationPreference>Size</IlcOptimizationPreference>
    <RootAllApplicationAssemblies>false</RootAllApplicationAssemblies>
    <IlcGenerateCompleteTypeMetadata>false</IlcGenerateCompleteTypeMetadata>
    <IlcGenerateStackTraceData>false</IlcGenerateStackTraceData>
    <IlcDisableReflection>true</IlcDisableReflection>
    <IlcFoldIdenticalMethodBodies>true</IlcFoldIdenticalMethodBodies>
    <IlcDisableUnhandledExceptionExperience>false</IlcDisableUnhandledExceptionExperience>
</PropertyGroup>

IlcOptimizationPreference Size
最適化されたコードを生成するときは、小さいコードサイズを優先します。

IlcOptimizationPreference Speed
最適化されたコードを生成するときは、コードの実行速度を優先します。

RootAllApplicationAssemblies デフォルト:true
一部のリフレクションコーディングの使用法との互換性のために、コンパイラが未使用のコードを削除しないようにします。このオプションをfalseに設定すると、実行可能ファイルのサイズが小さくなります。

IlcGenerateCompleteTypeMetadata デフォルト:true
実行可能ファイルからオブジェクトにアクセスする場合に、メタデータタイプの生成を許可します。このオプションをfalseに設定すると、実行可能ファイルのサイズが小さくなります。

IlcGenerateStackTraceData デフォルト:true
スタックトレースでのテキスト名の生成を許可します。このオプションをfalseに設定すると、実行可能ファイルのサイズが小さくなります。

IlcDisableReflection デフォルト:false
リフレクションフリーモードは、CoreRTコンパイラとランタイムのモードであり、リフレクションAPIの機能を大幅に削減
https://github.com/dotnet/corert/blob/master/Documentation/using-corert/reflection-free-mode.md

IlcFoldIdenticalMethodBodies デフォルト:false
このオプションは、同一のメソッド本体を折りたたむ(メソッド本体の重複排除)。このオプションをtrueに設定すると、実行可能ファイルのサイズが小さくなります。しかし、予期しない動作が発生する可能性があります。

IlcDisableUnhandledExceptionExperience
未処理の例外のスタックトレースをコンソールに出力するコードを無効にします。

IlcInvariantGlobalization デフォルト:false
英語以外のカルチャをサポートするコードとデータを削除するグローバリゼーション不変モードを有効にします。コードとデータを削除すると、アプリが小さくなります。
https://github.com/dotnet/corert/blob/master/Documentation/using-corert/optimizing-corert.md

Linux-Arm および Linux-Arm64 サポート対象外

2021/11/08現在、ラズベリーパイ用にNativeAOTでコンパイルしたが、「error : Cross-OS native compilation is not supported. https://github.com/dotnet/corert/issues/5458」なった。

dotnet publish -r linux-arm64 -c release
or
dotnet publish -r linux-arm -c release

参照

it技術/dotnet/nativeaot.txt · 最終更新: 2021/12/09 02:39 by yajuadmin