MATLAB Language
multithreading
Ricerca…
Usare parfor per parallelizzare un loop
Puoi usare parfor
per eseguire le iterazioni di un ciclo in parallelo:
Esempio:
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
Nota: parfor
non può essere annidato direttamente. Per parfor
nesting usa una funzione in parfor
e aggiungi un secondo parfor
in quella funzione.
Esempio:
parfor i = 1:n
[op] = fun_name(ip);
end
function [op] = fun_name(ip)
parfor j = 1:length(ip)
% Some Computation
end
Quando usare parfor
Fondamentalmente, il parfor
è raccomandato in due casi: molte iterazioni nel tuo loop (es. Come 1e10
), o se ogni iterazione richiede molto tempo (es. eig(magic(1e4))
). Nel secondo caso potresti prendere in considerazione l'utilizzo di spmd
. La ragione parfor
è più lenta di una for
ciclo per intervalli brevi o iterazioni veloci è l'overhead necessaria per gestire tutti i lavoratori correttamente, piuttosto che semplicemente eseguire il calcolo.
Anche molte funzioni hanno implicito multithreading incorporato , facendo una parfor
ciclo non più efficiente, quando si utilizzano queste funzioni, di una serie for
ciclo, poiché vengono già utilizzati tutti i core. in questo caso il parfor
sarà effettivamente un danno, poiché ha il sovraccarico di allocazione, pur essendo parallelo come la funzione che si sta tentando di utilizzare.
Considera il seguente esempio per vedere il comportamento di for
in contrasto con quello di parfor
. Prima apri il pool parallelo se non lo hai già fatto:
gcp; % Opens a parallel pool using your current settings
Quindi esegui un paio di loop di grandi dimensioni:
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[-]';
Quindi fai lo stesso con parfor
anziché for
. Noterai che il tempo medio per iterazione sale. Realizza comunque che il parfor
utilizzato tutti i lavoratori disponibili, quindi il tempo totale ( sum(Time)
) deve essere diviso per il numero di core nel tuo computer.
Quindi, mentre il tempo di fare ogni iterazione separata sale usando parfor
rispetto a usando for
, il tempo totale diminuisce considerevolmente.
Esecuzione di comandi in parallelo usando un'istruzione "Single Program, Multiple Data" (SPMD)
A differenza di un parallelo for-loop ( parfor
), che prende le iterazioni di un ciclo e li distribuisce tra più thread, un singolo programma, più dati ( spmd
), prende una serie di comandi e li distribuisce a tutti i thread, in modo che ciascuno thread esegue il comando e memorizza i risultati. Considera questo:
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
È importante notare che è possibile accedere a ciascun thread durante il blocco spmd
tramite il relativo indice di thread (denominato anche lab index o 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 entrambi gli esempi, q
è un oggetto composito , che può essere inizializzato con il comando q = Composite()
. È importante notare che gli oggetti compositi sono accessibili solo mentre il pool è in esecuzione.
Utilizzo del comando batch per eseguire vari calcoli in parallelo
Per usare il multi-threading in MATLAB si può usare il comando batch
. Si noti che è necessario che la toolbox Parallel Computing sia installata.
Per uno script che richiede molto tempo, ad esempio,
for ii=1:1e8
A(ii)=sin(ii*2*pi/1e8);
end
per eseguirlo in modalità batch si usa quanto segue:
job=batch("da")
che consente a MATLAB di funzionare in modalità batch e consente nel frattempo di utilizzare MATLAB per fare altre cose, come aggiungere ulteriori processi batch.
Per recuperare i risultati dopo aver terminato il lavoro e caricare l'array A
nell'area di lavoro:
load(job, 'A')
Infine, apri "monitor gui di lavoro" da Home → Ambiente → Parallela → Monitora i lavori ed elimina il lavoro tramite:
delete(job)
Per caricare una funzione per l'elaborazione batch, è sufficiente utilizzare questa istruzione dove fcn
è il nome della funzione, N
è il numero di matrici di output e x1
, ...
, xn
sono matrici di input:
j=batch(fcn, N, {x1, x2, ..., xn})