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


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow