В этом примере показано, как профилировать параллельный код с помощью параллельного профилировщика для работников в параллельном пуле.
Создайте параллельный пул.
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 занимает одинаковое количество времени у всех работников. Рабочая нагрузка теперь распределена лучше.
