- 適用於 JDK 23 的 GraalVM (最新)
- 適用於 JDK 24 的 GraalVM (搶先體驗)
- 適用於 JDK 21 的 GraalVM
- 適用於 JDK 17 的 GraalVM
- 封存
- 開發建置
- Truffle 語言實作框架
- Truffle 分支檢測
- 動態物件模型
- 靜態物件模型
- 直譯器程式碼的主機最佳化
- Truffle 的函式內聯方法
- 分析 Truffle 直譯器
- Truffle Interop 2.0
- 語言實作
- 使用 Truffle 實作新的語言
- Truffle 語言和工具遷移至 Java 模組
- Truffle 原生函式介面
- 最佳化 Truffle 直譯器
- 選項
- 堆疊上替換
- Truffle 字串指南
- 特化直方圖
- 測試 DSL 特化
- 基於多語言 API 的 TCK
- Truffle 的編譯佇列方法
- Truffle 函式庫指南
- Truffle AOT 概觀
- Truffle AOT 編譯
- 輔助引擎快取
- Truffle 語言安全點教學
- 單態化
- 分割演算法
- 單態化使用案例
- 向執行階段回報多型特化
特化直方圖
本指南說明如何使用 --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
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
直方圖會為每個節點類別印出兩個內部表格。
第一個表格會將特化和動態類型組合分組。例如,在此直方圖中,節點類別 JSWriteCurrentFrameSlotNodeGen
已例項化 8
次,並執行了 18
次。這佔總例項的 20%
和此執行中所有節點執行的 11%
。
在此腳本中例項化了三個特化,即 doBoolean
、doObject
和 doInt
。doBoolean
特化只例項化和執行了一次,這佔此節點類別所有例項的 13%
和所有執行的 6%
。doObject
特化使用三種不同的輸入值組合來調用:DynamicObjectBasic
、IteratorRecord
和 String
。與特化類似,我們可以查看每個節點的使用次數以及執行次數。對於每一行,您都可以看到每個例項的最小、平均和最大執行次數。最後一欄會印出執行次數最多的例項的來源區段。
第二個表格會將節點類別使用的每種特化組合分組。
以下是一些您可能想要詢問這些特化統計資訊的問題
- 是否很少使用特定的特化組合,而且可以將其移除/合併為單一特化?
- 是否有具有非常常見類型組合的特化可以從進一步的特化中受益?
- 哪些特化組合很常見,並且值得擁有自己的特化?這可能表示程式碼中存在常見的多型,可以進行調查。
- 哪些是常見的特化,且順序是否與執行次數相符?最常用的特化應在節點類別中首先排序。這可能會提升直譯器的效能。
- 是否例項化了意料之外的特化?如果是,請使用列印的來源區段進一步調查。
- 哪些特化經常例項化,因此應該針對記憶體佔用空間進行最佳化?
- 設定檔中是否有名稱為
Uncached
的節點?應很少使用未快取的節點。如果它們經常被使用,則值得深入研究以了解原因。