MATLAB Language
multithreading
Zoeken…
Parfor gebruiken om een lus te parallelliseren
U kunt parfor
gebruiken om de iteraties van een lus parallel uit te voeren:
Voorbeeld:
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
Opmerking: parfor
kan niet direct worden genest. Gebruik voor parfor
nesting een functie in fisrt parfor
en voeg tweede parfor
in die functie.
Voorbeeld:
parfor i = 1:n
[op] = fun_name(ip);
end
function [op] = fun_name(ip)
parfor j = 1:length(ip)
% Some Computation
end
Wanneer parfor gebruiken
Kortom, parfor
wordt aanbevolen in twee gevallen: veel iteraties in je lus (bijv., Zoals 1e10
), of als elke iteratie erg lang duurt (bijv. eig(magic(1e4))
). In het tweede geval kunt u overwegen om spmd
. De reden waarom parfor
langzamer is dan een for
lus voor korte afstanden of snelle iteraties, is de overhead die nodig is om alle werknemers correct te beheren, in tegenstelling tot alleen het uitvoeren van de berekening.
Veel functies hebben ook een impliciete ingebouwde multi-threading , waardoor een parfor
lus bij gebruik van deze functies niet efficiënter is dan een seriële for
lus, omdat alle cores al worden gebruikt. parfor
zal in dit geval een nadeel zijn, omdat het de toewijzing overhead heeft, terwijl het even parallel is als de functie die u probeert te gebruiken.
Overweeg het volgende voorbeeld om het gedrag van for
in tegenstelling tot dat van parfor
. Open eerst de parallelle pool als u dit nog niet hebt gedaan:
gcp; % Opens a parallel pool using your current settings
Voer vervolgens een paar grote lussen uit:
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[-]';
Doe dan hetzelfde met parfor
plaats van for
. U zult merken dat de gemiddelde tijd per iteratie omhoog gaat. Realiseer je echter dat het parfor
alle beschikbare werkers heeft gebruikt, dus de totale tijd ( sum(Time)
) moet worden gedeeld door het aantal cores in je computer.
Dus, terwijl de tijd om elke afzonderlijke iteratie te doen omhoog gaat met behulp van parfor
met betrekking tot het gebruik for
, neemt de totale tijd aanzienlijk af.
Parallel uitvoeren van opdrachten met behulp van een "Single Program, Multiple Data" (SPMD) -instructie
In tegenstelling tot een parallelle for-loop ( parfor
), die de iteraties van een lus gebruikt en ze over meerdere threads verdeelt, neemt een enkele programma, multiple data ( spmd
) -instructie een reeks opdrachten en verdeelt ze over alle threads, zodat elke thread voert de opdracht uit en slaat de resultaten op. Overweeg dit:
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
Het is belangrijk op te merken dat elke thread tijdens het spmd
blok toegankelijk is via de spmd
(ook wel labindex
of 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
In beide voorbeelden is q
een samengesteld object , dat kan worden geïnitialiseerd met de opdracht q = Composite()
. Het is belangrijk op te merken dat samengestelde objecten alleen toegankelijk zijn terwijl de pool actief is.
Het batch-commando gebruiken om verschillende berekeningen parallel uit te voeren
Om multi-threading in MATLAB te gebruiken, kan men de batch
gebruiken. Merk op dat de Parallel Computing-toolbox geïnstalleerd moet zijn.
Voor een tijdrovend script bijvoorbeeld
for ii=1:1e8
A(ii)=sin(ii*2*pi/1e8);
end
om het in batch-modus uit te voeren zou men het volgende gebruiken:
job=batch("da")
waardoor MATLAB in batchmodus kan worden uitgevoerd en het mogelijk maakt om MATLAB in de tussentijd te gebruiken om andere dingen te doen, zoals meer batchprocessen toevoegen.
Om de resultaten op te halen na het voltooien van de taak en de array A
in de werkruimte te laden:
load(job, 'A')
Open tenslotte de "monitor job gui" vanuit Home → Omgeving → Parallel → Monitor jobs en verwijder de job door:
delete(job)
Om een functie voor batchverwerking te laden, gebruikt u eenvoudig deze instructie waarbij fcn
de functienaam is, N
aantal uitvoerarrays is en x1
, ...
, xn
zijn:
j=batch(fcn, N, {x1, x2, ..., xn})