MATLAB Language
Multithreading
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 Accueil → Environnement → Parallèle → Surveiller 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})