MATLAB Language
Multihilo
Buscar..
Usando Parfor para paralelizar un bucle
Puede usar parfor
para ejecutar las iteraciones de un bucle en paralelo:
Ejemplo:
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
no puede ser anidado directamente. Para el anidamiento de parfor
use una función en parr parfor
y agregue el segundo parfor
en esa función.
Ejemplo:
parfor i = 1:n
[op] = fun_name(ip);
end
function [op] = fun_name(ip)
parfor j = 1:length(ip)
% Some Computation
end
Cuando usar parfor
Básicamente, se recomienda parfor
en dos casos: muchas iteraciones en su bucle (es decir, como 1e10
), o si cada iteración toma mucho tiempo (por ejemplo, eig(magic(1e4))
). En el segundo caso es posible que desee considerar el uso de spmd
. La razón parfor
es más lento que una for
lazo para distancias cortas o iteraciones rápidas es la sobrecarga necesaria para gestionar correctamente todos los trabajadores, en lugar de sólo hacer el cálculo.
Además, muchas funciones tienen un subprocesamiento múltiple implícito incorporado , lo que hace que un bucle parfor
no sea más eficiente, cuando se usan estas funciones, que un bucle serie for
bucle, ya que todos los núcleos ya están en uso. parfor
realmente será un detrimento en este caso, ya que tiene la sobrecarga de asignación, mientras que es tan paralelo como la función que está tratando de usar.
Considere el siguiente ejemplo para ver el comportamiento de for
en oposición al de parfor
. Primero abre la piscina paralela si aún no lo has hecho:
gcp; % Opens a parallel pool using your current settings
Luego ejecuta un par de bucles grandes:
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[-]';
Luego haz lo mismo con parfor
lugar de for
. Notarás que el tiempo promedio por iteración aumenta. Sin embargo, parfor
cuenta que el parfor
usó todos los trabajadores disponibles, por lo tanto, el tiempo total ( sum(Time)
) debe dividirse por el número de núcleos en su computadora.
Entonces, mientras que el tiempo para hacer cada iteración por separado aumenta usando parfor
con respecto a usar for
, el tiempo total disminuye considerablemente.
Ejecutar comandos en paralelo utilizando una declaración "Programa único, datos múltiples" (SPMD)
A diferencia de un bucle for paralelo ( parfor
), que toma las iteraciones de un bucle y las distribuye entre varios subprocesos, un solo programa, una declaración de datos múltiples ( spmd
) toma una serie de comandos y los distribuye a todos los subprocesos, de modo que cada uno El hilo ejecuta el comando y almacena los resultados. Considera esto:
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
Es importante señalar que cada hilo se puede acceder durante el spmd
bloque por su índice de hilo (también llamada índice de laboratorio, 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
En ambos ejemplos, q
es un objeto compuesto , que puede inicializarse con el comando q = Composite()
. Es importante tener en cuenta que los objetos compuestos solo son accesibles mientras se está ejecutando el grupo.
Usando el comando batch para hacer varios cálculos en paralelo
Para usar subprocesos múltiples en MATLAB, se puede usar el comando batch
. Tenga en cuenta que debe tener instalada la caja de herramientas de computación paralela.
Para un script que consume mucho tiempo, por ejemplo,
for ii=1:1e8
A(ii)=sin(ii*2*pi/1e8);
end
para ejecutarlo en modo batch deberías usar lo siguiente:
job=batch("da")
que permite que MATLAB se ejecute en modo por lotes y permite utilizar MATLAB mientras tanto para hacer otras cosas, como agregar más procesos por lotes.
Para recuperar los resultados después de finalizar el trabajo y cargar la matriz A
en el espacio de trabajo:
load(job, 'A')
Finalmente, abra la "interfaz de trabajo del monitor" desde Inicio → Entorno → Paralelo → Supervisar trabajos y eliminar el trabajo a través de:
delete(job)
Para cargar una función para el procesamiento por lotes, simplemente use esta declaración donde fcn
es el nombre de la función, N
es el número de matrices de salida y x1
, ...
, xn
son matrices de entrada:
j=batch(fcn, N, {x1, x2, ..., xn})