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

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

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

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

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

Обычно сравнение рабочих с минимальными и максимальными общими временами выполнения полезно. Для этого нажмите Compare (макс. по сравнению с 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

В отчете выберите Compare (макс. по сравнению с min TotalTime), чтобы сравнить рабочих с минимальными и максимальными общими временами выполнения. Заметьте что на этот раз, несколько выполнения conv займите подобное количество времени во всех рабочих. Рабочая нагрузка теперь лучше распределяется.

Смотрите также

| |