Recherche…


Utiliser parfor pour paralléliser une boucle

Vous pouvez utiliser parfor pour exécuter les itérations d'une boucle en parallèle:

Exemple:

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

Remarque: parfor ne peut pas être imbriqué directement. Pour parfor imbriquer, utilisez une fonction dans parfor et ajoutez un second parfor dans cette fonction.

Exemple:

parfor i = 1:n
[op] = fun_name(ip);
end

function [op] = fun_name(ip)
parfor j = 1:length(ip)
% Some Computation
end

Quand utiliser parfor

Fondamentalement, parfor est recommandé dans deux cas: beaucoup d'itérations dans votre boucle (comme 1e10 ), ou si chaque itération prend beaucoup de temps (par exemple, eig(magic(1e4)) ). Dans le second cas, vous pouvez envisager d'utiliser spmd . La raison parfor est plus lente qu'une for boucle pour les courtes distances ou itérations rapides est la surcharge nécessaire pour gérer correctement tous les travailleurs, plutôt que de faire tout le calcul.

En outre, de nombreuses fonctions parfor une fonction multi-threading implicite , ce qui parfor boucle parfor moins efficace lors de l'utilisation de ces fonctions qu'une boucle série for , car tous les cœurs sont déjà utilisés. parfor sera en fait un inconvénient dans ce cas, car il est parfor la surcharge tout en étant aussi parallèle que la fonction que vous essayez d'utiliser.

Prenons l'exemple suivant pour voir le comportement de for par opposition à celui de parfor . Ouvrez d'abord le pool parallèle si vous ne l'avez pas déjà fait:

gcp; % Opens a parallel pool using your current settings

Ensuite, exécutez quelques grandes boucles:

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[-]';

Ensuite, faites la même chose avec parfor au lieu de for . Vous remarquerez que le temps moyen par itération augmente. parfor cependant que le parfor utilisé tous les travailleurs disponibles, donc le temps total ( sum(Time) ) doit être divisé par le nombre de cœurs de votre ordinateur.

Ainsi, alors que le temps de faire chaque itération séparée augmente en utilisant parfor qui concerne l'utilisation de for , le temps total diminue considérablement.

Exécuter des commandes en parallèle à l'aide d'une instruction "Single Program, Multiple Data" (SPMD)

Contrairement à un parallèle for-loop ( parfor ), qui prend les itérations d'une boucle et les répartit entre plusieurs threads, un seul programme, une spmd multiple data ( spmd ) prend une série de commandes et les distribue à tous les threads, de sorte que chaque thread effectue la commande et stocke les résultats. Considère ceci:

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

Il est important de noter que chaque thread est accessible pendant le bloc spmd par son index de thread (également appelé index de laboratoire ou 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

Dans les deux exemples, q est un objet composite qui peut être initialisé avec la commande q = Composite() . Il est important de noter que les objets composites ne sont accessibles que lorsque le pool est en cours d'exécution.

Utilisation de la commande batch pour effectuer divers calculs en parallèle

Pour utiliser le multithreading dans MATLAB, vous pouvez utiliser la commande batch . Notez que la boîte à outils Parallel Computing doit être installée.

Pour un script long, par exemple,

for ii=1:1e8
   A(ii)=sin(ii*2*pi/1e8);
end

pour l'exécuter en mode batch, utilisez les éléments suivants:

job=batch("da")

ce qui permet à MATLAB de s'exécuter en mode batch et permet d'utiliser MATLAB entre-temps pour faire d'autres choses, telles que l'ajout de processus par lots.

Pour récupérer les résultats après avoir terminé le travail et charger le tableau A dans l'espace de travail:

load(job, 'A')

Enfin, ouvrez le "moniteur de travail" à partir de AccueilEnvironnementParallèleSurveiller les travaux et supprimez le travail via:

delete(job)

Pour charger une fonction pour le traitement par lots, utilisez simplement cette instruction où fcn est le nom de la fonction, N est le nombre de tableaux de sortie et x1 , ... , xn sont des tableaux d'entrée:

 j=batch(fcn, N, {x1, x2, ..., xn})


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow