MATLAB Language
multithreading
Sök…
Använd parfor för att parallellisera en slinga
Du kan använda parfor
att utföra iterationerna av en slinga parallellt:
Exempel:
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
Obs: parfor
kan inte kapslas direkt. För parfor
använda en funktion i fisrt parfor
och lägga till andra parfor
i den funktionen.
Exempel:
parfor i = 1:n
[op] = fun_name(ip);
end
function [op] = fun_name(ip)
parfor j = 1:length(ip)
% Some Computation
end
När man ska använda parfor
I parfor
rekommenderas parfor
i två fall: massor av iterationer i din slinga (dvs. som 1e10
), eller om varje iteration tar mycket lång tid (t.ex. eig(magic(1e4))
). I det andra fallet kanske du vill överväga att använda spmd
. Anledningen till att parfor
är långsammare än en for
loop för korta intervall eller snabba iterationer är den överhead som behövs för att hantera alla arbetare korrekt, i motsats till att bara göra beräkningen.
Många funktioner har också implicit inbyggd parfor
, vilket gör en parfor
inte mer effektiv när man använder dessa funktioner än en serie for
slinga, eftersom alla kärnor redan används. parfor
kommer faktiskt att vara till nackdel i det här fallet, eftersom det har allokeringsomkostningen, samtidigt som den är lika parallell som den funktion du försöker använda.
Tänk på följande exempel för att se beteendet hos for
motsats till parfor
. Öppna först den parallella poolen om du inte redan har gjort det:
gcp; % Opens a parallel pool using your current settings
Kör sedan ett par stora slingor:
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
samma sak med parfor
istället for
. Du kommer att märka att den genomsnittliga tiden per iteration går upp. Förstår dock att parfor
använde alla tillgängliga arbetare, och därför parfor
den totala tiden ( sum(Time)
) delas med antalet kärnor i din dator.
Så, medan tiden för varje separat iteration går upp med parfor
gäller att använda for
, går den totala tiden betydligt ner.
Utföra kommandon parallellt med ett "Single Program, Multiple Data" (SPMD) uttalande
Till skillnad från en parallell för-loop ( parfor
), som tar iterationerna av en slinga och fördelar dem mellan flera trådar, tar ett enskilt program, flera data ( spmd
) uttalande en serie kommandon och distribuerar dem till alla trådar, så att varje tråd utför kommandot och lagrar resultaten. Tänk på detta:
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
Det är viktigt att notera att varje tråd kan nås under spmd
blocket genom dess trådindex (även kallad labindex
eller 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
I båda exemplen är q
ett sammansatt objekt som kan initialiseras med kommandot q = Composite()
. Det är viktigt att notera att sammansatta objekt endast är tillgängliga medan poolen är igång.
Använd batch-kommandot för att göra olika beräkningar parallellt
För att använda flertrådar i MATLAB kan man använda batch
kommandot. Observera att du måste ha verktygslådan Parallell Computing installerad.
För ett tidskrävande skript, till exempel,
for ii=1:1e8
A(ii)=sin(ii*2*pi/1e8);
end
för att köra den i batch-läge skulle man använda följande:
job=batch("da")
vilket gör det möjligt för MATLAB att köra i batchläge och gör det möjligt att använda MATLAB under tiden för att göra andra saker, till exempel att lägga till fler batchprocesser.
Så här hämtar du resultaten efter att jobbet har slutförts och laddat matrisen A
i arbetsytan:
load(job, 'A')
Slutligen öppnar du "monitor job gui" från Hem → Miljö → Parallell → Monitor jobb och raderar jobbet genom:
delete(job)
För att ladda en funktion för batchbehandling, använd bara detta uttalande där fcn
är funktionsnamnet, N
är antal utmatningsmatriser och x1
, ...
, xn
är inmatningsmatriser:
j=batch(fcn, N, {x1, x2, ..., xn})