exponenta event banner

Выбрать между spmd, parfor, и parfeval

Обмен параллельным кодом

Для параллельного выполнения вычислений можно использовать parfor, parfeval, parfevalOnAll, или spmd. Каждая конструкция опирается на различные концепции параллельного программирования. Если требуется, чтобы работники общались во время вычислений, используйте parfeval, parfevalOnAll, или spmd.

  • Использовать parfeval или parfevalOnAll если код может быть разделен на набор задач, где каждая задача может зависеть от вывода других задач.

  • Использовать spmd если во время вычисления требуется связь между работниками.

Вычисления с помощью parfeval лучше всего представлены в виде графика, аналогично доске Канбана с блокировкой. Как правило, результаты собираются у работников после завершения вычислений. Можно собирать результаты выполнения parfeval операция с использованием afterEach или afterAll. Результаты обычно используются в дальнейших расчетах.

Вычисления с помощью spmd лучше всего представлены блок-схемой, аналогичной последовательности операций водопада. Выполняется работник пула spmd операторы называются лабораторией. Результаты могут быть собраны в лабораториях во время вычислений. Иногда лаборатории должны взаимодействовать с другими лабораториями, прежде чем они смогут завершить вычисления.

Если вы не уверены, спросите себя следующее: в рамках моего коммуникационного параллельного кода можно ли выполнить каждое вычисление без какого-либо общения между работниками? Если да, используйте parfeval. В противном случае используйте spmd.

Синхронная и асинхронная работа

При выборе между parfor, parfeval, и spmdрассмотрите, требуется ли для расчета синхронизация с клиентом.

parfor и spmd требовать синхронизации и, следовательно, запретить выполнение любых новых вычислений на клиенте MATLAB ® .parfeval не требует синхронизации, поэтому клиент может свободно выполнять другую работу.

Сравнение производительности многопоточности и ProcessPool

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

Вспомогательная функция clientFasterThanPool, перечисленных в конце этого примера, возвращает true если несколько исполнений выполняются на клиенте быстрее, чем parfor-луп. Синтаксис совпадает с parfeval: использовать дескриптор функции в качестве первого аргумента, количество выходов в качестве второго аргумента, а затем дать все необходимые аргументы для функции.

Сначала создайте локальный ProcessPool.

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

Проверьте, насколько быстро eig запускает функцию с помощью clientFasterThanPool поддерживающая функция. Создать анонимную функцию с помощью eig для представления вызова функции.

[~, t_client, t_pool] = clientFasterThanPool(@(N) eig(randn(N)), 0, 500)
t_client = 22.6243
t_pool = 4.9334

Параллельный пул вычисляет ответ быстрее, чем клиент. Разделиться t_client около maxNumCompThreads чтобы найти время, затраченное на поток на клиенте.

t_client/maxNumCompThreads
ans = 3.7707

Работники по умолчанию однопоточны. Результат показывает, что время, затраченное на поток, одинаково как для клиента, так и для пула, как значение t_pool приблизительно в 1,5 раза превышает значение t_client/maxNumCompThreads. eig функция не получает преимуществ от многопоточности.

Затем проверьте, насколько быстро lu запускает функцию с помощью clientFasterThanPool поддерживающая функция.

[~, t_client, t_pool] = clientFasterThanPool(@(N) lu(randn(N)), 0, 500)
t_client = 1.0225
t_pool = 0.4693

Параллельный пул обычно вычисляет ответ быстрее, чем клиент, если локальный компьютер имеет четыре или более ядер. Разделиться t_client около maxNumCompThreads , чтобы найти время, затраченное на поток.

t_client/maxNumCompThreads
ans = 0.1704

Этот результат указывает, что время, затраченное на поток, значительно меньше на клиенте, чем на пуле, поскольку значение t_pool приблизительно в 3 раза превышает значение t_client/maxNumCompThreads. Каждый поток используется в течение меньшего вычислительного времени, что указывает на то, что lu использует многопоточность.

Определение вспомогательной функции

Вспомогательная функция clientFasterThanPool проверяет, быстрее ли выполняется вычисление на клиенте, чем на параллельном пуле. В качестве ввода используется дескриптор функции fcn и переменное число входных аргументов (in1, in2, ...). clientFasterThanPool выполняет fcn(in1, in2, ...) как на клиенте, так и в активном параллельном пуле. В качестве примера, если вы хотите протестировать rand(500), дескриптор функции должен быть в следующей форме:

fcn = @(N) rand(N);

Затем используйте clientFasterThanPool(fcn,500).

function [result, t_multi, t_single] = clientFasterThanPool(fcn,numout,varargin)
    % Preallocate cell array for outputs
    outputs = cell(numout);
    
    % Client
    tic
    for i = 1:200
        if numout == 0
            fcn(varargin{:});
        else
            [outputs{1:numout}] = fcn(varargin{:});
        end
    end
    t_multi = toc;
    
    % Parallel pool
    vararginC = parallel.pool.Constant(varargin);
    tic
    parfor i = 1:200
        % Preallocate cell array for outputs
        outputs = cell(numout);
        
        if numout == 0
            fcn(vararginC.Value{:});
        else
            [outputs{1:numout}] = fcn(vararginC.Value{:});
        end
    end
    t_single = toc;
    
    % If multhreading is quicker, return true
    result = t_single > t_multi;
end

Сравнение производительности parfor, parfeval, и spmd

Используя spmd может быть медленнее или быстрее, чем использование parfor-циклы или parfeval, в зависимости от типа вычислений. Накладные расходы влияют на относительную производительность parfor-циклы, parfeval, и spmd.

Для набора задач, parfor и parfeval обычно работают лучше, чем spmd в этих условиях.

  • Вычислительное время, затраченное на задачу, не является детерминированным.

  • Вычислительное время, затрачиваемое на задачу, не является одинаковым.

  • Данные, возвращаемые из каждой задачи, невелики.

Использовать parfeval когда:

  • Требуется выполнить вычисления в фоновом режиме.

  • Каждая задача зависит от других задач.

В этом примере рассматривается скорость, с которой можно выполнять матричные операции при использовании parfor-луп, parfeval, и spmd.

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

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

Вычислить случайные матрицы

Проверьте скорость, с которой случайные матрицы могут быть сгенерированы с помощью parfor-луп, parfeval, и spmd. Установить количество пробных версий (n) и размер матрицы (для mоколо-m матрица). Увеличение числа испытаний улучшает статистику, используемую в более позднем анализе, но не влияет на сам расчет.

m = 1000;
n = 20;

Затем используйте parfor-loop для выполнения rand(m) один раз для каждого работника. Время каждого из n судебные разбирательства.

parforTime = zeros(n,1);
for i = 1:n
    tic;
    mats = cell(1,p.NumWorkers);
    parfor N = 1:p.NumWorkers
      mats{N} = rand(m);
    end
    parforTime(i) = toc;
end

Далее используйте parfeval выполнять rand(m) один раз для каждого работника. Время каждого из n судебные разбирательства.

parfevalTime = zeros(n,1);
for i = 1:n
    tic;
    f(1:p.NumWorkers) = parallel.FevalFuture;
    for N = 1:p.NumWorkers
      f(N) = parfeval(@rand,1,m);
    end
    mats = fetchOutputs(f, "UniformOutput", false)';
    parfevalTime(i) = toc;
    clear f
end

Наконец, используйте spmd выполнять rand(m) один раз для каждой лаборатории. Для получения подробной информации о лабораториях и выполнении команд на них с помощью spmdсм. раздел Запуск отдельных программ для нескольких наборов данных. Время каждого из n судебные разбирательства.

spmdTime = zeros(n,1);
for i = 1:n
    tic;
    spmd
        e = rand(m);
    end
    eigenvals = {e{:}};
    spmdTime(i) = toc;
end

Использовать rmoutliers для удаления отклонений из каждого испытания. Затем используйте boxplot для сравнения времени.

% Hide outliers
boxData = rmoutliers([parforTime parfevalTime spmdTime]);

% Plot data
boxplot(boxData, 'labels',{'parfor','parfeval','spmd'}, 'Symbol','')
ylabel('Time (seconds)')
title('Make n random matrices (m by m)')

Как правило, spmd требует больше накладных расходов на оценку, чем parfor или parfeval. Поэтому в данном случае с использованием parfor-луп или parfeval является более эффективным.

Вычислить сумму случайных матриц

Затем вычислите сумму случайных матриц. Это можно сделать, используя переменную сокращения с parfor-loop, сумма после вычислений с parfeval, или gplus с spmd. Снова задайте количество испытаний (n) и размер матрицы (для mоколо-m матрица).

m = 1000;
n = 20;

Затем используйте parfor-loop для выполнения rand(m) один раз для каждого работника. Вычислите сумму с помощью переменной уменьшения. Время каждого из n судебные разбирательства.

parforTime = zeros(n,1);
for i = 1:n
    tic;
    result = 0;
    parfor N = 1:p.NumWorkers
      result = result + rand(m);
    end
    parforTime(i) = toc;
end

Далее используйте parfeval выполнять rand(m) один раз для каждого работника. Использовать fetchOutputs на всех матрицах, затем используйте sum. Время каждого из n судебные разбирательства.

parfevalTime = zeros(n,1);
for i = 1:n
    tic;
    f(1:p.NumWorkers) = parallel.FevalFuture;
    for N = 1:p.NumWorkers
      f(N) = parfeval(@rand,1,m);
    end
    result = sum(fetchOutputs(f));
    parfevalTime(i) = toc;
    clear f
end

Наконец, используйте spmd выполнять rand(m) один раз для каждой лаборатории. Использовать gplus для суммирования всех матриц. Чтобы отправить результат только в первую лабораторию, установите дополнительный параметр targetlab аргумент для 1. Время каждого из n судебные разбирательства.

spmdTime = zeros(n,1);
for i = 1:n
    tic;
    spmd
        r = gplus(rand(m), 1);
    end
    result = r{1};
    spmdTime(i) = toc;
end

Использовать rmoutliers для удаления отклонений из каждого испытания. Затем используйте boxplot для сравнения времени.

% Hide outliers
boxData = rmoutliers([parforTime parfevalTime spmdTime]);

% Plot data
boxplot(boxData, 'labels',{'parfor','parfeval','spmd'}, 'Symbol','')
ylabel('Time (seconds)')
title('Sum of n random matrices (m by m)')

Для этого расчета spmd значительно быстрее, чем parfor-луп или parfeval. При использовании переменных сокращения в parfor-loop, вы транслируете результат каждой итерации parfor-закольцовывание ко всем работникам. Напротив, spmd требования gplus только один раз для выполнения операции глобального сокращения, требующей меньших затрат. Таким образом, накладные расходы для части сокращения в расчете составляют O (n2) дляspmdи O (mn2) дляparfor.

См. также

| |

Связанные темы