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 HemMiljöParallellMonitor 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})


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow