В выводе node.js --prof, что делает эта функция со странным именем C ++? - PullRequest
0 голосов
/ 25 февраля 2020

Я профилирую сильно измененный форк JS Интерпретатор , работающий на node.js v12.12.0, использующий --prof, в то время как он запускает короткий синтетический тест c. В выводе `node --prof-process я вижу, что 63% времени выполнения программы тратится на C ++:

 [Summary]:
   ticks  total  nonlib   name
   1503   35.6%   35.9%  JavaScript
   2658   63.0%   63.4%  C++
    119    2.8%    2.8%  GC
     30    0.7%          Shared libraries
     29    0.7%          Unaccounted

В частности, есть одна функция C ++, на которую приходится 59% всего времени выполнения:

 [C++]:
   ticks  total  nonlib   name
   2504   59.3%   59.8%  t __ZN4node9inspector8protocol11NodeRuntime14DispatcherImplD1Ev
     27    0.6%    0.6%  T node::native_module::NativeModuleEnv::CompileFunction(v8::FunctionCallbackInfo<v8::Value> const&)
     23    0.5%    0.5%  T _proc_set_dirty
     16    0.4%    0.4%  T __kernelrpc_vm_remap
      9    0.2%    0.2%  t __malloc_initialize
      9    0.2%    0.2%  T _thread_get_state
      8    0.2%    0.2%  T node::contextify::ContextifyContext::CompileFunction(v8::FunctionCallbackInfo<v8::Value> const&)
  ...

К сожалению, для меня не слишком очевидно, что может делать __ZN4node9inspector8protocol11NodeRuntime14DispatcherImplD1Ev.

  • Название предполагает, что ему есть чем заняться с протоколом инспектора, но я не использую флаг командной строки --inspect и не пытаюсь подключиться к запущенному процессу с помощью инспектора.

  • Не удается найти файл в node.js источниках, которые содержат как строки "NodeRuntime", так и "DispatcherImpl".

  • Кажется, что он вызывается из нескольких разных мест, чаще всего рекурсивно из самого себя (список обрезан, чтобы показать в основном записи верхнего уровня), но названные функции JavaScript не имеют очевидной общности:

 [Bottom up (heavy) profile]:
  Note: percentage shows a share of a particular caller in the total
  amount of its parent calls.
  Callers occupying less than 1.0% are not shown.

   ticks parent  name
   2504   59.3%  t __ZN4node9inspector8protocol11NodeRuntime14DispatcherImplD1Ev
   1287   51.4%    t __ZN4node9inspector8protocol11NodeRuntime14DispatcherImplD1Ev
    785   61.0%      LazyCompile: *intrp.Object.defineProperty /Users/cpcallen/src/CodeCity/server/interpreter.js:4477:51
    226   17.6%      LazyCompile: *intrp.UserFunction.instantiateDeclarations /Users/cpcallen/src/CodeCity/server/interpreter.js:4840:66
     67    5.2%      LazyCompile: *intrp.Object.getOwnPropertyDescriptor /Users/cpcallen/src/CodeCity/server/interpreter.js:4455:61
     34    2.6%      t __ZN4node9inspector8protocol11NodeRuntime14DispatcherImplD1Ev
     22    1.7%      LazyCompile: *stepFuncs_.MemberExpression /Users/cpcallen/src/CodeCity/server/interpreter.js:6582:42
    278   11.1%    LazyCompile: *Interpreter.run /Users/cpcallen/src/CodeCity/server/interpreter.js:290:37
    140    5.6%    LazyCompile: *stepFuncs_.Identifier /Users/cpcallen/src/CodeCity/server/interpreter.js:6494:36
    121    4.8%    LazyCompile: *intrp.UserFunction.instantiateDeclarations /Users/cpcallen/src/CodeCity/server/interpreter.js:4840:66
     91    3.6%    LazyCompile: ~runBench /Users/cpcallen/src/CodeCity/server/tests/interpreter_bench.js:37:18
     79    3.2%    LazyCompile: *intrp.UserFunction.call /Users/cpcallen/src/CodeCity/server/interpreter.js:4782:47
     65    2.6%    LazyCompile: *Interpreter.getBoundNames_ /Users/cpcallen/src/CodeCity/server/interpreter.js:2907:48
     62    2.5%    LazyCompile: *stepFuncs_.CallExpression /Users/cpcallen/src/CodeCity/server/interpreter.js:6039:40

Я задавался вопросом, может ли это быть сборщик мусора, но используя --trace-gc показывает в G C занимает намного меньше 10% от общего времени выполнения.

Как я могу выяснить, что делает эта функция C ++?

1 Ответ

1 голос
/ 25 февраля 2020

Поиск DispatcherImpl не сложно: https://github.com/nodejs/node/search?q=dispatcherimpl&unscoped_q=dispatcherimpl ведет прямо к https://github.com/nodejs/node/blob/5aaa7fee2e4a075d9123b885f9e8cda3de2a780a/tools/inspector_protocol/templates/TypeBuilder_cpp.template#L218. Но это, вероятно, не то, что вы действительно ищете ...

Некоторое время в системе --prof была ошибка, из-за которой отметки C ++ могли быть отнесены к неправильной функции - похоже, что вы может столкнуться с этим. Это было исправлено в V8 , но это исправление еще не вошло в выпуск Node.

В качестве обходного пути на Linux вы можете использовать perf для профилирования C ++ код [1], все еще используя --prof для JavaScript; Тики JavaScript, а также распределение C ++ / JavaScript должны быть надежно правильными в выводе --prof. На других платформах должны быть эквивалентные общие c методы профилирования.

[1] Подробнее см. Справочную страницу. Я обычно использую что-то вроде:

perf record -e cycles -F 10000 <executable and arguments>
perf report -M intel
...