特化直方图

本指南解释了如何使用 --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 的节点?不缓存节点的用量应该很少。如果它们被频繁使用,那么深入探究原因可能是有价值的。

联系我们