Programación paralela

De NLHPC

Para resolver un problema más rápido, el trabajo a veces se puede ejecutar en paralelo. Para lograr esto, generalmente se usa un modelo de programación Memoria Compartida o Memoria Distribuida. A continuación se incluye una breve descripción del concepto básico de Sistemas de memoria compartida y Sistemas de memoria distribuida.

Memoria Compartida (OpenMP)

Esquema Memoria Compartida


La programación de memoria compartida funciona como la comunicación de varias personas que limpian una casa a través de un tablón de anuncios. Hay una memoria compartida (tablón de anuncios en la analogía) donde todos pueden ver lo que todos están haciendo y qué tan lejos han llegado o qué resultados (el baño ya está limpio) llegaron. Al igual que en el mundo físico, existen límites logísticos en muchas unidades paralelas (las personas) pueden usar la memoria (pin board) de manera eficiente y cuán grande puede ser.

En la computadora, esto se traduce en múltiples núcleos que tienen acceso conjunto a la misma memoria compartida como se muestra. Esto tiene la ventaja de que generalmente hay muy poca sobrecarga de comunicación, ya que cada núcleo puede escribir en cada ubicación de memoria y, por lo tanto, la comunicación es implícita. Además, la paralelización de un programa secuencial existente (= no paralelo) es comúnmente directo y muy fácil de implementar, si el problema subyacente permite la paralelización. Como se puede ver en la imagen, no es práctico adjuntar más y más núcleos a la misma memoria, ya que solo puede servir un número limitado de núcleos con datos de manera eficiente al mismo tiempo. Por lo tanto, este paradigma está limitado por cuántos núcleos pueden caber en una computadora (unos pocos cientos es una buena estimación).

Para aplicaciones paralelas, que planean ejecutarse en este tipo de sistemas, se usa comúnmente en la comunidad HPC.

Memoria Distribuida (MPI)

Esquemático de memoria de sistemas distribuidos para redes dispersas

Esquemático de memoria de sistemas distribuidos para redes dispersas


Esquema de un sistema de memoria distribuida con una red densa.

Esquema de un sistema de memoria distribuida con una red densa.

La memoria distribuida es similar a la forma en que múltiples humanos interactúan mientras resuelven problemas: cada proceso (persona) 'trabaja' por sí mismo y puede comunicarse con los demás enviando mensajes (hablando y escuchando).

En una computadora o un grupo de computadoras, cada núcleo funciona por sí mismo y tiene una forma (por ejemplo, la Interfaz de paso de mensajes (MPI) para comunicarse con los otros núcleos. Esta mensajería puede ocurrir dentro de una CPU entre múltiples núcleos, utilizar una red de alta velocidad entre las computadoras (nodos) de una supercomputadora o, en teoría, incluso ocurrir en Internet. Este envío y recepción de mensajes a menudo es más difícil de implementar para el desarrollador y, a veces, incluso requiere una gran reescritura / reestructuración del código existente. Sin embargo, tiene la ventaja de que se puede escalar a más computadoras (nodos), ya que cada proceso tiene su propia memoria y puede comunicarse a través de MPI con los otros procesos. El factor limitante aquí es la velocidad y las características de la red física, que conecta los diferentes nodos.

El patrón de comunicación se representa con una red dispersa y densa. En una red dispersa, los mensajes deben ser reenviados a veces por múltiples núcleos para llegar a su destino. Cuantas más conexiones haya, menor será esta cantidad de reenvío, lo que reduce la latencia promedio y la sobrecarga y aumenta el rendimiento y la escalabilidad.

Dado que cada comunicación está codificada explícitamente, este patrón de comunicación puede diseñarse cuidadosamente para explotar la arquitectura y los nodos disponibles en toda su extensión. De ello se deduce que, en teoría, la aplicación puede escalar tan alto como lo permita el problema subyacente, estando solo limitada por la red que conecta los nodos y la sobrecarga para enviar / recibir mensajes.

¿Debo usar memoria distribuida o memoria compartida?

Esto realmente depende del problema en cuestión. Si el problema es paralelo, la potencia informática requerida es un buen indicador. Cuando bastan unos pocos cientos de núcleos, OpenMP es (para los códigos existentes) la alternativa más fácil. Sin embargo, si se requieren miles o incluso millones de núcleos, no hay realmente una forma de evitar MPI. Para tener una mejor visión general, los diferentes pros y contras se enumeran en la siguiente tabla:


Memoria compartida (OpenMP) Memoria distribuida (MPI)
Pros Cont Pros Cont
Fácil de implementar Escala solo a 1 nodo Escalas a través de múltiples nodos Más difícil de implementar
Variables compartidas Carreras de datos inherentes Sin carreras de datos inherentes Sin variables compartidas
Bajo consumo   Cada proceso MPI puede utilizar OpenMP,

resultando en una aplicación híbrida

Consumo normal
Puede ejecutarse / iniciarse normalmente   Necesita un contenedor de biblioteca