В этом примере показано, как профилировать явную связь с ближайшей соседней лабораторией. Он иллюстрирует использование labSend
, labReceive
, и labSendReceive
, показывающий как медленный (неправильный), так и быстрый (оптимальный) способ реализации этого алгоритма. Задача исследуется с помощью параллельного профилировщика. Для начала работы с параллельным профилированием смотрите Профилирование Параллельного Кода.
Рисунки в этом примере получаются из 12-узлового кластера.
Пример кода включает явную коммуникацию. В MATLAB ® явная связь является синонимом прямого использования примитивов связи Parallel Computing Toolbox (например labSend
, labReceive
, labSendReceive
, labBarrier
). Проблемы эффективности, связанные с этим типом связи, если они не связаны с базовым оборудованием, может быть трудно проследить. С помощью параллельного профилировщика можно в интерактивном режиме идентифицировать многие из этих проблем. Важно помнить, что вы можете разделить различные части своей программы на отдельные функции. Это может помочь при профилировании, потому что некоторые данные собираются только для каждой функции.
Алгоритм, который мы профилируем, является ближайшим соседним шаблоном связи. Каждому работнику MATLAB нужны данные только от себя и одной соседней лаборатории. Этот тип параллельного шаблона данных хорошо поддается многим матричным проблемам, но при неправильном выполнении может быть ненужно медленным. Другими словами, каждая лаборатория зависит от данных, которые уже доступны в соседней лаборатории. Например, в кластере с четырьмя лабораториями лаборатория 1 хочет отправить некоторые данные в лабораторию 2 и нуждается в некоторых данных из лаборатории 4, поэтому каждая лаборатория зависит только от одной другой лаборатории:
1 зависит от - > 4
2 зависит от - > 1
3 зависит от - > 2
4 зависит от - > 3
Можно реализовать любой заданный алгоритм связи, используя labSend
и labReceive
. labReceive
всегда блокирует вашу программу, пока коммуникация не будет завершена, в то время как labSend
возможно, нет, если данные маленькие. Использование labSend
во-первых, в большинстве случаев не помогает.
Одним из способов достижения этого алгоритма является то, чтобы каждая лаборатория ждала получения, и только одна лаборатория запускает цепь связи, завершая отправку и затем получение. Кроме того, мы можем использовать labSendReceive
и на первый взгляд может быть неясно, что должна быть большое различие в эффективности.
Можно просмотреть код для pctdemo_aux_profbadcomm и pctdemo_aux_profcomm, чтобы увидеть полные реализации этого алгоритма. Посмотрите на первый файл и заметьте, что он использует labSend
и labReceive
для связи.
Это распространенная ошибка - начинать думать с точки зрения labSend
и labReceive
когда это не обязательно. Глядя на то, как это pctdemo_aux_profbadcomm
выполнение реализации даст нам лучшее представление о том, чего ожидать.
labSend
Реализацияspmd labBarrier; % to ensure the labs all start at the same time mpiprofile reset; mpiprofile on; pctdemo_aux_profbadcomm; end
Lab 1: sending to 2 Lab 2: receive from 1 Lab 3: receive from 2 Lab 4: receive from 3 Lab 5: receive from 4 Lab 6: receive from 5 Lab 7: receive from 6 Lab 8: receive from 7 Lab 9: receive from 8 Lab 10: receive from 9 Lab 11: receive from 10 Lab 12: receive from 11 Lab 1: receive from 12 Lab 6: sending to 7 Lab 7: sending to 8 Lab 8: sending to 9 Lab 9: sending to 10 Lab 10: sending to 11 Lab 11: sending to 12 Lab 12: sending to 1 Lab 2: sending to 3 Lab 3: sending to 4 Lab 4: sending to 5 Lab 5: sending to 6
mpiprofile viewer
Отображается сводный отчет по функциям. На этой странице вы можете увидеть время ожидания в коммуникациях как оранжевую полосу под заголовком Total Time Plot. Приведенные ниже данные показывают, что значительное количество времени было потрачено на ожидание. Посмотрим, как параллельный профилировщик помогает идентифицировать причины этих ожиданий.
В профилировщике Function Summary Report проверьте запись pctdemo_aux_profbadcomm и нажмите Compare max vs. min TotalTime. Наблюдайте большое оранжевое время ожидания, обозначенное под функцией iRecFromPrevLab
. Это раннее указание на то, что с соответствующей отправкой что-то не так, либо из-за проблем с сетью, либо из-за проблем с алгоритмом.
Используйте верхнюю таблицу панели инструментов, чтобы щелкнуть Plot All Per Worker Communication
. Первый рисунок в этом представлении показывает все данные, полученные каждой лабораторией. В этом примере каждая лаборатория получает одинаковый объем данных из предыдущей лаборатории, поэтому, похоже, это не проблема распределения данных. Второй рисунок показывает различные моменты времени связи, включая время ожидания связи. На третьем рисунке график Comm Waiting Time Per Worker показывает постепенное увеличение времени ожидания. Пример графика Comm Waiting Time Per Worker можно увидеть ниже с помощью кластера с 12 узлами. Хорошо вернуться и проверить, что происходит в лаборатории источников.
Просмотр того, что происходит в лаборатории 1. а.) В профилировщике нажмите Home. б) Щелкните значок верхнего уровня pctdemo_aux_profbadcomm
для перехода в Детализированный отчет Function. c.) Убедитесь, что выбран параметр Show function listing. д.) Прокрутите вниз и посмотрите, где лаборатория 1 проводит время и какие линии покрыты. e.) Для сравнения посмотрите на Линии, где больше всего времени было потрачено на таблицу и выберите последнюю лабораторию usinAAg в списке Перейти к работнику.
Чтобы увидеть все профилированные строки кода, прокрутите вниз до последнего элемента на странице. Пример этого аннотированного списка кода можно увидеть ниже.
Чтобы четко увидеть проблему с нашим использованием labSend
и labReceive
, посмотрите на следующий график Время ожидания приема комм из 12-узлового кластера.
На графике выше можно увидеть ненужное ожидание с помощью Plot All Per Worker Communication. Это время ожидания увеличивается из-за labReceive
блокирует до тех пор, пока соответствующий парный labSend
завершено. Следовательно, вы получаете последовательную связь, даже если последующие лаборатории нуждаются только в данных, которые берутся от ближайшего соседа labindex
.
labSendReceive
для реализации этого алгоритмаМожно использовать labSendReceive
отправлять и получать данные одновременно из лаборатории, от которой вы зависите, чтобы получить минимальное время ожидания. Смотрите это в исправленной версии шаблона связи, реализованной в pctdemo_aux_profcomm
. Очевидно, что использование labSendReceive
невозможно, если вам нужно получить данные перед отправкой. В таких случаях используйте labSend
и labReceive
для обеспечения хронологического порядка. Однако в таких случаях, как этот пример, когда нет необходимости получать данные перед отправкой, используйте labSendReceive
. Профилируем эту версию, не сбрасывая данные, собранные в предыдущей версии (используйте mpiprofile resume
).
spmd labBarrier; mpiprofile resume; pctdemo_aux_profcomm; end
Lab 1: sending to 2 receiving from 12 Lab 2: sending to 3 receiving from 1 Lab 3: sending to 4 receiving from 2 Lab 4: sending to 5 receiving from 3 Lab 5: sending to 6 receiving from 4 Lab 6: sending to 7 receiving from 5 Lab 7: sending to 8 receiving from 6 Lab 8: sending to 9 receiving from 7 Lab 9: sending to 10 receiving from 8 Lab 10: sending to 11 receiving from 9 Lab 11: sending to 12 receiving from 10 Lab 12: sending to 1 receiving from 11
mpiprofile viewer
Эта исправленная версия сокращает время ожидания до эффективного нуля. Чтобы увидеть это, нажмите Plot All Per Worker Communication после выбора pctdemo_aux_profcomm
. Тот же шаблон связи, описанный выше, теперь почти не тратит времени на ожидание использования labSendReceive
(см. график «Comm Waiting Time Per Worker» ниже).
Для каждого 2-D графика изображения схема раскраски нормирована к поставленной задаче. Поэтому не используйте схему раскраски на графике, показанном выше, чтобы сравнить с другими графиками, так как цвета нормализованы и зависят от максимального значения (видно в верхнем правом в коричневом цвете). В данном примере использование максимального значения является лучшим способом сравнить огромное различие во времени ожидания, когда мы используем pctdemo_aux_profcomm
вместо pctdemo_aux_profbadcomm
.