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


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow