Diferencia entre las páginas «Escalamiento» y «MATLAB Distrib Computing»

De NLHPC
(Diferencia entre las páginas)
 
 
Línea 1: Línea 1:
== Concepto de Escalamiento ==
== Beneficios ==
Cuando nos referimos al '''Escalamiento de un programa''', debemos apuntar al comportamiento del programa a medida que se ejecuta de manera paralela al tener mayor cantidad de procesadores para utilizar. De ser así, podemos considerar que el programa a utilizar permite ser escalable y podremos calcular su eficiencia.
Al usar este Toolbox permite ejecutar una tarea en múltiples CPU en un mismo nodo, con un '''máximo de 20 o 44 (dependiendo del nodo)''', la ventaja es que se mejora el rendimiento de una aplicación cuando se lanza en modo paralelo.


Entonces, el escalamiento de un programa será calculado a razón de un determinado rango de procesadores a utilizar, pero pasado ciertos niveles -según el programa-, no importará la cantidad de procesadores que podamos asignar, ya que su eficiencia no será la óptima, e incluso puede verse afectada de manera negativa.
== Comparación de parfor v/s for ==
Usaremos el siguiente código de ejemplo que utiliza la función [https://mathworks.com/help/matlab/ref/for.html for] v/s [https://mathworks.com/help/distcomp/parfor.html parfor], lanzaremos distintas tareas con diferentes parámetros para luego hacer una tabla comparativa de los resultados de los tiempos.


== Importancia del Escalamiento de Programas ==
'''for'''
La importancia respecto a cómo escalan los programas se debe al uso óptimo de recursos disponibles, permitiendo que cada usuario obtenga los resultados esperados en un mejor tiempo en comparación a trabajos secuenciales, como también sabiendo que una incorrecta asignación de recursos puede hacer que los resultados deseados se obtengan un mayor período de tiempo como también que la tarea falle.


Además, una incorrecta asignación de recursos no solo afectará al usuario que intenta ejecutar una tarea, ya que también afectará a los otros usuarios del Cluster que requieren poder de cómputo.
Código MATLAB para for:
 
Un escalamiento adecuado permitirá un uso eficiente de los recursos para la ejecución de nuestras tareas y las de todos.
 
== Calculando el Speedup y Eficiencia de mi programa ==
Para realizar el escalamiento de un programa, utilizaremos dos métricas: Speedup y Eficiencia.
 
El Speedup se obtiene calculando el cociente entre el tiempo de ejecución secuencial (1 proceso) y el tiempo de ejecución aumentando la cantidad de procesos asignados a la misma tarea.
<pre>speedup = tiempo 1 proceso / tiempo N procesos</pre>
 
 
La Eficiencia se obtiene calculando el cociente entre el Speedup y el Número de Procesos asignados a la tarea.
<pre>eficiencia = speedup / Número de Procesos</pre>
La realización de este ejercicio consta en modificar la cantidad de procesadores a utilizar y comparar sus tiempos de ejecución. Cada tarea ejecutada debe ser planeada según los recursos disponibles en las particiones que necesitamos utilizar, como también considerar la agrupación de tareas.
 
En nuestro siguiente ejemplo hemos ejecutado una tarea en la partición '''Slims''' y utilizado el software '''LAMMPS'''. Al ejecutarlo por primera vez, asignando un solo proceso( #SBATCH -n 1 ), el tiempo de ejecución alcanzó a 1 hora con 27 segundos.
 
El script utilizado fue:
<pre>
<pre>
#!/bin/bash
N = str2num(getenv('MATLAB_N'));
#SBATCH -J escalamiento
M = 1000;
#SBATCH -p slims
#SBATCH -n 1
#SBATCH --ntasks-per-node=1
#SBATCH --mail-user=$USER@nlhpc.cl
#SBATCH --mail-type=FAIL
#SBATCH -o escalamiento_%j.out
#SBATCH -e escalamiento_%j.err


ml purge
a = zeros(N,1);
ml intel
tic;
ml impi
for i = 1:N
ml icc
    a(i) = max(abs(eig(rand(M))));
ml LAMMPS/20Nov19
end


srun lmp_intel_cpu_intelmpi -in input-file/in.poly-bench
fprintf('\n\n for (N=%d): %f secs\n\n', N, toc);
</pre>
</pre>
En las siguientes iteraciones, en donde aumentamos el número de procesos, los tiempos de ejecución fueron bajando. Los parámetros que fueron siendo modificados fueron:
* Número de procesos (tareas en paralelo): -n X
* Número de tareas por nodo (aumentando según los límetes de la partición Slims): --ntasks-per-node=X
Por ejemplo, el script usado para la prueba con 128 procesos fue:


Script para lanzar la tarea:
<pre>
<pre>
#!/bin/bash
#!/bin/bash
#SBATCH -J escalamiento
#SBATCH --job-name=for_test
#SBATCH -p slims
#SBATCH --mail-user=usuario@correo.cl
#SBATCH -n 128
#SBATCH --mail-type=ALL
#SBATCH --ntasks-per-node=16
#SBATCH --output=%j_%x.out
#SBATCH --mail-user=$USER@nlhpc.cl
#SBATCH --error=%j_%x.err
#SBATCH --mail-type=FAIL
#SBATCH --partition=slims
#SBATCH -o escalamiento_%j.out
#SBATCH -n 20
#SBATCH -e escalamiento_%j.err
#SBATCH -L matlab # indico licencias a usar
#SBATCH --mem-per-cpu=2300


ml purge
module load MATLAB/2017a
ml intel
ml impi
ml icc
ml LAMMPS/20Nov19


srun lmp_intel_cpu_intelmpi -in input-file/in.poly-bench
export MATLAB_N=$1
matlab -nodisplay -nosplash -nodesktop < for.m
</pre>
</pre>


La siguiente es la tabla de comparación en relación a número de procesos, tiempo de ejecución, Speedup y Eficiencia:
'''parfor'''


<table class="wikitable">
Código MATLAB para parfor:
<pre>
pc = parcluster();
pc.JobStorageLocation = strcat('/tmp/', getenv('SLURM_JOB_ID'), '/lcj/');
parpool(pc, str2num(getenv('SLURM_CPUS_ON_NODE')));


<tbody><tr>
N = str2num(getenv('MATLAB_N'));
<th>Procesos <br> <code>-n</code></th>
M = 1000;
<th>Tareas por Nodo<br><code>--ntasks-per-node</code></th>
<th>Tiempo</th>
<th>Speedup</th>
<th>Eficiencia
</th></tr>
<tr>
<td>1</td>
<td>1</td>
<td>01:00:27</td>
<td>1</td>
<td>1
</td></tr>
<tr>
<td>2</td>
<td>2</td>
<td>00:33:47</td>
<td>1,8</td>
<td>0,9
</td></tr>
<tr>
<td>4</td>
<td>4</td>
<td>00:18:02</td>
<td>3,4</td>
<td>0,8
</td></tr>
<tr>
<td>8</td>
<td>8</td>
<td>00:09:13</td>
<td>6,6</td>
<td>0,8
</td></tr>
<tr>
<td>16</td>
<td>16</td>
<td>00:05:06</td>
<td>11,9</td>
<td>0,7
</td></tr>
<tr>
<td>32</td>
<td>16</td>
<td>00:02:31</td>
<td>24,0</td>
<td>0,8
</td></tr>
<tr>
<td>64</td>
<td>16</td>
<td>00:01:18</td>
<td>46,5</td>
<td>0,7
</td></tr>
<tr>
<td>128</td>
<td>16</td>
<td>00:00:48</td>
<td>75,6</td>
<td>0,6
</td></tr>
<tr>
<td>256</td>
<td>16</td>
<td>00:00:34</td>
<td>106,7</td>
<td>0,4
</td></tr>
<tr>
<td>500</td>
<td>20</td>
<td>00:00:31</td>
<td>117,0</td>
<td>0,2
</td></tr>
<tr>
<td>600</td>
<td>20</td>
<td>00:00:35</td>
<td>103,6</td>
<td>0,2
</td></tr>
<tr>
<td>700</td>
<td>20</td>
<td>00:00:35</td>
<td>103,6</td>
<td>0,1
</td></tr></tbody></table>


Una vez que hemos obtenido resultados suficientes, podemos graficar el comportamiento de nuestra tarea, obteniendo una comparativa entre Speedup v/s Eficiencia:
a = zeros(N,1);
tic;
parfor i = 1:N
    a(i) = max(abs(eig(rand(M))));
end


IMAGEN
fprintf('\n\n parfor (N=%d): %f secs\n\n', N, toc);
</pre>


Escalamiento-2022.png
Script para lanzar la tarea:
Es recomendable que la eficiencia que se busque siempre sea superior a 0,5 (con un décimal), por lo que el uso de más de 128 procesos o más, según nuestro ejemplo, serán descartados. Incluso podemos agregar que el uso de más de 256 procesos y más no representa una verdadera mejora, e incluso afectará la cola de trabajo evitando que otras tareas entren en ejecución.
<pre>
#!/bin/bash
#SBATCH --job-name=parfor_test
#SBATCH --mail-user=usuario@correo.cl
#SBATCH --mail-type=ALL
#SBATCH --output=%j_%x.out
#SBATCH --error=%j_%x.err
#SBATCH --partition=slims
#SBATCH -n 20
#SBATCH -L matlab,matlab-distrib_computing # indico licencias a usar
#SBATCH --mem-per-cpu=2300


Ante esto, es recomendable seleccionar 128 o 64 procesadores para optar a un tiempo menor de ejecución y a una mejor eficacia.
module load MATLAB/2017a


== Cuentas de Pruebas ==
mkdir -p /tmp/${SLURM_JOB_ID}/{lcj,mcr}
El NLHPC pone a disposición cuentas para la realización de Pruebas de Escalamiento.
export MCR_CACHE_ROOT=/tmp/${SLURM_JOB_ID}/mcr


Estas cuentas tienen las siguientes características:
export MATLAB_N=$1


500 cores
matlab -nodisplay -nosplash -nodesktop < parfor.m
6 horas de tiempo de ejecución
</pre>
100Gb de Almacenamiento
1 semana de duración
Pueden ser solicitadas desde nuestra página de SOLICITUD DE CUENTAS indicar que realizará la prueba de escalamiento.


=== Estudio de Escalamiento ===
para encolar las diferentes tareas
Es importante que si va a solicitar una cuenta en el Cluster del NLHPC, realice una prueba de escalamiento como la indicada anteriormente en donde se pueda medir el Speedup y la Eficiencia.
<pre>
 
for i in 400 600 800 1000 1200
Puede descargar la siguiente plantilla para ver un ejemplo y editarla con los datos de su aplicación.
    do sbatch script.sh $i
 
done
=== Ejecución de varias instancias de mi programa ===
</pre>
Una vez concluido tu estudio de escalamiento, podrás considerar una mayor cantidad de procesadores/cores a solicitar.
 
Siguiendo nuestro ejemplo anterior, si el valor máximo para una tarea es de 128 procesos en paralelo y teniendo la necesidad de ejecutar LAMMPS con 3 archivos distintos de entrada, podré solicitar 384 cores al momento de requerir mi cuenta.


=== Ejecución de distintos programas que escalen ===
== Tabla Comparativa ==
En el caso de que sea necesario ejecutar distintos programas que puedan ser paralelizables, lo ideal es que el cálculo de escalamiento sea realizado en el programa que más recursos requiera.


Siempre considera realizar pruebas que sean un reflejo a las tareas reales que ejecutarás de esta manera existirá una correlación con lo que reportes y el comportamiento en producción de tus tareas.
<p>&nbsp;</p>


== Programas secuenciales ==
<table align="center" border="1" cellpadding="1" cellspacing="1" style="height:419px; width:400px">
Si utilizará programas secuenciales que no soporten paralelización, no es necesario realizar el estudio de escalamiento.
<tr>
<th scope="col">N</th>
<th scope="col">parfor</th>
<th scope="col">for</th>
</tr>
<tr>
<td style="text-align:center">400</td>
<td style="text-align:center">37</td>
<td style="text-align:center">374</td>
</tr>
<tr>
<td style="text-align:center">600</td>
<td style="text-align:center">42</td>
<td style="text-align:center">557</td>
</tr>
<tr>
<td style="text-align:center">800</td>
<td style="text-align:center">54</td>
<td style="text-align:center">711</td>
</tr>
<tr>
<td style="text-align:center">1000</td>
<td style="text-align:center">&nbsp;66</td>
<td style="text-align:center">900</td>
</tr>
<tr>
<td style="text-align:center">1200</td>
<td style="text-align:center">88</td>
<td style="text-align:center">&nbsp;1479</td>
</tr>
</table>


En el caso de que reserve recursos a modo de intentar paralelizar una tarea secuencial, solo generará una reserva de recursos incorrecta, generando estados ociosos, los que son considerados subutilización y su tarea será cancelada.
<p>&nbsp;&nbsp;&nbsp;&nbsp;<br />
<br />
&nbsp;</p>


Y por último si necesita ejecutar varias tareas secuenciales, estas se podrán lanzar de manera simultanea aprovechando los recursos disponibles.
<p>&nbsp;</p>


== Pasos a seguir ==
Ya hemos visto el proceso de calcular el escalamiento de un programa, requerido para cuando soliciten cuentas en el Cluster del NLHPC.


Recuerda que las tareas de los usuarios son monitoreadas para dar un uso adecueado a los recursos. Si quieres saber más visita nuestra sección sobre Monitoreo De Tareas.
Los valores del tiempo de ejecución están expresados en segundos, para medir se ocupo la función [https://mathworks.com/help/matlab/ref/tic.html tic]/[https://mathworks.com/help/matlab/ref/toc.html toc]. En el caso de un vector de 400 elementos, con el uso de parfor presenta una mejora del 90% en tiempo respecto al uso de for.


== Enlaces de Interés ==
== Referencias ==
Introducción al paralelismo y al rendimiento
* [https://mathworks.com/products/parallel-computing.html Parallel Computing Toolbox]
Performance Metrics, Prediction, and Measurement
* [https://mathworks.com/help/distcomp/decide-when-to-use-parfor.html Decide When to Use parfor]
A Begginer's Guide to High-Performance Computing

Revisión del 21:21 7 sep 2022

Beneficios

Al usar este Toolbox permite ejecutar una tarea en múltiples CPU en un mismo nodo, con un máximo de 20 o 44 (dependiendo del nodo), la ventaja es que se mejora el rendimiento de una aplicación cuando se lanza en modo paralelo.

Comparación de parfor v/s for

Usaremos el siguiente código de ejemplo que utiliza la función for v/s parfor, lanzaremos distintas tareas con diferentes parámetros para luego hacer una tabla comparativa de los resultados de los tiempos.

for

Código MATLAB para for:

N = str2num(getenv('MATLAB_N'));
M = 1000;

a = zeros(N,1);
tic;
for i = 1:N
    a(i) = max(abs(eig(rand(M)))); 
end

fprintf('\n\n for (N=%d): %f secs\n\n', N, toc);

Script para lanzar la tarea:

#!/bin/bash
#SBATCH --job-name=for_test
#SBATCH --mail-user=usuario@correo.cl
#SBATCH --mail-type=ALL
#SBATCH --output=%j_%x.out
#SBATCH --error=%j_%x.err
#SBATCH --partition=slims
#SBATCH -n 20 
#SBATCH -L matlab # indico licencias a usar
#SBATCH --mem-per-cpu=2300

module load MATLAB/2017a

export MATLAB_N=$1
 
matlab -nodisplay -nosplash -nodesktop < for.m

parfor

Código MATLAB para parfor:

pc = parcluster();
pc.JobStorageLocation = strcat('/tmp/', getenv('SLURM_JOB_ID'), '/lcj/');
parpool(pc, str2num(getenv('SLURM_CPUS_ON_NODE')));

N = str2num(getenv('MATLAB_N'));
M = 1000;

a = zeros(N,1);
tic;
parfor i = 1:N
    a(i) = max(abs(eig(rand(M)))); 
end

fprintf('\n\n parfor (N=%d): %f secs\n\n', N, toc);

Script para lanzar la tarea:

#!/bin/bash
#SBATCH --job-name=parfor_test
#SBATCH --mail-user=usuario@correo.cl
#SBATCH --mail-type=ALL
#SBATCH --output=%j_%x.out
#SBATCH --error=%j_%x.err
#SBATCH --partition=slims 
#SBATCH -n 20
#SBATCH -L matlab,matlab-distrib_computing # indico licencias a usar
#SBATCH --mem-per-cpu=2300

module load MATLAB/2017a

mkdir -p /tmp/${SLURM_JOB_ID}/{lcj,mcr}
export MCR_CACHE_ROOT=/tmp/${SLURM_JOB_ID}/mcr

export MATLAB_N=$1

matlab -nodisplay -nosplash -nodesktop < parfor.m

para encolar las diferentes tareas

for i in 400 600 800 1000 1200
     do sbatch script.sh $i
done

Tabla Comparativa

 

N parfor for
400 37 374
600 42 557
800 54 711
1000  66 900
1200 88  1479

    

 

 


Los valores del tiempo de ejecución están expresados en segundos, para medir se ocupo la función tic/toc. En el caso de un vector de 400 elementos, con el uso de parfor presenta una mejora del 90% en tiempo respecto al uso de for.

Referencias