exponenta event banner

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

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

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

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 loop, то вы можете использовать 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 занимает одинаковое количество времени у всех работников. Рабочая нагрузка теперь распределена лучше.

См. также

| |