Documentos de Académico
Documentos de Profesional
Documentos de Cultura
En un primer lugar me parece clave aclarar qué implica el cómputo en Paralelo, para poder
comprender más claramente ambos modelos: el de programación de memoria compartida y
el de programación con memoria distribuida.
Ahora bien, debe también haber cierta comunicación para que todo esto pueda llevarse a
cabo.
Región Región
Secuencial Secuencial
Región Región
Paralela Paralela
Antes de continuar, me gustaría dejar en claro que los threads ejecutan en mismo código o
programa, pero al manejarse con identificadores distintos si se utilizan condiciones o su
identificador correctamente se puede lograr que cada thread realice una tarea distinta o que
cooperando con el resto de los threads cada uno realice una pequeña porción del trabajo.
Vale aclarar que los mensajes no solo sirven para la comunicación entre los procesos, sino
que también ayudan a la sincronización. Además, toda interacción requiere la cooperación
de dos procesos.
Para responder esta pregunta primero explicaré a que nos referimos cuando hablamos de
determinismo en un programa. Decimos que un programa es determinístico cuando para
los mismos datos de entrada, ejecuta siempre la misma secuencia de instrucciones y obtiene
la misma salida. Contrariamente un programa no determinístico es cuando puede dar
distintos resultados al ejecutarse sobre los mismos datos de entrada.
Al dividir en procesos paralelos, no puede darse determinismo. Esto tiene que ver con la
naturaleza del paralelismo, que implica una competencia entre los procesos para acceder a
un recurso compartido o para enviar mensajes a otro proceso. En ambos casos, no es
posible saber de antemano el orden en que se llevará a cabo la ejecución, ya que se
obtendrán distintos resultados tras cada repetición. Asimismo, aplicar restricciones que
permitan dar desde el código un orden de ejecución, puede llevar a que se pierda la ventaja
del paralelismo y que se lleve al equivalente a una versión secuencial de programa,
perdiendo performance.
Zona Crítica
En ambos modelos la sincronización de los procesos puede llevar a que los procesos tengan
tiempo ocioso. En el modelo de programación con memoria compartida, si se utilizan
menos threads que los disponibles, si se utilizan las barreras dónde no corresponden o
demasiadas zonas críticas ciertos procesos pueden quedar ociosos. Por otro lado, en el
modelo de programación con memoria distribuida los mensajes bloqueantes pueden llevar a
que ciertos procesos tengan tiempo ocioso. Un Send debe esperar a que se ejecute el Recv
respectivo para que la ejecución puede seguir y viceversa. Una solución a esto es agregar
un buffer. Cuando hay un SEND, este copia el dato en el buffer y el programa sigue
adelante. Cuando el receptor realiza el Recv respectivo, encuentra el dato en el buffer.
Igualmente también aparece un tema de hardware. Recordemos que en memoria distribuida
cada procesador es una entidad independiente. Imaginemos, entonces que tenemos 4
procesadores: uno que hace de master y 3 que hacen de workers, según el modelo de
master-worker que hemos estudiado a lo largo de la cursada. ¿Qué sucede si distribuimos la
carga de trabajo de manera estática y hay un procesador que es muchísimo más veloz que
los otros? Este quedará rápidamente ocioso y estaremos desperdiciando un recurso. Como
solución deberíamos analizar distribuir la carga dinámicamente.