Неизвестные события в nodejs/v8 flashgraph с использованием perf_events

Я пытаюсь выполнить профилирование nodejs с использованием Linux perf_events, как описано Brendan Gregg здесь.

Последовательность действий:

  • запустите node > 0.11.13 с --perf-basic-prof, который создает файл /tmp/perf-(PID).map, в котором записано отображение символов JavaScript.
  • Захват стеков с помощью perf record -F 99 -p `pgrep -n node` -g -- sleep 30
  • Сложите стеки с помощью stackcollapse-perf.pl script из этот репозиторий
  • Генерировать диаграмму пламени svg с помощью flamegraph.pl script

Я получаю следующий результат (который выглядит очень красиво в начале): enter image description here

Проблема в том, что существует много элементов [unknown], которые, я полагаю, должны быть моими вызовами функции nodejs. Я предполагаю, что весь процесс терпит неудачу в точке 3, где перфорированные данные должны быть свернуты с помощью сопоставлений, созданных с помощью node/v8, выполненных с помощью --perf-basic-prof. Создается файл /tmp/perf-PID.map, и в процессе выполнения node записывается некоторое сопоставление.

Как решить эту проблему?

Я использую CentOS 6.5 x64 и уже пробовал это с помощью node 0.11.13, 0.11.14 (как для предварительной сборки, так и для компиляции) без успеха.

Ответ 1

В общем, что означает "[неизвестно]", то сэмплер не может определить имя функции, потому что это системная или библиотечная функция. Если да, то ОК - вам все равно, потому что вы ищете вещи, ответственные за время в вашем коде, а не системный код.

На самом деле, я предлагаю, что это один из тех вопросов XY. Даже если вы получите прямой ответ на то, что вы спросили, это, вероятно, малопригодно. Вот почему:

1. Профилирование ЦП малоприменимо в связанной с I/O программе

Две башни слева на вашем графике пламени делают I/O, поэтому они, вероятно, занимают гораздо больше времени на стене, чем большая куча справа. Если этот график пламени был получен из образцов настенных времен, а не образцов времени процессора, он мог бы походить на второй график ниже, который сообщает вам, где время фактически идет:

enter image description here

То, что было большой сочной смотровой кучкой справа, сократилось, так что она нигде не столь значительна. С другой стороны, башни ввода/вывода очень широкие. Любая из этих широких оранжевых полос, если это в вашем коде, представляет собой шанс сэкономить много времени, если некоторые из операций ввода-вывода можно было бы избежать.

2. Независимо от того, связана ли программа с CPU или I/O-привязкой, возможности ускорения могут легко скрываться от диаграмм пламени

Предположим, что есть некоторая функция Foo, которая действительно делает что-то расточительное, что, если бы вы знали об этом, вы могли бы исправить. Предположим, что в графе пламени темно-красный цвет. Предположим, что он вызван из многих мест в коде, поэтому он не все собрано в одном месте на графе пламени. Скорее он появляется в нескольких небольших местах, показанных здесь черными контурами:

enter image description here

Обратите внимание, что если все эти прямоугольники были собраны, вы могли видеть, что на него приходится 11% времени, то есть стоит посмотреть. Если вы можете сократить время в два раза, вы можете сэкономить 5,5% в целом. Если на самом деле его можно полностью избежать, вы можете сэкономить 11% в целом. Каждый из этих маленьких прямоугольников будет сжиматься до нуля и вытащить остальную часть графика справа от него.

Теперь я покажу вам метод, который я использую. Я беру умеренное количество выборок случайных стеков и изучаю каждый из них для подпрограмм, которые могут быть ускорены. Это соответствует взятию образцов на диаграмме пламени следующим образом:

enter image description here

Строгие вертикальные линии представляют собой двадцать выборок стека случайного времени. Как вы можете видеть, три из них отмечены X. Это те, которые проходят через Foo. Это о правильном числе, потому что 11% раз 20 равно 2.2.

(Confused? OK, здесь немного вероятность для вас. Если вы переверните монету 20 раз, и у нее есть 11% -ный шанс набрать головы, сколько голов вы получите? Технически это биномиальное распределение. вероятный номер, который вы получите, равен 2, следующие, скорее всего, числа 1 и 3. (Если вы получаете только 1, вы продолжаете идти, пока не получите 2.) Здесь распределение:)

введите описание изображения здесь

(Среднее количество образцов, которые вы должны увидеть, чтобы увидеть Foo дважды, равно 2/0,11 = 18,2 сэмпла.)

Глядя на эти 20 образцов, может показаться немного сложным, потому что они работают от 20 до 50 уровней. Тем не менее, вы можете в принципе игнорировать весь код, который не принадлежит вам. Просто изучите их для своего кода. Вы точно увидите, как вы проводите время, и у вас будет очень грубое измерение того, сколько. Глубокие стеки - плохая новость и хорошие новости - они означают, что у кода вполне может быть много места для ускорений, и они показывают вам, что это такое.

Все, что вы видите, что вы можете ускорить, если вы видите его более чем на одном образце, даст вам здоровое ускорение, гарантированное. Причина, по которой вам нужно увидеть его более чем на одном примере, - если вы только видите его на одном образце, вы знаете, что его время не равно нулю. Если вы видите это по нескольким образцам, вы все равно не знаете, сколько времени требуется, но вы знаете, что это не мало. Вот статистика.

Ответ 2

Вообще говоря, это плохая идея не согласиться с экспертом по предмету, но (с большим уважением) здесь мы идем!

SO вызывает ответ, чтобы сделать следующее:

"Пожалуйста, не забудьте ответить на вопрос. Сообщите подробности и поделитесь своими исследованиями!"

Итак, вопрос был, по крайней мере, в моей интерпретации, почему существуют [неизвестные] кадры в представлении perf script (и как мне превратить эти [неизвестные] кадры в значимые имена)? Этот вопрос может касаться "как улучшить производительность моей системы?" но я не вижу этого в этом конкретном случае. Здесь существует настоящая проблема о том, как перфорированные данные были обработаны после обработки.

Ответ на вопрос заключается в том, что хотя правильность настройки правильная: правильная версия node, правильный аргумент присутствовал для генерации имен функций (-perf-basic-prof), сгенерированных Файл перфорации должен принадлежать root для perf script для получения ожидаемого результата.

Что это!

Написав некоторые новые скрипты сегодня, я ударил apon, это направило меня на этот вопрос SO.

Вот несколько дополнительных ссылок:

https://yunong.io/2015/11/23/generating-node-js-flame-graphs/

https://github.com/jrudolph/perf-map-agent/blob/d8bb58676d3d15eeaaf3ab3f201067e321c77560/bin/create-java-perf-map.sh#L22

[иногда могут быть принудительно заблокированы файлы без root) http://www.spinics.net/lists/linux-perf-users/msg02588.html