Поиск…


Использование parfor для параллелизации цикла

Вы можете использовать parfor для выполнения итераций цикла параллельно:

Пример:

poolobj = parpool(2);       % Open a parallel pool with 2 workers 

s = 0;                      % Performing some parallel Computations
parfor i=0:9
    s = s + 1;
end
disp(s)                     % Outputs '10'

delete(poolobj);            % Close the parallel pool

Примечание: parfor не может быть вложен напрямую. Для parfor nesting используйте функцию в parse parfor и добавьте второй parfor в эту функцию.

Пример:

parfor i = 1:n
[op] = fun_name(ip);
end

function [op] = fun_name(ip)
parfor j = 1:length(ip)
% Some Computation
end

Когда использовать парфор

В принципе, parfor рекомендуется в двух случаях: много итераций в вашем цикле (например, 1e10 ), или если каждая итерация занимает очень много времени (например, eig(magic(1e4)) ). Во втором случае вы можете рассмотреть возможность использования spmd . Причина parfor медленнее , чем for цикла для коротких диапазонов или быстрых итераций накладных расходов , необходимых для управления всех работников правильно, а не просто делать расчет.

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

Рассмотрим следующий пример , чтобы увидеть поведение for в противоположность тому , что из parfor . Сначала откройте параллельный пул, если вы еще этого не сделали:

gcp; % Opens a parallel pool using your current settings

Затем выполните пару больших циклов:

n = 1000; % Iteration number
EigenValues = cell(n,1); % Prepare to store the data
Time = zeros(n,1);
for ii = 1:n
tic
    EigenValues{ii,1} = eig(magic(1e3)); % Might want to lower the magic if it takes too long
Time(ii,1) = toc; % Collect time after each iteration
end

figure; % Create a plot of results
plot(1:n,t)
title 'Time per iteration'
ylabel 'Time [s]'
xlabel 'Iteration number[-]';

Затем сделайте то же самое с parfor а не for . Вы заметите, что среднее время на итерацию увеличивается. Помните, однако, что parfor использует всех доступных работников, поэтому общее время ( sum(Time) ) должно быть разделено на количество ядер на вашем компьютере.

Таким образом, в то время как время , чтобы сделать каждую отдельную итерацию идет вверх , используя parfor относительно использования for , общее время значительно снижается.

Выполнение команд параллельно с помощью оператора «Single Program, Multiple Data» (SPMD)

В отличие от параллельного for-loop ( parfor ), который принимает итерации цикла и распределяет их между несколькими потоками, оператор одной программы, несколько данных ( spmd ) принимает серию команд и распределяет их по всем потокам, так что каждый thread выполняет команду и сохраняет результаты. Учти это:

poolobj = parpool(2);    % open a parallel pool with two workers

spmd
    q = rand(3);         % each thread generates a unique 3x3 array of random numbers
end

q{1}             % q is called like a cell vector
q{2}             % the values stored in each thread may be accessed by their index

delete(poolobj)  % if the pool is closed, then the data in q will no longer be accessible

Важно отметить, что каждый поток может быть доступен во время блока spmd по индексу потока (также называемому лабораторным индексом или labindex ):

poolobj = parpool(2);        % open a parallel pool with two workers

spmd
    q = rand(labindex + 1);  % each thread generates a unique array of random numbers
end

size(q{1})                   % the size of q{1} is 2x2
size(q{2})                   % the size of q{2} is 3x3

delete(poolobj)              % q is no longer accessible

В обоих примерах q представляет собой составной объект , который может быть инициализирован командой q = Composite() . Важно отметить, что составные объекты доступны только во время работы пула.

Используя командную команду для параллельного выполнения различных вычислений

Для того, чтобы использовать многопоточность в MATLAB можно использовать batch команду. Обратите внимание, что у вас должен быть установлен инструментарий Parallel Computing.

Например, для трудоемкого сценария,

for ii=1:1e8
   A(ii)=sin(ii*2*pi/1e8);
end

для запуска его в пакетном режиме можно использовать следующее:

job=batch("da")

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

Чтобы получить результаты после завершения задания и загрузить массив A в рабочую область:

load(job, 'A')

И, наконец, откройте «GUID для монитора» из « Домашняя» → « Среда» → « Параллельный» → « Задания монитора» и удалите задание с помощью:

delete(job)

Чтобы загрузить функцию для пакетной обработки, просто используйте этот оператор, где fcn - имя функции, N - количество выходных массивов, а x1 , ... , xn - входные массивы:

 j=batch(fcn, N, {x1, x2, ..., xn})


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow