1. Avance 2.1: Simulación concurrente
1.1. Repositorio y archivos
El proyecto 2, sobre paralelismo de datos con concurrencia y distribución declarativa, se realiza por los mismos equipos del proyecto 1. Se entrega en el mismo repositorio del proyecto, y siguiendo los mismos lineamientos de la sección "Repositorio y archivos" estipulados en el enunciado del avance 1.1, con las siguientes diferencias:
-
En el proyecto 1 se trabaja con un código heredado, mientras que en el proyecto 2 el equipo parte "desde cero", es decir, creando una base de código propia.
-
Para el proyecto 2 se crea una carpeta en la raíz del repositorio del equipo, la cual tendrá la estructura de un proyecto de software como se ha hecho en las tareas del curso. Esto incluye las conocidas carpetas para el código fuente (ej.:
src/
), archivos intermedios (ej.:build
), un método de construcción automática de la solución (ej.:Makefile
), documentación (e.j:Doxyfile
, entre otros. -
Todos los miembros del equipo deben participar de forma equitativa en ambos proyectos y reflejarlo en el historial de control de versiones, tanto en commits como branches. No serán aceptados desequilibrios de la forma "Juan y María hicieron el proyecto 1, mientras que Ana y Daniel hicieron el proyecto 2" porque estarían declarando incumplir los objetivos del curso y naturalmente tendría implicaciones en la evaluación del mismo.
-
Una vez completado este avance 2.1 etiquetar el commit con
avance21
(o en inglésmilestone21
).
1.2. Análisis del problema
Se debe crear un documento de análisis readme.ext
, donde la extensión depende del tipo de documento (Markdown, AsciiDoc o LaTeX), en la raíz de la carpeta para el proyecto. En este documento se ha de explicar el problema a resolver, el cual se enuncia en la siguiente secciónl. Incluya una sección "Construcción de la solución" (en inglés, "Build") sobre cómo compilar el código.
Agregar en una sección "Manual de usuario" cómo ejecutar la aplicación, describir los parámetros, y la salida esperada. Conviene agregar ejemplos con salidas textuales (preferible) o capturas de pantalla. Explicar el formato de los archivos usados por el programa para ayudar a los usuarios investigadores a emplear la simulación.
1.2.1. Transferencia de calor
Se necesita una sencilla simulación por computadora que ayude a encontrar el momento de equilibro térmico de una lámina rectangular a la que se le inyecta calor constante por su borde. La lámina (en inglés, plate) corresponde a un rectángulo de dos dimensiones de un mismo material. Para efectos de la simulación, el rectángulo es dividido en \$R\$ filas y \$C\$ columnas ambas de igual alto y ancho \$h\$ como se ve en la Figura 1. Esto genera una matriz cuyas celdas son todas cuadradas, de ancho y alto \$h\$.
Cada celda de la matriz almacena una temperatura, la cual puede cambiar en el tiempo. Se usa la notación \$T_{i,j}^k\$ para indicar la temperatura de la celda ubicada en la fila \$i\$, columna \$j\$, en el instante o estado \$k\$. Después de transcurrido un tiempo \$\Delta t\$, la simulación pasará del instante \$k\$ al instante \$k+1\$, y la temperatura en la lámina habrá variado (estado). Como es sabido, la energía se transfiere de un área más caliente hacia una más fría. La nueva temperatura en la celda \$i,j\$ será \$T_{i,j}^{k+1}\$ como se ve en la parte derecha de la Figura 1, y puede estimarse a partir de su temperatura en el instante (o estado) anterior y la temperatura de sus celdas vecinas por la relación:
De acuerdo a la relación anterior, la temperatura de una celda en el instante o estado \$k+1\$ indicado por \$T_{i,j}^{k+1}\$, es el resultado de la temperatura que la celda tenía en el instante o estado anterior \$T_{i,j}^k\$ más la pérdida o ganancia de energía que la celda haya sufrido con sus inmediaciones durante ese período \$\Delta t\$. Para efecto de la simulación, las inmediaciones son las cuatro celdas vecinas en forma de cruz como se ve en la Figura 1. Esta transferencia de energía o calor está regida por:
-
La energía que la celda \$i,j\$ recibe de sus inmediaciones, y se calcula como la suma de las temperaturas de las cuatro vecinas \$T_{i-1,j}^k + T_{i,j+1}^k + T_{i+1,j}^k + T_{i,j-1}^k\$.
-
La energía que la celda pierde y se distribuye a sus cuatro celdas vecinas, calculada como \$-4T_{i,j}^k\$.
-
La transferencia no es instantánea, sino que depende del área que recorre. Entre mayor es el área de la celda, más tiempo requerirá la energía para desplazarse y equilibrarse con sus vecinas. Por eso la ganancia y pérdida de energía calculada en los dos puntos anteriores, se divide entre el área de la celda \$h^2\$.
-
La cantidad de energía transferida es proporcional al tiempo. Es decir, entre más tiempo \$\Delta t\$ se permita entre el estado \$k\$ y el estado \$k+1\$, más energía podrá intercambiar la celda con sus vecinas. Por esto, el intercambio de energía calculado en los puntos anteriores se multiplica por la duración del estado \$\Delta t\$.
-
La cantidad de energía intercambiada en el periodo de tiempo depende de la calidad conductora de la lámina. Materiales como la madera son lentos para transmitir energía, mientras que los metales son eficientes para este fin. Para reflejar esta realidad, el intercambio de energía calculado en los puntos anteriores se multiplica por la difusividad térmica, que corresponde a una constante α que indica a qué tasa el material logra transmitir energía desde un punto caliente hacia otro frío a través de él. Sus unidades son de área entre tiempo, como \$\frac{m^2}{s}\$ ó \$\frac{mm^2}{s}\$. Por ejemplo, la madera tiene una difusividad cercana a \$0.08\frac{mm^2}{s}\$ mientras que el oro de \$127\frac{mm^2}{s}\$, es decir, el oro transfiere calor aproximadamente 1500 veces más rápido que la madera.
1.2.2. Simulación de calor
La Figura 2 muestra cuatro instantes o estados de una simulación hipotética de una lámina de oro (difusividad térmica \$α=127\frac{mm^2}{s}\$). Para efectos de la simulación, la lámina fue dividida en 5 filas y 4 columnas, cuyas celdas son de \$h=1000mm\$ de lado, es decir, de un metro de ancho por un metro de alto.
En el estado o instante cero (\$k=0\$) la simulación carga la matriz de un archivo que indica las temperaturas iniciales de cada celda de la lámina. Es importante resaltar que los bordes de la lámina no cambian su temperatura en el tiempo, dado que es el punto donde los experimentadores "inyectan o retiran calor". Por esto los bordes se resaltan con color de fondo en la Figura 2. De esta figura puede verse que en la parte superior se inyecta calor a una temperatura constante de 10 unidades (Celcius, Farenheit, o Kelvin), y conforme se desciende en la lámina, se provee menos calor en los bordes.
En cada instante o estado, la simulación debe actualizar las celdas internas de la lámina de acuerdo al modelo físico presentado en la sección anterior. En el instante o estado \$k=1\$ habrán transcurrido \$k \Delta t = 1200s = 20min\$. Como puede verse en la Figura 2, las temperaturas en los bordes se mantienen constantes, pero las celdas internas han adquirido energía de los bordes, en especial las celdas en la parte superior. Sin embargo, la celda \$2,2\$ perdió energía pese a que está al lado de un borde de temperatura 6, dado que tres de sus vecinas estaban más frías que ella en el estado previo \$k=0\$.
En el estado \$k=2\$ habrán transcurrido \$k \Delta t = 2 \cdot 1200s = 40min\$. Como puede verse en la Figura 2, las celdas internas han incrementado lentamente su temperatura dado a que son de \$1m^2\$ cada una. Incluso la celda \$2,2\$ ha visto reflejado un incremento. En el estado \$k=3\$ que en la vida real ocurriría una hora después de que inicia el experimento, la temperatura interna sigue creciendo, pero aún no se ha equilibrado con los valores de los bordes.
Se desea que la simulación continúe hasta que se haya alcanzado el punto de equilibrio, lo cual ocurre cuando el calor se ha estabilizado en la lámina. Para esto se proveerá un parámetro épsilon (ε) a la simulación, que representa el mínimo cambio de temperatura significativo en la lámina. En cada estado \$k\$ se actualizan todas las celdas internas de la lámina. Si al menos una de las celdas internas tiene un cambio en su temperatura mayor a ε, indica que no se ha alcanzado aún el equilibrio y la simulación continúa con el siguiente estado \$k+1\$, de lo contrario se detiene y reporta los resultados de la simulación. Por ejemplo, si la simulación de la Figura 2 se corriera con un \$ε=2\$ unidades de temperatura, ésta terminaría en el estado \$k=2\$, dado que el cambio de temperatura más grande del estado \$k=1\$ a \$k=2\$ se da en la celda \$1,1\$, calculada como \$|4.51-2.74|=1.77\$, y es menor que el \$ε=2\$.
El modelo físico presentado en la sección anterior es muy sensible a los parámetros de entrada, y dependiendo de la combinación de valores puede producir resultados incorrectos. El modelo se acerca más a la realidad entre más celdas se usen para representar la lámina (filas y columnas) y más pequeños sean los cambios de tiempo (\$\Delta t\$). Sin embargo acercarse a la realidad impone más presión sobre los recursos de la máquina, lo que hace la simulación más lenta, por lo que se desea una versión paralelizada de la simulación, que pueda encontrar el punto de equilibrio térmico en el menor tiempo posible.
1.2.3. Programa de simulación
Se necesita que la solución concurrente sea invocada desde la línea de comandos con los siguientes argumentos:
-
El nombre de un archivo de trabajo (job). Es obligatorio. Si no se provee, se debe emitir un mensaje de error.
-
La cantidad de hilos de ejecución. Es opcional, y si se omite, se debe suponer la cantidad de CPUs disponibles en el sistema.
Por ejemplo, la siguiente invocación indica que se quiere realizar todas las simulaciones indicadas en el archivo de trabajo job001.txt
con 16 hilos de ejecución.
bin/heatsim jobs/job001.txt 16
1.2.4. Archivo de trabajo
El archivo de trabajo (job file) es un archivo de texto que lista varias láminas y los parámetros de simulación que los experimentadores quieren investigar en cada una de ellas. El siguiente es un ejemplo de un archivo de trabajo job001.txt
:
plate001.bin 1200 127 1000 2 plate001.bin 1200 127 1000 1.5 plate002.bin 60 0.08 450 0.75
Cada línea del archivo de trabajo contiene una simulación independiente de las demás. Una simulación consta de los siguientes parámetros separados por espacios en blanco:
-
Nombre del archivo que contiene la lámina en su estado inicial. El contenido de este archivo se explica más adelante. La ubicación del archivo de simulación es relativo al archivo de trabajo. Por ejemplo si el anterior es el contenido del archivo de trabajo
jobs/job001.txt
significa queplate001.bin
se encuentra también en la subcarpetajobs/plate001.bin
. C++17 ofrece funcionalidad para trabajar con el sistema de archivos. Una alternativa para trabajar con rutas se ofrece más adelante. -
La duración de cada etapa \$\Delta t\$ en segundos.
-
La difusividad térmica α del material medida en unidades de área entre tiempo, por ejemplo: \$\frac{m^2}{s}\$ ó \$\frac{mm^2}{s}\$. Puede suponer que las unidades de tiempo siempre son las mismas que las usadas en el parámetro anterior.
-
Las dimensiones \$h\$ de las celdas medidas en las mismas unidades de área que el parámetro anterior pero lineales (distancia).
-
La sensitividad del punto de equilibrio ε, en las mismas unidades de temperatura que se usaron en el archivo de la lámina.
Su programa debe realizar todas las simulaciones indicadas en el archivo de trabajo. Una simulación involucra cargar la lámina como una matriz en memoria, y actualizarla a lo largo de varios estados hasta que se haya alcanzado el punto de equilibrio térmico. Una vez que esto ocurre se debe hacer un reporte a los investigadores, como se indica en la próxima sección.
1.2.5. Archivo de reporte
El archivo de reporte provee estadísticas resultado de ejecutar cada simulación. Su nombre tiene la forma job###.tsv
, donde ###
es el mismo número del archivo de trabajo. Cada vez que se invoca el programa de simulación, se crea o sobrescribe el archivo de reporte correspondiente. El archivo de reporte es de texto y tiene un formato similar al archivo de trabajo:
plate001.bin 1200 127 1000 2 2 0000/00/00 00:40:00 plate001.bin 1200 127 1000 1.5 3 0000/00/00 01:00:00 plate002.bin 60 0.08 450 0.75 56907 0000/01/09 12:27:00
Las líneas del archivo de reporte coinciden con las del archivo de trabajo. Cada línea del reporte contiene los mismos valores del archivo de trabajo, pero separados por tabuladores, y agrega dos resultados:
-
La cantidad de estados \$k\$ que transcurrieron hasta alcanzar el punto de equilibrio.
-
El tiempo transcurrido \$k\Delta t\$ hasta alcanzar el punto de equilibrio, pero reportado en formato legible para humanos
YYYY/MM/DD hh:mm:ss
donde, por sencillez, los meses son siempre de 30 días.
Para formatear el tiempo transcurrido en segundos, puede usar la siguiente función:
static std::string format_time(const time_t seconds) {
// TODO(any): Using C until C++20 std::format() is implemented by compilers
char text[48]; // YYYY/MM/DD hh:mm:ss
const std::tm& gmt = * std::gmtime(&seconds);
snprintf(text, sizeof text, "%04d/%02d/%02d\t%02d:%02d:%02d", gmt.tm_year
- 70, gmt.tm_mon, gmt.tm_mday - 1, gmt.tm_hour, gmt.tm_min, gmt.tm_sec);
return text;
}
Los experimentadores están también interesados en conocer el estado de la lámina una vez que haya alcanzado el punto de equilibrio. Por eso la simulación debe crear –o sobrescribir si ya existe– un archivo binario con el estado de la matriz en el punto de equilibrio, y con el nombre plate###-k.bin
donde k
corresponde al número de estado donde se alcanzó el equilibrio. Este archivo tiene el mismo formato que cualquier otro archivo de lámina, y por lo tanto, podría ser usado como punto de partida de nuevas simulaciones.
1.2.6. Archivo de lámina
Las láminas son matrices que se almacenan en archivos binarios que tienen una estructura sencilla. Los primeros ocho bytes son un entero sin signo \$R\$ que indica la cantidad de filas de la matriz. Los segundos ocho bytes son un entero sin signo \$C\$ que indica la cantidad de columnas de la matriz. A partir de los 16 bytes anteriores, continúan \$R\cdotC\$ números flotantes de doble precisión con la temperatura inicial de cada una de las celdas de la matriz, en el orden habitual de filas y columnas. Todos los valores se encuentran en little-endian.
Importante: Las matrices que los investigadores simulen pueden ser muy grandes debido a la necesidad de una alta granularidad para poder acercar la fidelidad de la simulación a la realidad. Su programa debe hacer un cuidadoso y eficiente manejo de memoria y de errores.
1.3. Desarrollo de la solución
El equipo debe desarrollar una solución concurrente en C++ de la simulación de calor usando la tecnología de paralelismo de datos OpenMP.
1.3.1. Solución serial
Se recomienda primero resolver el problema con una solución serial enfocada en corrección. El equipo debe escoger el paradigma dominante para su solución serial entre programación procedimental (recomendado) o programación orientada a objetos (OOP).
-
Si se utiliza el paradigma procedimental, la solución en C++ constará de un conjunto de subrutinas como por ejemplo
main()
,load_job_file()
, etc. Estas subrutinas pueden usar plantillas y objetos, como contenedores de la biblioteca estándar de C++. El diseño debe realizarse en pseudocódigo. -
Si se utiliza orientación a objetos, debe realizarse el diseño acorde en UML, al menos con diagramas de clases.
Los diseños deben guardarse en la subcarpeta design/
dentro de la carpeta para el proyecto02 en su repositorio de control de versiones. Si usa diagramas, expórtelos a imágenes vectoriales (SVG) o escalares (PNG) e incrústelas en un archivo design/readme.ext
, donde la extensión depende del tipo de documento (Markdown, AsciiDoc o LaTeX). En este documento se escriben las explicaciones que ayuden a comprender la solución (los diagramas) a alto nivel.
Implementen la versión serial en C++ aplicando las buenas prácticas de programación y documentación. La aplicación debe validar las entradas, como números mal formados, fuera de rango, matrices incompletas o inválidas. El programa debe reportar estas anomalías con mensajes de error, en lugar de caerse o producir resultados incorrectos. Asegúrense de que la aplicación no genere diagnósticos del linter o sanitizers.
1.3.2. Programa de pruebas
Se recomienda crear un programa adicional (herramienta) que compare dos archivos binarios de lámina. El programa recibe tres argumentos en línea de comandos: el nombre del primer archivo a comparar, el nombre del segundo archivo, y una sensitividad (un épsilon). Este tercer parámetro es necesario dados los problemas de precisión que presenta la aritmética flotante. La sensitividad es un número pequeño de tal forma que una diferencia menor a este número se considera despreciable y que los dos números son el mismo.
El programa comparador compararía las matrices en ambos archivos. Si tienen las mismas dimensiones, procedería a comparar celda por celda. Las celdas son temperaturas representadas en números flotantes de doble precisión. La comparación no debe hacerse directamente con el operador de igualdad (==
) o desigualdad (!=
), sino que por errores de precisión aritmética, podrían haber diferencias que dependen del orden en que se realicen las operaciones o por otros motivos, aunque realmente los modelos sean correctos. Por eso se puede comparar la diferencia entre cada pareja de celdas de la matriz contra un valor de sensitividad o épsilon, como se muestra a continuación:
double file1Cell = ...;
double file2Cell = ...;
// Wrong!
if (file1Cell != file2Cell) {
// Files are different
}
// OK
if (fabs(file1Cell - file2Cell) > epsilon) {
// Files are different
}
Este programa permitirá comparar casos de prueba binarios contra una salida esperada. El código fuente de este programa debe estar en su propia carpeta para no interferir con el código de la simulación.
1.3.3. Simulación concurrente con OpenMP
Una vez construida su solución serial, realicen una paralelización que incremente el desempeño usando la tecnología OpenMP. Dado que la paralelización es una optimización, apliquen el método sugerido para optimizar visto durante las lecciones.
Paso 1. Se debe medir el rendimiento de la versión serial con un archivo de trabajo grande, siguiendo el procedimiento indicado en la Tarea03 para realizar mediciones de rendimiento en un nodo esclavo del clúster Arenal con al menos tres corridas (no usar una computadora local). Anotar los resultados en una hoja de cálculo. Nota: si no se implementó una versión serial puede usar la versión paralelizada con un único hilo.
Paso 2. Hacer profiling con Callgrind para identificar las regiones de código que más impactan el consumo de CPU con un archivo de trabajo pequeño. Este paso debería ayudar al equipo a confirmar sus hipótesis de cuáles líneas de código son las candidatas a ser paralelizadas.
Paso 3. Diseñar e implementar la paralelización con OpenMP. Discutan la optimización pretendida y el método de mapeo que logre la mayor eficiencia. Consideren que las láminas también podrían ser muy altas y delgadas, o muy anchas y aplastadas. Implementar la paralelización con OpenMP en el código fuente. Recuerde que la cantidad de hilos debe poderse controlar por argumento de línea de comandos. En caso de omitirse se debe suponer la cantidad de CPU disponibles en el equipo donde corre el programa.
Paso 4. Pasar las pruebas de corrección. La solución debe pasar los casos de prueba usando el programa comparador, y no tener malas prácticas como espera activa, condiciones de carrera, bloqueos mutuos, inanición, serialización innecesaria, o ineficiencia.
Paso 5. Medir el rendimiento de la versión paralelizada con los mismos métodos que el paso 1. Calcular el incremento de velocidad (speedup) y la eficiencia. Cree un gráfico que incluya en el eje-x las dos soluciones (serial, concurrente), en el eje-y primario el incremento de velocidad, y en el eje-y secundario la eficiencia. Para la versión concurrente use tantos hilos como núcleos hayan disponibles en la máquina. Incruste su gráfico en una sección "Análisis de rendimiento" de su readme.ext
con su correspondiente discusión corta (500 palabras máximo).
1.4. Evaluación
La revisión de avance será mediante una sesión interactiva por videoconferencia, como se estipula en el primer avance del proyecto 1. Se dará crédito a la evidencia presentada en cada aspecto de este enunciado y se distribuye en los siguientes rubros.
-
[5%] Buen uso y aporte equilibrado del repositorio (commits, ignores, tags) y directorios.
-
[10%] Análisis:
readme.ext
, problema, construcción, manual de usuario. -
[10%] Diseño: documento de diseño, clases en UML o pseudocódigo.
-
[15%] Procesa archivos de trabajo, lee y escribe archivos de lámina, genera reportes.
-
[5%] Programa comparador de archivos de láminas. Pasa los casos de prueba.
-
[10%] Implementa el modelo físico y detiene la simulación en el punto de equilibrio térmico.
-
[15%] Paraleliza correctamente con OpenMP.
-
[10%] Comparaciones de rendimiento, gráficas, y discusión.
-
[10%] Buen uso de la memoria y de la concurrencia (Sanitizers).
-
[10%] Modularización en subrutinas y archivos (
.hpp
,.cpp
). Apego a una convención de estilos (cpplint
). Documentación de interfaces (doxygen
) e implementaciones (algoritmos).
Recuerde que en todos los rubros se evalúan las buenas prácticas de programación.
2. Proy2.2: Simulación de calor distribuida
La segunda entrega del Proyecto 2 consiste en mejorar el rendimiento de la primera entrega agregando distribución mediante la tecnología MPI
. Dado que es una continuación, aplican los mismos lineamientos del avance 2.1. Modifiquen directamente el código del proyecto en el repositorio de control de versiones. No dupliquen la carpeta. Este es un avance que incrementa o mejora el código existente.
2.1. Análisis y diseño
Modifique los artefactos de análisis (readme
) y diseño en la carpeta design/
del Proyecto02 para agregar las decisiones de distribución que incrementen el desempeño de la solución.
Agregue pseudocódigo usando la notación vista durante las lecciones del curso. Recuerde que el pseudocódigo debe enfocarse en las decisiones concurrentes y distribuidas. Aspectos seriales pueden ser abstraídos con subrutinas como "Cargar matriz de archivo binario". Considerar en su diseño los siguientes puntos:
-
Unidad de descomposición de la carga de trabajo y el tipo mapeo dinámico a los procesos (con MPI). Considere que los trabajos (jobs) y las láminas (plates), pueden ser de cualquier tamaño y requerir diferente cantidad de trabajo que no se puede determinar de antemano. Su solución debe adaptarse para balancear la carga de trabajo heterogénea.
-
Unidad de descomposición de la carga de trabajo y su tipo de mapeo a los hilos de ejecución (con OpenMP). Puede ser que esta decisión se mantenga inalterada respecto al avance 2.1 o cambie al introducir la distribución.
En su documento de diseño, justifique en un párrafo las elecciones anteriores. En cuanto al documento de análisis, agregue una sección para indicar cómo usar su solución en un ambiente distribuido, como un clúster. Considere:
-
Si utilizan separación de asuntos entre procesos, explicar en el manual de usuario qué hace cada tipo de proceso y en qué nodo del clúster se debería ejecutar cada tipo de proceso. Esto con el fin de que los usuarios puedan configurar su programa adecuadamente a otros tipos de clúster. Provea ejemplos de ejecución y de los archivos de hosts para Arenal en su manual de usuario.
-
Describa qué otras preparaciones son necesarias para poder compilar y correr su solución en el clúster. Por ejemplo, cargar módulos, preparar archivos de datos, o carpetas vacías.
2.2. Implementación distribuida
Agregue a su solución concurrente (OpenMP) la capacidad de distribuir trabajo que incremente el desempeño mediante la tecnología MPI
. Antes de continuar, asegúrense de haber medido el rendimiento de la versión concurrente (con OpenMP) con el caso de prueba job020
o superior en un nodo esclavo del clúster Arenal. Esta medición se usará como base para comparaciones de la versión distribuida.
Implemente la paralelización con MPI
siguiendo las decisiones de diseño realizadas en la sección anterior. Asegúrese de que la solución pasa las pruebas de corrección, por ejemplo, generar el archivo de reporte esperado. Use su programa comparador de archivos binarios para determinar que no hayan diferencias con al menos cinco cifras significativas (epsilon = 0.00001).
Recuerde que la cantidad de CPUs a utilizar debe poder ser controlada por argumento de línea de comandos. En caso de omitirse se debe suponer la cantidad de CPU disponibles en el equipo donde corre el programa.
La solución no tener malas prácticas como espera activa, condiciones de carrera, bloqueos mutuos, inanición, serialización innecesaria, o ineficiencia. Aplique buenas prácticas de programación. Documente su código. Sea consistente con la convención de estilo (cpplint
). Haga un buen uso del repositorio de control de versiones.
2.3. Comparación de rendimiento
Realice las siguientes mediciones de rendimiento de sus programas con el caso de prueba job020
o superior en el clúster de Arenal.
-
Mida el rendimiento de la versión distribuida (MPI) usando todos los nodos del clúster, y en cada nodo cree tantos procesos como núcleos haya en él. Por ejemplo, en el clúster de Arenal sería en total 24 procesos de paralelismo de dato (8 por nodo). Sólo cree un hilo en cada proceso.
-
Mida el rendimiento de la versión híbrida (OpenMP+MPI) en todos los nodos del clúster usando un proceso por nodo, y tantos hilos como núcleos haya en dicho nodo. Por ejemplo en el clúster de Arenal sería en total 3 procesos de paralelismo de dato y 8 hilos en cada proceso.
Calcular el incremento de velocidad (speedup) y eficiencia de las dos mediciones distribuidas contra la medición concurrente (OpenMP) que realizó en un nodo esclavo del clúster. Cree un gráfico combinado que en el eje-y primario exprese el incremento de velocidad y en el eje-y secundario la eficiencia. En el eje-x incluya las siguientes mediciones:
-
Concurrente OpenMP un proceso con 8 hilos en un solo nodo.
-
Distribuida MPI con 24 procesos de 1 hilo en 3 nodos.
-
Híbrida OpenMP+MPI con 3 procesos de 8 hilos en 3 nodos.
Incruste la tabla con las mediciones y su gráfico en una sección "Análisis de rendimiento" de su README.md
. Comente brevemente (500 palabras máximo) sus resultados. Indique si obtuvo el desempeño que esperaba. En caso negativo, indique de qué manera podría mejorar la eficiencia de su solución.
2.4. Evaluación
La revisión de avance será mediante una sesión interactiva por videoconferencia, como se estipula en el primer avance del proyecto 1. Marque el commit a presentar con la etiqueta avance22
(o milestone22
). Se dará crédito a la evidencia presentada en cada aspecto de este enunciado y se distribuye en los siguientes rubros.
-
[5%] Buen uso y aporte equilibrado del repositorio y directorios.
-
[5%] Análisis (
readme.ext
): construcción, manual de usuario. -
[15%] Diseño refleja decisiones de descomposición y mapeo distribuido y concurrente.
-
[25%] Implementación de la distribución, paso de mensajes.
-
[20%] Genera resultados correctos.
-
[25%] Comparaciones de rendimiento, gráficas, y discusión.
-
[5%] Modularización en subrutinas y archivos (
.hpp
,.cpp
). Apego a una convención de estilos (cpplint
). Documentación de interfaces (doxygen
) e implementaciones (algoritmos).
Recuerde que en todos los rubros se evalúan las buenas prácticas de programación.
Referencias
-
Becker and Kaus (2016). Excerpt from GEOL557 Numerical Modeling of Earth Systems. Accedido Nov, 2021.