MATLAB Language
Многопоточность
Поиск…
Использование 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})