特化直方圖

本指南說明如何使用 --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%

在此腳本中例項化了三個特化,即 doBooleandoObjectdoIntdoBoolean 特化只例項化和執行了一次,這佔此節點類別所有例項的 13% 和所有執行的 6%doObject 特化使用三種不同的輸入值組合來調用:DynamicObjectBasicIteratorRecordString。與特化類似,我們可以查看每個節點的使用次數以及執行次數。對於每一行,您都可以看到每個例項的最小、平均和最大執行次數。最後一欄會印出執行次數最多的例項的來源區段。

第二個表格會將節點類別使用的每種特化組合分組。

以下是一些您可能想要詢問這些特化統計資訊的問題

  1. 是否很少使用特定的特化組合,而且可以將其移除/合併為單一特化?
  2. 是否有具有非常常見類型組合的特化可以從進一步的特化中受益?
  3. 哪些特化組合很常見,並且值得擁有自己的特化?這可能表示程式碼中存在常見的多型,可以進行調查。
  4. 哪些是常見的特化,且順序是否與執行次數相符?最常用的特化應在節點類別中首先排序。這可能會提升直譯器的效能。
  5. 是否例項化了意料之外的特化?如果是,請使用列印的來源區段進一步調查。
  6. 哪些特化經常例項化,因此應該針對記憶體佔用空間進行最佳化?
  7. 設定檔中是否有名稱為 Uncached 的節點?應很少使用未快取的節點。如果它們經常被使用,則值得深入研究以了解原因。

與我們聯繫