Выберите Between spmdparfor, и parfeval

Передача параллельного кода

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

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

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

Расчеты с parfeval лучше всего представлены как график, похожий на плату Kanban с блокированием. Обычно результаты собраны от рабочих после того, как расчет будет завершен. Можно собрать результаты выполнения a 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- цикл, чтобы выполнить 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- цикл, сумма после расчетов с parfeval, или gplus с spmd. Снова, определите номер испытаний (n) и матричный размер (для m- m матрица).

m = 1000;
n = 20;

Затем используйте parfor- цикл, чтобы выполнить 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- цикл, вы широковещательно передаете результат каждой итерации parfor- цикл всем рабочим. В отличие от этого, spmd вызовы gplus только однажды, чтобы сделать глобальную операцию сокращения, требуя меньше служебного. По сути, издержки для части сокращения вычисления O(n2) для spmd, и O(mn2) для parfor.

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

| |

Похожие темы