補助エンジン・キャッシング

次のドキュメントでは、GraalVMの補助エンジン・キャッシュの仕組みについて説明します。

この機能は、Oracle GraalVMでのみ使用できます。GraalVM Community Editionでは、これらのオプションは使用できません。

概要

Truffleゲスト言語プログラムのウォームアップには、かなりの時間がかかることがあります。ウォームアップは、ピーク・パフォーマンスに達するまで、プログラムの実行のたびに繰り返される作業で構成されます。これには次の作業が含まれます:

  1. Truffle ASTデータ構造へのゲスト・アプリケーションのロードおよび解析。
  2. インタプリタでのゲスト・アプリケーションの実行およびプロファイリング。
  3. ASTのマシン・コードへのコンパイル。

単一のOSプロセス内で、明示的なエンジンを指定することで、ウォームアップ中に実行される作業を共有できます。これには、コンテキスト関連の最適化を無効にして、コンテキスト間でコードを共有する脱最適化を回避するための言語実装が必要です。補助エンジン・キャッシングは、コンテキスト関連の最適化を無効にするためのメカニズムをベースに、ASTおよび最適化済マシン・コードを備えたエンジンをディスクに保持できるようにした構成になっています。この方法で、新しいプロセスの最初のアプリケーション・コンテキストでウォームアップ中に実行される作業を大幅に削減できます。

SVM補助イメージ機能を使用して、必要なデータ構造をディスクに保持し、ロードします。イメージの保持には、コンパイルを実行する必要があるため、長い時間がかかる場合があります。ただし、ロードはできるだけ速く、通常はほぼ瞬時に行うように設計されています。これによってアプリケーションのウォームアップ時間が大幅に短縮されます。

スタート・ガイド

Oracle GraalVMをインストールしたら、まず補助エンジン・キャッシング機能を備えたイメージを(再)ビルドする必要があります。たとえば、補助エンジン・キャッシュ機能を追加することで、JavaScriptイメージを再ビルドできます:

graalvm/bin/native-image --macro:js-launcher -H:+AuxiliaryEngineCache -H:ReservedAuxiliaryImageBytes=1073741824

--macro引数の値は、ゲスト言語によって異なります。デフォルトでは、最大1 GBの補助イメージが可能です。最大サイズは、必要に応じて拡大または縮小できます。予約済バイト数は、アプリケーションによって消費されるメモリーに実際には影響しません。将来のバージョンでは、--macro:js-launcherマクロを使用すると、補助エンジン・キャッシュがデフォルトで有効になります。

JavaScriptランチャの再ビルド後に、この機能は次のように使用されます:

新しいファイルfib.jsを作成します:

function fib(n) {
   if (n == 1 || n == 2) {
       return 1;
   }
   return fib(n - 1) + fib(n - 2);
}
console.log(fib(32))

プロファイリング実行のエンジンをディスクに保持するには、次のコマンドラインを使用します:

graalvm/bin/js --experimental-options --engine.TraceCache=true --engine.CacheStore=fib.image fib.js

` –engine.TraceCache=true`オプションは任意指定であり、現在何が起こっているかを確認できます。

出力内容は次のようになります。

[engine] [cache] No load engine cache configured.
2178309
[engine] [cache] Preparing engine for store (compile policy hot)...
[engine] [cache] Force compile targets mode: hot
[engine] [cache] Prepared engine in 1 ms.
[engine] [cache] Persisting engine for store ...
[engine] [cache] Persisted engine in 20 ms.
[engine] [cache] Detecting changes (update policy always)...
[engine] [cache]     New image contains         1 sources and  82 function roots.
[engine] [cache]     Always persist policy.
[engine] [cache] Writing image to fib.image...
[engine] [cache] Finished writing 1,871,872 bytes in 4 ms.

次のコマンドを使用してディスクからエンジンをロードできるようになりました:

graalvm/bin/js --experimental-options --engine.TraceCache --engine.CacheLoad=fib.image fib.js

次のように出力されます:

[engine] [cache] Try loading image './fib.image'...
[engine] [cache] Loaded image in 0 ms. 1,871,872 bytes   1 sources  82 roots
[engine] [cache] Engine from image successfully patched with new options.
2178309
[engine] [cache] No store engine cache configured.

アプリケーションをウォームアップする必要がないため、アプリケーションの実行時間が大幅に短縮されます。

使用方法

キャッシュの格納およびロードの操作は、次のオプションを使用して制御できます:

--engine.CacheCompile=<policy>オプションを使用してイメージが格納される場合、ルートのコンパイルが強制されることがあります。サポートされているポリシーは次のとおりです:

デフォルトでは、コンパイル・キュー内のすべての開始されたコンパイルが完了して、保持されます。関数ルートがAOTコンパイル可能かどうかは、言語によって決まります。言語は、RootNode.prepareForAOT()を実装することにより、AOTをサポートします。

ロードと格納の両方の操作が--engine.UpdatePolicy=<policy>オプションを使用して設定されている場合は、更新ポリシーを指定できます。使用可能なポリシーは次のとおりです:

既知の制限事項

セキュリティに関する考慮事項

ディスクに保持されたすべてのデータは、コードのみを表し、グローバル変数などのアプリケーション・コンテキスト固有のデータは表しません。ただし、プロファイリングされたASTおよびコードには、Truffle ASTで実行された最適化のアーティファクトが含まれる場合があります。たとえば、ランタイム文字列が最適化に使用され、それによってエンジン・イメージに保持される可能性があります。

NativeImageでの開発およびデバッグ

NativeImageで補助エンジン・キャッシングを実行する際のデバッグに役立ついくつかのオプションがあります:

HotSpotでの開発およびデバッグ

これは、HotSpotでの補助イメージに関連する言語実装の問題をデバッグする場合に役立ちます。JVMモードのOracle GraalVMでは、この機能に関する問題のデバッグに使用できる追加オプションがあります。HotSpotでの部分ヒープの格納はサポートされていないため、これらのデバッグ機能はHotSpotでは使用できません。

たとえば:

js --experimental-options --engine.TraceCompilation --engine.DebugCacheTrace --engine.DebugCacheStore --engine.DebugCacheCompile=executed fib.js

次のように出力されます:

[engine] opt done         fib                                                         |ASTSize            32 |Time   231( 147+84  )ms |Tier             Last |DirectCallNodes I    6/D    8 |GraalNodes   980/ 1857 |CodeSize         7611 |CodeAddress 0x10e20e650 |Source       fib.js:2
2178309
[engine] [cache] Preparing debug engine for storage...
[engine] [cache] Force compile targets mode: executed
[engine] [cache] Force compiling 4 roots for engine caching.
[engine] opt done         @72fa3b00                                                   |ASTSize             3 |Time   211( 166+45  )ms |Tier             Last |DirectCallNodes I    2/D    1 |GraalNodes   500/ 1435 |CodeSize         4658 |CodeAddress 0x10e26c8d0 |Source            n/a
[engine] opt done         :program                                                    |ASTSize            25 |Time   162( 123+39  )ms |Tier             Last |DirectCallNodes I    1/D    1 |GraalNodes   396/ 1344 |CodeSize         4407 |CodeAddress 0x10e27fd50 |Source       fib.js:1
[engine] opt done         Console.log                                                 |ASTSize             3 |Time    26(  11+15  )ms |Tier             Last |DirectCallNodes I    0/D    0 |GraalNodes    98/  766 |CodeSize         2438 |CodeAddress 0x10e285710 |Source    <builtin>:1
[engine] [cache] Stored debug engine in memory.

これにより、コンパイルに関連する問題を迅速に反復でき、またJavaデバッガをアタッチできます。Javaデバッガは、--vm.Xdebug --vm.Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000を使用してアタッチできます。

HotSpotではエンジンのディスクへの書込みがサポートされていないため、永続化エンジンのロードをデバッグすることは、より困難です。ただし、ポリグロット埋込みAPIを使用して、ユニット・テストでこのユース・ケースをシミュレートすることは可能です。例として、com.oracle.truffle.enterprise.test.DebugEngineCacheTestクラスを参照してください。