特殊化ヒストグラム
このガイドでは、--engine.SpecializationStatistics
オプションの使用方法について説明します。
特殊化ヒストグラムでは、Truffle DSLノードを特別な方法で生成する必要があります。したがって、標準の特殊化ヒストグラム・オプションを使用すると、次のように出力されます:
js --engine.SpecializationStatistics test.js
[engine] Specialization histogram:
No specialization statistics data was collected. Either no node with @Specialization annotations was executed or the interpreter was not compiled with -Atruffle.dsl.GenerateSpecializationStatistics=true e.g as parameter to the javac tool.
エラーのアドバイスに従って、インタプリタを再コンパイルします。mx
ユーザーの場合、これは次のように単純です:
mx build -c -A-Atruffle.dsl.GenerateSpecializationStatistics=true
再構築後、特殊化統計を使用できます。その間、IDEがソースを自動的に再コンパイルしないようにしてください。このチュートリアルでは、単純なtest.js
スクリプトを使用します:
function test() {
var array = [42, "", {}, []]
var globalVar = true;
for (element of array) {
globalVar = element;
}
}
test();
ここで、特殊化統計を有効にする必要があります。この例では、GraalVMのJavaScriptランチャを使用します:
js --experimental-options --engine.SpecializationStatistics test.js
スクリプトの実行後、各クラスのヒストグラムが出力されます。これらのヒストグラムは各ノードの実行の合計によって順序付けられますが、最も頻繁に使用されるノード・クラスが最後に出力されます。
これらは、test.js
の実行時に出力されるヒストグラムの一部です: (ノート: この出力はすでに古くなっている可能性があります。)
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Name Instances Executions Executions per instance
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
| JSWriteCurrentFrameSlotNodeGen 8 (17%) 18 (12%) Min= 1 Avg= 2.25 Max= 5 MaxNode= test.js~5-7:76-128
| doBoolean <boolean> 1 (13%) 1 (6%) Min= 1 Avg= 1.00 Max= 1 MaxNode= test.js~4:52-71
| doInt <int> 1 (13%) 1 (6%) Min= 1 Avg= 1.00 Max= 1 MaxNode= test.js~5-7:76-128
| doSafeIntegerInt 0 (0%) 0 (0%) Min= 0 Avg= 0.00 Max= 0 MaxNode= -
| doSafeInteger 0 (0%) 0 (0%) Min= 0 Avg= 0.00 Max= 0 MaxNode= -
| doLong 0 (0%) 0 (0%) Min= 0 Avg= 0.00 Max= 0 MaxNode= -
| doDouble 0 (0%) 0 (0%) Min= 0 Avg= 0.00 Max= 0 MaxNode= -
| doObject 7 (88%) 16 (89%) Min= 1 Avg= 2.29 Max= 5 MaxNode= test.js~5-7:76-128
| <DynamicObjectBasic> 6 (86%) 12 (75%) Min= 1 Avg= 2.00 Max= 5 MaxNode= test.js~5-7:76-128
| <IteratorRecord> 1 (14%) 1 (6%) Min= 1 Avg= 1.00 Max= 1 MaxNode= test.js~1-8:16-130
| <String> 2 (29%) 2 (13%) Min= 1 Avg= 1.00 Max= 1 MaxNode= test.js~5-7:76-128
| <Integer> 1 (14%) 1 (6%) Min= 1 Avg= 1.00 Max= 1 MaxNode= test.js~6:105-123
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------
| [doBoolean] 1 (13%) 1 (6%) Min= 1 Avg= 1.00 Max= 1 MaxNode= test.js~4:52-71
| [doInt, doObject] 1 (13%) 4 (22%) Min= 4 Avg= 4.00 Max= 4 MaxNode= test.js~5-7:76-128
| doInt 1 (100%) 1 (25%) Min= 1 Avg= 1.00 Max= 1 MaxNode= test.js~5-7:76-128
| doObject 1 (100%) 3 (75%) Min= 3 Avg= 3.00 Max= 3 MaxNode= test.js~5-7:76-128
| [doObject] 6 (75%) 13 (72%) Min= 1 Avg= 2.17 Max= 5 MaxNode= test.js~5-7:76-128
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Name Instances Executions Executions per instance
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
| JSReadCurrentFrameSlotNodeGen 8 (17%) 25 (17%) Min= 1 Avg= 3.13 Max= 5 MaxNode= test.js~5-7:76-128
| doBoolean 0 (0%) 0 (0%) Min= 0 Avg= 0.00 Max= 0 MaxNode= -
| doInt <no-args> 1 (13%) 1 (4%) Min= 1 Avg= 1.00 Max= 1 MaxNode= test.js~5:81-87
| doDouble 0 (0%) 0 (0%) Min= 0 Avg= 0.00 Max= 0 MaxNode= -
| doObject <no-args> 8 (100%) 24 (96%) Min= 1 Avg= 3.00 Max= 5 MaxNode= test.js~5-7:76-128
| doSafeInteger 0 (0%) 0 (0%) Min= 0 Avg= 0.00 Max= 0 MaxNode= -
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------
| [doInt, doObject] 1 (13%) 4 (16%) Min= 4 Avg= 4.00 Max= 4 MaxNode= test.js~5:81-87
| doInt 1 (100%) 1 (25%) Min= 1 Avg= 1.00 Max= 1 MaxNode= test.js~5:81-87
| doObject 1 (100%) 3 (75%) Min= 3 Avg= 3.00 Max= 3 MaxNode= test.js~5:81-87
| [doObject] 7 (88%) 21 (84%) Min= 1 Avg= 3.00 Max= 5 MaxNode= test.js~5-7:76-128
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
このヒストグラムでは、ノード・クラスごとに2つの内部表が出力されています。
1つ目の表は、特殊化と動的な型の組合せをグループ化したものです。たとえば、このヒストグラムでは、ノード・クラスJSWriteCurrentFrameSlotNodeGen
が8
回インスタンス化され、18
回実行されました。これは、インスタンス合計の20%
で、その実行のすべてのノード実行の11%
です。
このスクリプトでは、doBoolean
、doObject
およびdoInt
という3つの特殊化がインスタンス化されました。doBoolean
特殊化は、1回のみインスタンス化されて実行されました。これは、このノード・クラスのすべてのインスタンスの13%
およびすべての実行の6%
を占めます。doObject
特殊化は、DynamicObjectBasic
、IteratorRecord
およびString
の3つの異なる入力値の組合せを使用して呼び出されました。特殊化と同様に、ノード当たりのこれらの使用回数および実行回数を確認できます。行ごとに、インスタンス当たりの最小、平均および最大実行回数を確認できます。最後の列には、実行回数が最大のインスタンスのソース・セクションが出力されます。
2つ目の表は、ノード・クラスで使用された特殊化の組合せごとにグループ化したものです。
これらの特殊化統計に関する質問を次にいくつか示します:
- 特定の特殊化の組合せはほとんど使用されないため、それを削除するか、統合して単一の特殊化にすることはできますか。
- さらなる特殊化のメリットを得られる可能性のある、非常に一般的な型の組合せを使用した特殊化はありますか。
- どの特殊化の組合せが一般的で、その独自の特殊化に価値はありますか。これは、調査可能なコードの一般的な多相性を示している可能性があります。
- 一般的な特殊化とは何ですか。また、その順序は実行回数と一致しますか。最も一般的に使用される特殊化は、ノード・クラスの最初に順序付ける必要があります。これにより、インタプリタのパフォーマンスが向上する可能性があります。
- 予期しないインスタンス化された特殊化はありますか。ある場合は、出力されたソース・セクションを使用してさらに調査します。
- 頻繁にインスタンス化されるため、メモリー・フットプリント用に最適化する必要がある特殊化はどれですか。
- プロファイルに
Uncached
という名前のノードはありましたか。キャッシュされていないノードが使用されることはめったにありません。それらが頻繁に使用されている場合は、その理由を詳しく調べることをお薦めします。