- JDK 23向けGraalVM (最新)
- JDK 24向けGraalVM (早期アクセス)
- JDK 21向けGraalVM
- JDK 17向けGraalVM
- アーカイブ
- 開発ビルド
- Truffle言語実装フレームワーク
- Truffleブランチインストルメンテーション
- 動的オブジェクトモデル
- 静的オブジェクトモデル
- インタプリタコードのホスト最適化
- Truffleの関数インライン化アプローチ
- Truffleインタプリタのプロファイリング
- Truffle Interop 2.0
- 言語実装
- Truffleを使用した新しい言語の実装
- JavaモジュールへのTruffle言語とインストルメントの移行
- Truffleネイティブ関数インターフェース
- Truffleインタプリタの最適化
- オプション
- オンスタック置換
- Truffle文字列ガイド
- 特殊化ヒストグラム
- DSL特殊化のテスト
- ポリグロットAPIベースのTCK
- コンパイルキューへのTruffleのアプローチ
- Truffleライブラリガイド
- Truffle AOTの概要
- Truffle AOTコンパイル
- 補助エンジンキャッシング
- Truffle言語セーフポイントチュートリアル
- モノモーフィゼーション
- 分割アルゴリズム
- モノモーフィゼーションのユースケース
- ポリモーフィック特殊化をランタイムに報告
Truffleインタプリタのプロファイリング
Truffleを使用して記述されたインタープリタをプロファイリングするためのツールは豊富にあります。JVMモードで実行する場合は、VisualVM、Java Flight Recorder、Oracle Developer Studioなどの標準のJVMツールを使用できます。ネイティブイメージで実行する場合は、Valgrindツールスイートのcallgrind
や、strace
などの他のシステムツールを使用できます。GraalVMで実行される言語として、他のGraalVMツールも使用できます。プロファイリングの広義の定義では、コンパイラの出力を検査するためにIdeal Graph Visualizer (IGV)やC1 Visualizerを使用することもできます。
このガイドは、各ツールの使用方法ではなく、基本的な使用法を理解していることを前提として、ツールから最も有用な情報を抽出するための提案に重点を置いています。
CPUサンプラーを使用したプロファイリング #
アプリケーションレベルをプロファイリングする最も簡単な方法は、例えば、どのゲスト言語関数で最も時間が費やされているかを調べるために、/tools
スイートの一部であり、GraalVMの一部であるCPUサンプラーを使用することです。言語ランチャーに--cpusampler
を渡すだけです。
language-launcher --cpusampler --cpusampler.Delay=MILLISECONDS -e 'p :hello'
ウォームアップ後にのみプロファイリングを開始するために、--cpusampler.Delay=MILLISECONDS
でサンプリング遅延を使用することをお勧めします。そうすることで、どの関数がコンパイルされて、どの関数がコンパイルされていないにもかかわらず、実行にかなりの時間がかかるかを簡単に特定できます。
language-launcher --help:tools
で、その他の--cpusampler
オプションを確認してください。
CPUサンプラーからコンパイルデータを取得する #
CPUサンプラーは、コンパイルされたコードに費やされた時間に関する情報を表示しません。これは、少なくとも部分的には、「コンパイルされたコード」では十分に説明できなくなったマルチティアコンパイルの導入によって動機付けられました。--cpusampler.ShowTiers
オプションを使用すると、ユーザーはコンパイルデータを見るかどうかを制御できるだけでなく、レポートで考慮する必要があるコンパイルティアを正確に指定できます。たとえば、--cpusampler.ShowTiers=true
を追加すると、以下に示すように、実行中に発生したすべてのコンパイルティアが表示されます。
-----------------------------------------------------------------------------------------------------------------------------------------------------------
Sampling Histogram. Recorded 553 samples with period 10ms.
Self Time: Time spent on the top of the stack.
Total Time: Time spent somewhere on the stack.
T0: Percent of time spent in interpreter.
T1: Percent of time spent in code compiled by tier 1 compiler.
T2: Percent of time spent in code compiled by tier 2 compiler.
-----------------------------------------------------------------------------------------------------------------------------------------------------------
Thread[main,5,main]
Name || Total Time | T0 | T1 | T2 || Self Time | T0 | T1 | T2 || Location
-----------------------------------------------------------------------------------------------------------------------------------------------------------
accept || 4860ms 87.9% | 31.1% | 18.3% | 50.6% || 4860ms 87.9% | 31.1% | 18.3% | 50.6% || ../primes.js~13-22:191-419
:program || 5530ms 100.0% | 100.0% | 0.0% | 0.0% || 360ms 6.5% | 100.0% | 0.0% | 0.0% || ../primes.js~1-46:0-982
next || 5150ms 93.1% | 41.7% | 39.4% | 18.8% || 190ms 3.4% | 100.0% | 0.0% | 0.0% || ../primes.js~31-37:537-737
DivisibleByFilter || 190ms 3.4% | 89.5% | 10.5% | 0.0% || 100ms 1.8% | 80.0% | 20.0% | 0.0% || ../primes.js~7-23:66-421
AcceptFilter || 30ms 0.5% | 100.0% | 0.0% | 0.0% || 20ms 0.4% | 100.0% | 0.0% | 0.0% || ../primes.js~1-5:0-63
Primes || 40ms 0.7% | 100.0% | 0.0% | 0.0% || 0ms 0.0% | 0.0% | 0.0% | 0.0% || ../primes.js~25-38:424-739
-----------------------------------------------------------------------------------------------------------------------------------------------------------
あるいは、以下に示すように、--cpusampler.ShowTiers=0,2
は、インタプリタ時間とティア2でコンパイルされたコードに費やされた時間のみを表示します。
-----------------------------------------------------------------------------------------------------------------------------------------
Sampling Histogram. Recorded 620 samples with period 10ms.
Self Time: Time spent on the top of the stack.
Total Time: Time spent somewhere on the stack.
T0: Percent of time spent in interpreter.
T2: Percent of time spent in code compiled by tier 2 compiler.
-----------------------------------------------------------------------------------------------------------------------------------------
Thread[main,5,main]
Name || Total Time | T0 | T2 || Self Time | T0 | T2 || Location
-----------------------------------------------------------------------------------------------------------------------------------------
accept || 5510ms 88.9% | 30.9% | 52.3% || 5510ms 88.9% | 30.9% | 52.3% || ../primes.js~13-22:191-419
:program || 6200ms 100.0% | 100.0% | 0.0% || 320ms 5.2% | 100.0% | 0.0% || ../primes.js~1-46:0-982
next || 5870ms 94.7% | 37.3% | 20.6% || 190ms 3.1% | 89.5% | 10.5% || ../primes.js~31-37:537-737
DivisibleByFilter || 330ms 5.3% | 100.0% | 0.0% || 170ms 2.7% | 100.0% | 0.0% || ../primes.js~7-23:66-421
AcceptFilter || 20ms 0.3% | 100.0% | 0.0% || 10ms 0.2% | 100.0% | 0.0% || ../primes.js~1-5:0-63
Primes || 20ms 0.3% | 100.0% | 0.0% || 0ms 0.0% | 0.0% | 0.0% || ../primes.js~25-38:424-739
-----------------------------------------------------------------------------------------------------------------------------------------
CPUサンプラーからフレームグラフを作成する #
CPUSamplerからのヒストグラム出力は非常に大きくなる可能性があり、分析が困難になります。さらに、フラット形式では、出力に情報がエンコードされていないため、コールグラフを分析することはできません。フレームグラフは、コールグラフ全体を表示します。その構造により、アプリケーションの時間がどこに費やされているかをかなり簡単に確認できます。
フレームグラフの作成は多段階のプロセスです。まず、JSONフォーマッタでアプリケーションをプロファイリングする必要があります。
language-launcher --cpusampler --cpusampler.SampleInternal --cpusampler.Output=json -e 'p :hello' > simple-app.json
標準ライブラリ関数などの内部ソースをプロファイリングする場合は、--cpusampler.SampleInternal=true
オプションを使用します。
JSONフォーマッタは、ヒストグラム形式では利用できないコールグラフ情報をエンコードします。ただし、この出力からフレームグラフを作成するには、コールスタックサンプルを単一行に折りたたむ形式に変換する必要があります。これは、Benoit DalozeのFlameGraphのフォークにあるstackcollapse-graalvm.rbを使用して行うことができます。
まだ行っていない場合は、このFlameGraphのフォークを親ディレクトリにクローンする必要があります。これで、スクリプトを実行して出力を変換し、SVGデータを生成するスクリプトにパイプできます。
../FlameGraph/stackcollapse-graalvm.rb simple-app.json | ../FlameGraph/flamegraph.pl > simple-app.svg
この時点で、ChromiumベースのWebブラウザでSVGファイルを開く必要があります。システムでは、SVGファイルのデフォルトのアプリケーションとして別の画像操作アプリケーションが構成されている場合があります。このようなアプリケーションにファイルを読み込むとグラフがレンダリングされる場合がありますが、フレームグラフのインタラクティブなコンポーネントは処理されない可能性があります。Firefoxも同様に機能する可能性がありますが、Chromiumベースのブラウザは現在、フレームグラフファイルに対するより優れたサポートとパフォーマンスを備えているようです。
Oracle Developer Studioを使用したプロファイリング #
Oracle Developer Studioには、GraalVMで使用できるパフォーマンスアナライザが含まれています。Developer StudioはOTNからダウンロードでき、執筆時点での現在のバージョン(12.6)は、本番環境での使用および商用アプリケーションの開発に対して永久的な無償ライセンスを提供しています。
Developer Studio Performance Analyzerの使用は簡単です。Developer StudioのバイナリへのパスをPATH
に含め、通常のコマンドラインの前にcollect
を付加します。例:
collect js mybenchmark.js
完了すると、コマンド実行のプロファイリングデータを含む「実験」(.er)ディレクトリが作成されます。デフォルトではtest.1.er
です。プロファイリング結果を表示するには、analyzer
ツールを使用します。
analyzer test.1.er
analyzer
GUIを使用すると、キャプチャされたプロファイリング情報を、アプリケーションのタイムライン、フラット関数リスト、コールツリー、フレームグラフなど、いくつかの異なる方法で表示できます。また、テキスト形式でプロファイリング情報を出力してさらに分析するために使用できるコマンドラインツールer_print
もあります。
詳細については、パフォーマンスアナライザドキュメントを参照してください。