Способы визуализации данных о событиях в поисках проблем с производительностью

10

Я пытаюсь оптимизировать приложение MPI с высоко асинхронным шаблоном связи. Каждый ранг имеет список вещей для вычисления и отправляет сообщения по мере необходимости, если входы или выходы находятся на другом ранге. Кроме того, каждый ранг является многопоточным (в настоящее время с одним коммуникационным потоком и 5 рабочими).

Я снабдил код таймерами вокруг различных критически важных для кода частей кода, что дает мне список троек (начало, конец, тип) для каждого потока. Наглядным способом, со временем в качестве горизонтальной оси, рангом и нитью в качестве вертикали и цветом, указывающим, что в данный момент делает каждая нить, я получаю изображение, подобное этому, для 16 рангов с 6 нитями / ранг:

История Пентаго

Мой вопрос: каковы другие способы визуализации этих данных, которые могут помочь определить проблемы с производительностью? У кого-нибудь есть любимый тип графика, который они используют при профилировании асинхронных приложений?

Этот набор данных ограничен тем, что он не знает структуру потока данных, но я хотел бы получить как можно больше информации, прежде чем пытаться собрать что-то более сложное.

Несжатое изображение здесь, на случай, если кто-то захочет осмотреться (загрузка по обычному маршруту не удалась). К сожалению, Firefox не принимает его, хотя я считаю, что он действителен, возможно потому, что он просто слишком большой.

Джеффри Ирвинг
источник
У меня было немало проблем, чтобы заставить мой браузер или почти любую другую программу загрузить большое изображение. В конце концов, gimp сделал это, но вы можете пересмотреть размер или формат файла.
Педро
Прости за это. Я думаю, что изображение является действительным, так как Firefox выдает мне те же ошибки, что и при конвертировании (ImageMagick). Возможно, он превышает некоторый порог произвольного размера.
Джеффри Ирвинг

Ответы:

4

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

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

Поскольку вы используете гибридный подход с распределенной / распределенной памятью, я предполагаю, что ваш код находится в пробелах либо в ожидании вызова MPI, либо в переменной мьютекс / условие. Вы можете также обернуть эти вызовы таймерами, и это даст вам более полное представление о том, что вас тормозит, например, если оно всегда одинаково условно или всегда одинаково MPI_REDUCE, на котором застряли ваши потоки.

Частью программного обеспечения, которое я использую довольно часто, является Intel Vtune Amplifier XE . Он имеет приятную черту / опцию, которая визуализирует параллелизм потоков. Программа нарисует график, очень похожий на ваш, но когда поток ожидает мьютекс или переменную условия, он рисует диагональную линию из ожидающего потока, в то время как он начал ждать, к потоку, который фактически освободил мьютекс или дал сигнал условие, которого он ожидал, в то время, когда это было выпущено / сигнализировано. Это может быть довольно грязно, но это заставляет узкие места появляться немедленно.

Наконец, я также собираю статистические данные, например, для каждого мьютекса / сигнала / вызова MPI, каковы были среднее и максимальное время ожидания? Какова гистограмма собранных времен ожидания? Хотя сюжет дает вам хороший обзор, он может стать довольно грязным, когда дело доходит до мелких деталей.

Наконец, один вопрос, который не следует недооценивать: как вы собираете время? Ваш таймер достаточно навязчив, чтобы не влиять на ваш код? Я использую подсчет команд процессора всякий раз, когда это возможно, то есть RDTSCна архитектурах x86. Обычно это просто добавляет одну инструкцию к вашему коду.

Pedro
источник
У данных уже есть блоки вокруг всех ожиданий; на диаграмме они обозначены белым цветом для незанятых рабочих потоков и желтым цветом для ожидающих потоков связи. К сожалению, все ожидания в коммуникационном потоке происходят в одном общем MPI_Waitsome из-за асинхронности. Vtune в этом случае не применяется, поскольку чисто потоковая производительность по сути идеальна, но спасибо за указатель. Предложение гистограммы тоже хорошее.
Джеффри Ирвинг
Что касается временных затрат: я использую gettimeofday, который необходим по крайней мере вокруг свободных секций, так как там я использую переменные условия pthread. Можно ли заставить подсчет команд ЦП работать в такой ситуации? Накладные расходы уже достаточно низки, но более низкие, безусловно, будут лучше.
Джеффри Ирвинг
1
@ GeoffreyIrving: Да, вы можете использовать их, но они имеют смысл только на процессорах, у которых установлен constant_tscфлаг (проверьте /proc/cpuinfo) и если вы используете блокировку каждого потока на определенном ядре, то есть каждый поток всегда читает один и тот же регистр из одного и того же ядра, например, используя pthread_setaffinity_np. Обратите внимание, что последний зависит от Linux и, следовательно, не является переносимым.
Педро
@GeoffreyIrving: Даже если вы ожидаете какого-то нераскрытого события, используя его MPI_Waitsome, вы все равно можете записать, какие запросы действительно поступили и откуда. Эта информация может или не может быть полезна ...
Педро
5

Иногда вы можете получить альтернативное представление о проблемах производительности с помощью высокоуровневого анализа ресурсов: существует ли соответствующее узкое место, такое как пропускная способность памяти? Каждый рабочий поток выполняет одинаковое количество работы? Эти данные могут быть легко собраны с помощью likwid-perfctr из набора инструментов LIKWID Google Code проекта LIKWID . Если профиль таков, что существует много разных горячих точек, вам может потребоваться решить их один за другим. Также могут быть разные проблемы, в зависимости от того, сколько потоков / процессов используется.

Георг Хагер
источник
В интересах идеального раскрытия, Георг работает над проектом LIKWID, и я запросил этот ответ, потому что я хотел дополнить отличный ответ Педро с другой точки зрения (и отличный, свободно доступный инструмент).
Арон Ахмадиа
2

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

Важно увидеть, как это отличается от подходов, где вы измеряете, измеряете, измеряете. Единственное, что можно измерить, может сказать вам, куда не смотреть. Реальная настройка производительности требует тщательного изучения деталей с точки зрения времени. То, что вы ищете, это не то, где время потрачено, а где оно израсходовано без необходимости.

Удачи.

Майк Данлавей
источник
Другими словами, нет полезной визуализации данных, которые у меня есть. :) Джед Браун предложил Jumpshot (и связанные с ним утилиты) в качестве одного из способов сбора и визуализации предлагаемых вами данных, так что я рассмотрю это.
Джеффри Ирвинг
@Geof: удачи с визуализацией. Единственный инструмент, который я нашел бы полезным, - это что-то, чтобы собирать и объединять журналы событий, чтобы я мог следовать по пути одного или нескольких запросов, проходящих через различные потоки, потому что это единственный известный мне способ обнаружения ненужных задержки. Вот из чего состоит любая проблема производительности - ненужные задержки.
Майк Данлавей