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

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

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

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

См. также

| |