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 HomeAmbienteParallelaMonitora 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})


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow