Профилирование параллельного кода

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

Для параллельного профилирования вы используете mpiprofile команда подобно тому, как вы используете profile.

Параллельный код профиля

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

Создайте параллельный пул.

numberOfWorkers = 3;
pool = parpool(numberOfWorkers);
Starting parallel pool (parpool) using the 'local' profile ...
Connected to the parallel pool (number of workers: 3).

Сбор данных параллельного профиля путем включения mpiprofile.

mpiprofile on

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

values = [5 12 13 1 12 5];
tic;
parfor idx = 1:numel(values)
    u = rand(values(idx)*3e4,1);
    out(idx) = max(conv(u,u));
end
toc
Elapsed time is 31.228931 seconds.

После завершения кода просмотрите результаты из параллельного профилировщика, вызвав mpiprofile viewer. Это действие также останавливает набор данных профиля.

mpiprofile viewer

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

Как правило, сравнение работников с минимальными и максимальными общими временами выполнения полезно. Для этого в отчете щелкните Сравнить (max vs. min TotalTime). В этом примере наблюдайте, что conv выполняется несколько раз и занимает у одного работника значительно больше времени, чем у другого. Это наблюдение предполагает, что нагрузка может быть распределена не равномерно между работниками.

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

values = values(randperm(numel(values)));
  • Если вы знаете рабочую нагрузку каждой итерации в своей parfor цикл, тогда можно использовать parforOptions для управления разбиением итераций на подобласти значений для рабочих процессов. Для получения дополнительной информации смотрите parforOptions.

В этом примере, чем больше values(idx) Таким образом, чем более интенсивна в вычислительном отношении итерация. Каждая последовательная пара значений в values уравновешивает низкую и высокую вычислительную интенсивность. Чтобы лучше распределить рабочую нагрузку, создайте набор parfor опции для разделения parfor итерации в подобласти значений размера 2.

opts = parforOptions(pool,"RangePartitionMethod","fixed","SubrangeSize",2);

Включите параллельный профилировщик.

mpiprofile on

Запустите тот же код, что и раньше. Как использовать parfor опции, передайте их во второй входной параметр parfor.

values = [5 12 13 1 12 5];
tic;
parfor (idx = 1:numel(values),opts)
    u = rand(values(idx)*3e4,1);
    out(idx) = max(conv(u,u));
end
toc
Elapsed time is 21.077027 seconds.

Визуализируйте результаты параллельного профилировщика.

mpiprofile viewer

В отчете выберите Сравнить (max vs. min TotalTime), чтобы сравнить работников с минимальными и максимальными общими временами выполнения. Заметьте, что на этот раз, множества потоков выполнения conv взять аналогичное количество времени у всех работников. Теперь рабочая нагрузка распределена лучше.

Анализ данных параллельного профиля

Профилировщик собирает информацию о выполнении кода на каждом работнике и коммуникациях между работниками. Такая информация включает в себя:

  • Время выполнения каждой функции для каждого работника.

  • Время выполнения каждой строки кода в каждой функции.

  • Объем данных, переданных между каждым работником.

  • Количество времени, которое каждый рабочий проводит в ожидании связи.

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

parpool
Starting parallel pool (parpool) using the 'MyCluster' profile ...
Connected to the parallel pool (number of workers: 64).
R1 = rand(5e4,'distributed');
R2 = rand(5e4,'distributed');
mpiprofile on
R = R1*R2;
mpiprofile viewer

Последняя команда открывает окно Profiler, сначала показывая сводные данные параллельных профилей (или сводный отчет по функциям) для работника 1.

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

Заголовок столбцаОписание
ВызовыСколько раз функция вызывалась для этого работника
Общее времяОбщее количество времени, потраченного этим работником на выполнение этой функции
Собственное времяВремя, которое этот работник провел в этой функции, а не в дочерних или локальных функциях
Общее время коммОбщее время, потраченное этим работником на передачу данных другим работникам, включая время ожидания получения данных
Время ожидания Self CommВремя, потраченное этим работником во время выполнения этой функции в ожидании получения данных от других работников
Итого межрабочих данныхОбъем данных, переданных этому работнику и от него для этой функции
Коэффициент времени расчетаОтношение времени, потраченного в расчете для этой функции, к общему времени (которое включает в себя время связи) для этой функции
Общий график времениШтриховой график, показывающий относительный размер Self Time, Self Comm Waiting Time и Total Time для этой функции на этом работнике

Выберите имя любой функции в списке для получения дополнительной информации о выполнении этой функции. Функция детализированного отчета для codistributor1d.hMtimesImpl включает это объявление:

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

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

В следующем списке из сводного отчета показан результат использования Automatic Comparison Selection Compare (max vs. min TotalTime). Сравнение показывает данные от работника 50 по сравнению с работником 62, потому что это работники, которые тратят больше всего или меньше времени на выполнение кода.

На следующем рисунке показаны сводные данные всех функций, выполненных за время набора профиля. Manual Comparison Selection max Time Aggregate означает, что данные от всех работников для всех функций, чтобы определить, какой работник потратил максимальное время на каждую функцию. Рядом с именем каждой функции находится рабочий процесс, которому потребовалось самое длительное время для выполнения этой функции. В других столбцах перечислены данные от этого работника.

Следующий рисунок показывает сводный отчет для работников, которые тратят наибольшее и наименьшее время для каждой функции. Manual Comparison Selection max Time Aggregate против min Time >0 Aggregate сгенерировали эти сводные данные. Обе совокупные настройки указывают, что профилировщик должен учитывать данные от всех работников для всех функций, как максимальных, так и минимальных. В этом отчете перечислены данные для codistributor1d.hMtimesImpl от рабочих 50 и 62, потому что они потратили на эту функцию максимальное и минимальное время. Точно так же перечислены и другие функции.

Выберите имя функции в сводном списке сравнения, чтобы получить подробное сравнение. Подробное сравнение для codistributor1d.hMtimesImpl выглядит следующим образом, отображая линейные данные от обоих работников:

Чтобы увидеть графики коммуникационных данных, выберите Plot All Per Worker Communication в меню Show Figures. В верхнем фрагменте отчета о представлении графика показано, сколько данных каждый работник получает друг от друга работником для всех функций.

Чтобы увидеть только график времени межработнической связи, выберите Plot Communication Time Per Worker в меню Show Figures.

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