Qu vimos en la clase pasada Las arquitecturas

  • Slides: 51
Download presentation
Qué vimos en la clase pasada? ? Las arquitecturas de memoria distribuida son cada

Qué vimos en la clase pasada? ? Las arquitecturas de memoria distribuida son cada vez más habituales. Esto implica procesadores + memoria local + red de comunicaciones + otro mecanismo de comunicación/sincronización mensajes. Los programas concurrentes que se comunican por mensajes se denominan programas distribuidos. Esto supone la ejecución sobre una arquitectura de memoria distribuída, aunque puedan ejecutarse sobre una arquitectura de memoria compartida ( o híbrida). 07 -6 -2004 Programación Concurrente 2004 - Clase 8 1

Qué vimos en la clase pasada? ? En un programa distribuido los canales son

Qué vimos en la clase pasada? ? En un programa distribuido los canales son el único objeto que los procesos comparten no hay acceso concurrente a variables y la exclusión mutua no requiere ningún mecanismo especial. Los canales pueden proveer comunicaciones halfduplex o full-duplex. A su vez estas comunicaciones pueden ser asincrónicas (no bloqueantes) o sincrónicas (bloqueantes). 07 -6 -2004 Programación Concurrente 2004 - Clase 8 2

Qué vimos la clase pasada? ? Si bien se pueden obtener soluciones equivalentes, AMP

Qué vimos la clase pasada? ? Si bien se pueden obtener soluciones equivalentes, AMP y SMP son mejores para modelos tipo productorconsumidor o pares interactivos, mientras RPC y Rendezvous serán más útiles para esquemas C-S. El pasaje de mensajes (AMP o SMP) puede verse como una extensión de semáforos con datos. En RPC y Rendezvous se combina la interfaz procedural de los monitores con pasaje de mensajes implícito. Programación Concurrente 2004 - Clase 8 07 -6 -2004 3

Qué vimos la clase pasada? ? El grado de concurrencia en SMP se reduce

Qué vimos la clase pasada? ? El grado de concurrencia en SMP se reduce respecto de la sincronización por mensajes asincrónicos. Como contrapartida los casos de falla y recuperación de errores son más fáciles de manejar. Si bien send y sync_send son similares (en algunos casos intercambiables) la semántica es diferente y las posibilidades de deadlock mayores en comunicación sincrónica. Programación Concurrente 2004 - Clase 8 07 -6 -2004 4

Qué vimos la clase anterior? : El lenguaje CSP de Hoare. CSP (Hoare 1978)

Qué vimos la clase anterior? : El lenguaje CSP de Hoare. CSP (Hoare 1978) fue uno de los desarrollos fundamentales en Programación Concurrente. Muchos lenguajes reales (OCCAM, ADA, SR) se basan en CSP. La idea básica de Hoare fue la de comunicación guardada: es decir pasaje de mensajes con waiting selectivo. Canal: link directo entre dos procesos en lugar de mailbox global. Son half-duplex y nominados. Sentencias de Entrada y Salida ( ? ! ) : único medio por el cual los procesos se comunican. Efecto de la comunicación sentencia de asignación distribuida. 07 -6 -2004 Programación Concurrente 2004 - Clase 8 5

El lenguaje CSP de Hoare. Formas generales de sentencias de comunicación: Destino ! port(e

El lenguaje CSP de Hoare. Formas generales de sentencias de comunicación: Destino ! port(e 1, . . . , en); Fuente ? port(x 1, . . . , xn); Destino y Fuente nombran un proceso. port es un canal de comunicación simple en el proceso destino o un elemento de un arreglo de ports en el proceso destino. Los ports son usados (declarados) para distinguir entre distintas clases de mensajes que un proceso podría recibir. Dos procesos se comunican cuando ejecutan sentencias de comunicación que hacen matching. A! canaluno(dato); #el proceso A envia por canaluno B? canaluno(resultado); #el proceso B recibe por canaluno 07 -6 -2004 Programación Concurrente 2004 - Clase 8 6

El lenguaje CSP de Hoare. Primeros ejemplos. Server que calcula el Máximo Común Divisor

El lenguaje CSP de Hoare. Primeros ejemplos. Server que calcula el Máximo Común Divisor de dos enteros con algoritmo de Euclides: GCD espera recibir entrada en su port args desde un único cliente. Envía la respuesta al port result del cliente. Process GCD { INT Id, x, y; do true Client[*] ? args(Id, x, y); #Lo que sigue se repite hasta que x==y do x > y x : = x - y; �x < y y : = y - x; od Client[Id] ! result(x); od } Client se comunica con GCD ejecutando: . . . GCD ! args(v 1, v 2); GCD ? result(r). . . 07 -6 -2004 Programación Concurrente 2004 - Clase 8 7

CSP: comunicación guardada. Un proceso puede tener que realizar una comunicación sólo si se

CSP: comunicación guardada. Un proceso puede tener que realizar una comunicación sólo si se da una condición: IF B 1; comunicación 1 ----> S 1; �B 2; comunicación 2 ----> S 2; FI Process Copy { CHAR buffer[80]; INT front = 0, rear = 0, count = 0 do count < 80; West ? buffer[rear] count = count + 1; rear = (rear + 1)MOD 80; � count > 0; East ! buffer[front] count : = count - 1; front : = (front + 1) MOD 80; od } 07 -6 -2004 Programación Concurrente 2004 - Clase 8 8

Intercambio de valores entre dos procesos en CSP. Supongamos dos procesos que intercambian valores:

Intercambio de valores entre dos procesos en CSP. Supongamos dos procesos que intercambian valores: Process P 1 { INT value 1 = 1, value 2; IF P 2 ! value 1 ---> P 2 ? value 2; � P 2 ? value 2 ---> P 2 ! value 1; FI } Process P 2 { INT value 1 , value 2=2; IF P 1 ! value 2 ---> P 1 ? value 1; � P 1 ? value 1 ---> P 1 ! value 2; FI } Esta solución simétrica NO tiene deadlock porque el no determinismo en ambos procesos hace que se acoplen las comunicaciones correctamente. 07 -6 -2004 9 Programación Concurrente 2004 - Clase 8

CSP: Generación de números primos: la criba de Eratóstenes. Idea: generar todos los primos

CSP: Generación de números primos: la criba de Eratóstenes. Idea: generar todos los primos entre 2 y n 2 3 4 5 6 7. . . n Comenzando con el primer número, 2, recorremos la lista y borramos los múltiplos de ese número. Si n es impar: 2 3 5 7. . . n Pasamos al próximo número, 3, y borramos sus múltiplos. Si seguimos hasta que todo número fue considerado, los quedan son todos los primos entre 2 y n. 07 -6 -2004 Programación Concurrente 2004 - Clase 8 10

La criba de Eratóstenes: solución paralela en CSP. Process Sieve[i = 2 TO L]

La criba de Eratóstenes: solución paralela en CSP. Process Sieve[i = 2 TO L] { INT p, next; Sieve[i-1] ? p # p es primo DO Sieve[i-1] ? Next ---> #recibe el proximo candidato IF (next MOD p) <> 0 ---> #podría ser primo Sieve[i+1] ! Next; #entonces lo pasa FI OD } El número total L de procesos Sieve debe ser lo suficientemente grande para garantizar que todos los primos hasta n se generan. 07 -6 -2004 11 Programación Concurrente 2004 - Clase 8

El lenguaje de programación OCCAM Hoare introdujo CSP como lenguaje formal que sigue el

El lenguaje de programación OCCAM Hoare introdujo CSP como lenguaje formal que sigue el modelo de pasaje de mensajes sincrónicos, pero nunca fue implementado. OCCAM es un lenguaje real, que implementa lo esencial de CSP sobre una arquitectura “modelo” que físicamente se ha desarrollado y que son los trasputers. Trasputers + OCCAM constituyen una combinación que permite hablar de “sistema multiprocesador para procesamiento concurrente”, donde tanto la arquitectura como el lenguaje son simples y perfectamente adecuadas a la programación concurrente con mensajes sincrónicos. 07 -6 -2004 Programación Concurrente 2004 - Clase 8 12

El lenguaje de programación OCCAM. üOCCAM es un lenguaje simple con una sintaxis rígida:

El lenguaje de programación OCCAM. üOCCAM es un lenguaje simple con una sintaxis rígida: Cada proceso primitivo, constructor o declaración ocupa una línea. Se usa : al final de una declaración. Hay una rígida indentación. üLos procesos y los caminos de comunicación entre ellos son estáticos (definidos al momento de la compilación). Un programa en OCCAM tiene un número fijo de procesos. üEl modelo de comunicación es sincrónico por canales half duplex. üLas sentencias básicas (asignación y comunicación) son vistas como procesos primitivos. Programación Concurrente 2004 - Clase 8 07 -6 -2004 13

Conceptos del lenguaje de programación OCCAM üOccam no soporta recursión o cualquier forma de

Conceptos del lenguaje de programación OCCAM üOccam no soporta recursión o cualquier forma de creación o nombrado dinámico. Esto hace que muchos algoritmos sean difíciles de programar. üSin embargo, asegura que un compilador Occam puede determinar exactamente cuántos procesos contiene un programa y cómo se comunican uno con otro. üEsto, y el hecho de que distintos constructores no pueden compartir variables, hace posible para un compilador asignar procesos y datos a procesadores en una máquina de memoria distribuida tal como un transputer. 07 -6 -2004 14 Programación Concurrente 2004 - Clase 8

El lenguaje de programación OCCAM Las unidades básicas de un programa Occam son declaraciones

El lenguaje de programación OCCAM Las unidades básicas de un programa Occam son declaraciones y tres "procesos" primitivos: asignación, input(receive), output (sync_send). Los canales son declarados globales a los procesos. Sin embargo, cada canal debe tener exactamente un emisor y un receptor. Los procesos primitivos se combinan en procesos convencionales usando constructores (sentencias estructuradas). Estos incluyen un constructor secuencial SEQ, un constructor paralelo PAR similar a la sentencia co, y una sentencia de comunicación guardada. Un constructor puede ser precedido por declaraciones de variables y canales; el alcance de estos ítems es el constructor. 07 -6 -2004 Programación Concurrente 2004 - Clase 8 15

El lenguaje OCCAM: constructores SEQ y PAR En la mayoría de los lenguajes, el

El lenguaje OCCAM: constructores SEQ y PAR En la mayoría de los lenguajes, el default es ejecutar sentencias secuencialmente; el programador tiene que decir explícitamente cuándo ejecutar sentencias concurrentemente. Occam toma una aproximación distinta: no hay default. En lugar de esto, contiene dos constructores básicos: SEQ para ejecución secuencial y PAR para ejecución paralela. Por ejemplo, el siguiente programa incrementa x, luego y: INT x, y : SEQ x : = x + 1 y : = y + 1 07 -6 -2004 16 Programación Concurrente 2004 - Clase 8

El lenguaje OCCAM: constructores SEQ y PAR En el ejemplo anterior, dado que las

El lenguaje OCCAM: constructores SEQ y PAR En el ejemplo anterior, dado que las dos sentencias acceden variables distintas, pueden ser ejecutadas concurrentemente. Esto se expresa por: INT x, y : PAR x : = x + 1 y : = y + 1 Lo que cambia es el nombre del constructor, para indicarle al compilador y el monitor de ejecución si puede haber concurrencia. PAR no es tan poderoso como la sentencia co pues los procesos Occam no pueden compartir variables. 07 -6 -2004 17 Programación Concurrente 2004 - Clase 8

Comentarios sobre el constructor PAR en OCCAM üLos procesos especificados usando PAR ejecutan con

Comentarios sobre el constructor PAR en OCCAM üLos procesos especificados usando PAR ejecutan con igual prioridad y sobre cualquier procesador. üEl constructor PRI PAR puede usarse para especificar que el primer proceso tiene la prioridad más alta, el segundo la siguiente, etc. üEl constructor PLACED PAR puede usarse para especificar explícitamente dónde es ubicado y por lo tanto ejecutado cada proceso 07 -6 -2004 18 Programación Concurrente 2004 - Clase 8

El lenguaje de programación OCCAM: otros constructores El constructor IF se usa para alternativas:

El lenguaje de programación OCCAM: otros constructores El constructor IF se usa para alternativas: es similar a la sentencia IF guardada que conocemos, pero hay dos diferencias: las guardas son evaluadas en el orden en que están listadas, y al menos una guarda debe ser TRUE. El constructor CASE es una variante de IF que puede ser usada para alternativas múltiples. 07 -6 -2004 Programación Concurrente 2004 - Clase 8 19

El lenguaje de programación OCCAM: otros constructores El constructor WHILE es uno de los

El lenguaje de programación OCCAM: otros constructores El constructor WHILE es uno de los mecanismos de iteración; es como la sentencia while de Pascal. El constructor ALT soporta comunicación guardada. Cada guarda consta de un input process, una expresión booleana y un input process, o una expresión booleana y un SKIP (lo cual se reduce esencialmente a una expresión booleana pura). 07 -6 -2004 Programación Concurrente 2004 - Clase 8 20

Replicadores en OCCAM. Occam también contiene un mecanismo interesante llamado replicador. Es similar a

Replicadores en OCCAM. Occam también contiene un mecanismo interesante llamado replicador. Es similar a un cuantificador y se usa del mismo modo. Por ejemplo, lo siguiente declara un arreglo pepe de 21 elementos e iterativamente asigna un valor a cada elemento: [20] INT pepe : SEQ i = 0 FOR 10 pepe[i] : = i Como vemos, solo el límite superior del arreglo se declara; el límite inferior es implícitamente 0 para todos los arreglos. Las matrices se declaran como arreglos de arreglos. Un replicador no agrega nueva funcionalidad al lenguaje, solo es una abreviación para un conjunto de componentes. Occam requiere que el límite superior sea una constante, y por lo tanto un replicador siempre puede ser expandido para dar un programa equivalente pero más largo. 07 -6 -2004 21 Programación Concurrente 2004 - Clase 8

Comunicación y sincronización en OCCAM Como dijimos, las sentencias en los distintos constructores de

Comunicación y sincronización en OCCAM Como dijimos, las sentencias en los distintos constructores de Occam no pueden compartir variables. Para comunicarse y sincronizar, deben usar canales. Una declaración de canal tiene la forma: CHAN OF protocol name : El protocolo define el tipo de valores que son transmitidos por el canal. Pueden ser tipos básicos, arreglos de longitud fija o variable, o registros fijos o variantes. 07 -6 -2004 Programación Concurrente 2004 - Clase 8 22

Comunicación y sincronización en OCCAM Los procesos pueden ser creados con el constructor PAR.

Comunicación y sincronización en OCCAM Los procesos pueden ser creados con el constructor PAR. Los canales son accedidos por los procesos primitivos input (? ) y output (!). A lo sumo un proceso puede emitir por un canal, y a lo sumo uno puede recibir por un canal. Dado que el nombrado es estático, un compilador Occam puede forzar este requerimiento. 07 -6 -2004 Programación Concurrente 2004 - Clase 8 23

Comunicación y sincronización en OCCAM. Un ejemplo. WHILE TRUE BYTE ch : SEQ keyboard

Comunicación y sincronización en OCCAM. Un ejemplo. WHILE TRUE BYTE ch : SEQ keyboard ? ch ch ! screen Aquí, keyboard y screen son canales que se asume que están conectados a dispositivos periféricos. Aunque Occam no define mecanismos de E/S como parte del lenguaje, provee mecanismos para ligar canales de E/S a dispositivos. El sistema de desarrollo en transputer, por ejemplo, contiene una librería de procedures de E/S de modo de vincular canales lógicos y dispositivos físicos. 07 -6 -2004 24 Programación Concurrente 2004 - Clase 8

Comunicación y sincronización en OCCAM. Un ejemplo. El programa anterior usa un buffer simple,

Comunicación y sincronización en OCCAM. Un ejemplo. El programa anterior usa un buffer simple, ch. Puede convertirse en un programa concurrente que use doble buffering empleando dos procesos, uno para leer desde el teclado y uno para escribir en la pantalla. El proceso se comunica usando un canal adicional comm; cada uno tiene un carácter local ch: CHAN OF BYTE comm : PAR WHILE TRUE BYTE ch : SEQ keyboard ? ch comm ! ch WHILE TRUE BYTE ch : SEQ comm ? ch keyboard ! ch 07 -6 -2004 25 Programación Concurrente 2004 - Clase 8

Uso del constructor ALT en OCCAM El constructor ALT soporta comunicación guardada. Cada guarda

Uso del constructor ALT en OCCAM El constructor ALT soporta comunicación guardada. Cada guarda consta de un input process, una expresión booleana y un input process. Puede usarse un replicador como abreviatura, por ejemplo, para esperar recibir entrada de uno de un arreglo de canales. Por ejemplo, lo siguiente implementa un alocador de recursos simple: ALT i = 0 FOR n avail > 0 & acquire[i] ? unitid SEQ avail : = avail - 1 -- and select unit to allocate reply[i] ! Unitid release[i] ? unitid avail : = avail + 1 07 -6 -2004 -- and return unit 26 Programación Concurrente 2004 - Clase 8

Uso del constructor ALT en OCCAM. Comentarios. Acquire, reply y release son arreglos de

Uso del constructor ALT en OCCAM. Comentarios. Acquire, reply y release son arreglos de canales, con un elemento para cada cliente i. Se necesitan arreglos pues un canal puede ser usado por solo dos procesos. Occam no permite mensajes nulos (señales) de modo que se debe enviar algún valor por el canal acquire aunque no se use este valor. 07 -6 -2004 Programación Concurrente 2004 - Clase 8 27

Uso del constructor ALT en OCCAM. Comentarios. No se permiten output processes en guardas

Uso del constructor ALT en OCCAM. Comentarios. No se permiten output processes en guardas de un constructor ALT. Esto hace que algunos algoritmos sean duros de programar, pero simplifica la implementación. Esto último es especialmente importante pues Occam es el lenguaje de máquina del transputer. Las guardas en un ALT son evaluadas en orden indefinido(no determinístico). El constructor PRI ALT puede usarse para forzar que las guardas sean evaluadas en el orden deseado. 07 -6 -2004 Programación Concurrente 2004 - Clase 8 28

Proceso reloj en OCCAM. Occam también contiene una facilidad de timer. Un timer es

Proceso reloj en OCCAM. Occam también contiene una facilidad de timer. Un timer es una clase especial de canal. Un proceso hardware está siempre listo para enviar hacia algún canal timer declarado en un programa. Si un proceso declara el canal timer myclock, puede leer la hora ejecutando: myclock ? time El proceso también puede demorarse hasta que el reloj alcance un cierto valor ejecutando: myclock ? time AFTER value Aquí, value es un tiempo absoluto, no un intervalo. Un timer también puede usarse en una guarda en un constructor ALT; esto sirve para programar un interval timer. 07 -6 -2004 29 Programación Concurrente 2004 - Clase 8

La extensión de lenguajes secuenciales c/bibliotecas específicas Una técnica muy utilizada es el desarrollo

La extensión de lenguajes secuenciales c/bibliotecas específicas Una técnica muy utilizada es el desarrollo de bibliotecas de funciones que permiten comunicar/sincronizar procesos, NO dependientes de un lenguaje de programación determinado. Las soluciones basadas en bibliotecas (tales como LINDA, MPI, PVM) tienden a ser menos eficientes que los lenguajes “reales”de programación concurrente, aunque tienen la facilidad de “agregarse”al código secuencial con bajo costo de desarrollo. Las arquitecturas distribuidas han potenciado las soluciones basadas en PVM o MPI (que son básicamente bibliotecas de comunicaciones). Un esquema anterior (y original) es el de LINDA que veremos más adelante. 07 -6 -2004 Programación Concurrente 2004 - Clase 8 30

Programación Paralela con el concepto de “bag of tasks” Se parte del concepto de

Programación Paralela con el concepto de “bag of tasks” Se parte del concepto de tener una “bolsa”de tareas que pueden ser compartidas por procesos “worker”. Cada worker ejecuta un código básico: WHILE (true) { obtener un task de la bolsa IF (no hay más tareas) BREAK; # exit del WHILE ejecutar la tarea, incluyendo la creación de otras tareas; } Este enfoque puede usarse para resolver problemas con un número fijo de tareas y también para soluciones recursivas con nuevas tareas creadas dinámicamente. El paradigma del bag of tasks es sencillo, escalable y favorece el balance de carga entre los procesos. 07 -6 -2004 Programación Concurrente 2004 - Clase 8 31

Concepto de “bag of tasks”. Ejemplo. Consideraremos la multiplicación de 2 matrices a y

Concepto de “bag of tasks”. Ejemplo. Consideraremos la multiplicación de 2 matrices a y b de nxn. El ejemplo requiere n 2 productos internos entre filas de a y columnas de b. Cada producto interno es independiente y se puede realizar en paralelo. Suponemos que se dispone de una máquina multiprocesador con PR procesadores físicos, PR < n. Tratando de balancear la carga, puede pensarse en n tareas en la bolsa, una por fila y que cada PR haga uso de un número de tareas de modo de distribuir la carga. Podemos representar la bolsa, simplemente contando filas: INT nextrow = 0; Un worker saca una tarea de la bolsa ejecutando una acción atómica: < row = nextrow; nextrow++; > donde row es una variable local. Notar que lo podemos implementar con un FETCH and ADD. 07 -6 -2004 Programación Concurrente 2004 - Clase 8 32

Multiplicación de matrices con el “bag of tasks”. INT nextrow =0 # la bolsa

Multiplicación de matrices con el “bag of tasks”. INT nextrow =0 # la bolsa de tareas DOUBLE a[n, n], b[n, n], c[n, n]; PROCESS Worker [w=1 TO PR] { INT row; DOUBLE sum; WHILE (true) { # obtener una tarea < row = nextrow; nextrow++; > IF (row >= n) BREAK; Calcular los productos internos para c[row, *] ; } } Para terminar el proceso se pueden contar los BREAK, al llegar a n se tiene la matriz c completa y se puede finalizar el cálculo. 07 -6 -2004 33 Programación Concurrente 2004 - Clase 8

LINDA---> Primitivas para Programación Concurrente. LINDA ofrece una aproximación distintiva al procesamiento concurrente: NO

LINDA---> Primitivas para Programación Concurrente. LINDA ofrece una aproximación distintiva al procesamiento concurrente: NO es un lenguaje de programación, sino un conjunto de seis primitivas que operan sobre una memoria compartida donde hay “tuplas nombradas” (tagged tuples) que pueden ser pasivas (datos) o activas (tasks). En el enfoque de LINDA (que puede agregarse como biblioteca a cualquier lenguaje secuencial) se combinan aspectos de memoria compartida con pasaje de mensajes asincrónicos. Fue concebido en 1983 en la Tesis Doctoral de D. Gelernter (Univ. New York) y sus implementaciones sobre distintos lenguajes se desarrollaron entre esa fecha y 1989. 07 -6 -2004 34 Programación Concurrente 2004 - Clase 8

LINDA---> Primitivas para Programación Concurrente. El núcleo de la idea de LINDA es el

LINDA---> Primitivas para Programación Concurrente. El núcleo de la idea de LINDA es el espacio de tuplas compartidas (TS) que puede verse como un único canal de comunicaciones compartido en el que no existe orden: Depositar una tupla (OUT) funciona como un SEND. Extraer una tupla (IN) funciona como un RECEIVE. RD es la primitiva que permite “leer”como un RECEIVE pero sin extraer la tupla de TS. EVAL permite la creación de procesos (tuplas activas) dentro de TS. Por último IPD y RDP permiten hacer IN y RD no bloqueantes. Si bien hablamos de memoria compartida, TS puede estar físicamente distribuida en una arquitectura multiprocesador (con todas las complejidades asociadas). 07 -6 -2004 35 Programación Concurrente 2004 - Clase 8

LINDA---> Primitivas para Programación Concurrente. El TS consta de una colección no ordenada de

LINDA---> Primitivas para Programación Concurrente. El TS consta de una colección no ordenada de tuplas pasivas y activas. Las tuplas de datos (pasivas) son registros tagged que contienen el estado compartido de un cómputo. Las tuplas activas (de proceso) son rutinas que ejecutan asincrónicamente. La interacción se da leyendo, escribiendo y generando tuplas de datos. Cuando una tupla proceso termina, se convierte en una tupla de datos. Cada tupla de datos en TS tiene la forma: ("tag", value 1, . . . , valuen) El tag es un string literal que se usa para distinguir entre tuplas que representan distintas estructuras de datos. 07 -6 -2004 36 Programación Concurrente 2004 - Clase 8

LINDA---> Primitivas para depositar y extraer de TS. Un proceso deposita una tupla en

LINDA---> Primitivas para depositar y extraer de TS. Un proceso deposita una tupla en TS ejecutando: out("tag", expr 1, . . . , exprn) La ejecución de out termina una vez que las expresiones fueron evaluadas y la tupla de datos resultante fue depositada en TS. La operación out es similar a una sentencia send, excepto que la tupla se almacena en un TS no ordenado en lugar de ser agregada a un canal específico. Un proceso extrae una tupla de datos de TS ejecutando: in("tag", field 1, . . . , fieldn) Cada fieldi o es una expresión o un parámetro formal de la forma ? var donde var es una variable local en el proceso ejecutante. Los argumentos para in son llamados template. El proceso que ejecuta in se demora hasta que TS contenga al menos una tupla que matchee el template, y luego remueve una de TS. 07 -6 -2004 37 Programación Concurrente 2004 - Clase 8

LINDA---> Primitivas para examinar tuplas de datos. La tercera primitiva básica de LINDA es

LINDA---> Primitivas para examinar tuplas de datos. La tercera primitiva básica de LINDA es rd, que se usa para examinar tuplas de datos. Si t es un template, la ejecución de rd(t) demora al proceso hasta que TS contiene una tupla de datos que haga matching. Como con in, las variables en t luego son asignadas con los valores correspondientes de los campos de la tupla de datos. Sin embargo, la tupla permanece en TS. Hay variantes no bloqueantes de in y rd. Las operaciones inp y rdp son predicados que retornan true si hay una tupla matching en TS, y false en otro caso. Si retornan true, tienen el mismo efecto que in y rd respectivamente. Inp y rdp proveen una manera de que un proceso haga polling sobre TS. 07 -6 -2004 38 Programación Concurrente 2004 - Clase 8

LINDA---> Primitivas para crear procesos. La sexta y última primitiva Linda es eval, que

LINDA---> Primitivas para crear procesos. La sexta y última primitiva Linda es eval, que crea tuplas proceso. Esta operación tiene la misma forma que out y también produce una nueva tupla: eval("tag", expr 1, . . . , exprn) Al menos una expresión es un call a una función o procedimiento. Todos los campos de EVAL pueden ser tratados concurrentemente por procesos diferentes y el proceso que escribe el EVAL no espera. Cuando todos los campos son tratados (incluída la ejecución del o los procedimientos/funciones) la tupla se convierte en pasiva (quedan sólo datos) y se agrega a TS. La primitiva eval provee el medio por el cual la concurrencia se puede incorporar en un programa Linda. 07 -6 -2004 39 Programación Concurrente 2004 - Clase 8

LINDA---> Primitivas para crear procesos. Concurrencia con EVAL. Como ejemplo, consideremos la siguiente sentencia

LINDA---> Primitivas para crear procesos. Concurrencia con EVAL. Como ejemplo, consideremos la siguiente sentencia concurrente: co [i : = 1 to n] a[i] : = (i); oc Esto evalúa n llamados de en paralelo y asigna los resultados al arreglo compartido a. El código C-Linda correspondiente es: for ( i = 1; i n; i++ ) EVAL("a", i, f(i)); Esto dispara (forks) n tuplas proceso; cada una evalúa un llamado de f(i). Cuando una tupla proceso termina, se convierte en una tupla de datos que contiene el nombre del arreglo, un índice y el valor de ese elemento del arreglo a. 07 -6 -2004 40 Programación Concurrente 2004 - Clase 8

Generación de nros. primos con C y LINDA. (paradigma bag of tasks) Los workers

Generación de nros. primos con C y LINDA. (paradigma bag of tasks) Los workers comparten TS (bag of tasks). Aquí estarán los números candidatos a primos. Un proceso manager debe depositarlos y recoger los que sean confirmados como primos. Los workers buscan un candidato y deciden si es primo por el método habitual de dividirlo por los primos menores ya existentes. Si lo fuera, lo agrega a la lista (compartida) de primos. La rutina principal hace de manager. Lee los argumentos para saber cuantos primos generar, usa EVAL para crear los workers, tiene una tabla inicial con los primos 2 y 3, envía el primer candidato a primo(5) usando OUT y espera con IN recibir los primos que se vayan generando. Cada primo que recibe lo agrega a TS. Cuando la cuenta de recibidos llega a limit, imprime y termina. 07 -6 -2004 Programación Concurrente 2004 - Clase 8 41

Tareas para la próxima clase Estudiar el resto de la clase. En particular la

Tareas para la próxima clase Estudiar el resto de la clase. En particular la solución de generación de números primos con LINDA y C. Estudiar las primitivas básicas de MPI y PVM. Analizar soluciones de algunos problemas clásicos con mensajes sincrónicos: Filósofos centralizados. Broadcast de un servidor a N clientes. Broadcast de cualquier proceso a N pares. Analice los problemas de la molécula de agua y el puente de una vía con mensajes sincrónicos. Plantee una solución para cada uno con un esquema C-S y suponiendo cualquier herramienta de programación de las vistas: OCCAM, C+LINDA, XX+MPI XX+PVM. Programación Concurrente 2004 - Clase 8 07 -6 -2004 42

Ejercicio para la promoción 1 - Escriba muy sintéticamente las ventajas/desventajes de mensajes sincrónicos

Ejercicio para la promoción 1 - Escriba muy sintéticamente las ventajas/desventajes de mensajes sincrónicos respecto de los mensajes asincrónicos. 2 - Ud. tiene una red (por ejemplo móvil) conectada sin cables. Debe hacer un análisis para que todos sepan quienes están conectados en la red. Usaría mensajes sincrónicos o asincrónicos? Por qué? 3 - Si se tratara de hacer un broadcast en una red conectada en anillo, qué diferencias ve entre SMP y AMP? 4 - De lo visto de OCCAM, qué utilidad le ve a la instrucción ALT? Por qué utilizaría guardas en un ALT? Con qué estructura de ADA la asimilaría? Indique alguna característica en sincronización que tenga ADA y no OCCAM. 07 -6 -2004 Programación Concurrente 2004 - Clase 8 43

Números primos con C y LINDA. El Main Real_main(INT argc, CHAR *argv[ ] )

Números primos con C y LINDA. El Main Real_main(INT argc, CHAR *argv[ ] ) { INT primes[ limit] = {2, 3}; /*tabla de primos*/ INT limit, numworkers, i, isprime; INT numprimes=2, value=5; limit = atoi (argv[ 1]) ; /*se lee cuantos generar */ numworkers= atoi (argv[ 2] ); /* Crear los workers y poner el primer primo en TS */ FOR (i=1; i <= numworkers; i++ ) EVAL (“worker”, worker() ); OUT(“candidate”, value); /* Obtener los resultados de los workers en orden creciente */ WHILE (numprimes < limit) { IN (“result”, value, ? isprime); IF (isprime) { /*poner el valor en la tabla y en TS*/ primes[numprimes] = value; OUT (“prime”, numprimes, value); numprimes++; } value=value + 2; } OUT (“stop”); /* avisa a los workers que terminen */ IMPRIMIR; } 07 -6 -2004 44 Programación Concurrente 2004 - Clase 8

Generación de nros. primos con C y LINDA. (paradigma bag of tasks) Cada worker

Generación de nros. primos con C y LINDA. (paradigma bag of tasks) Cada worker tiene una tabla local de factores primos. Esta tabla la va extendiendo cuando necesita nuevos primos para testear un número candidato. Este nuevo primo lo obtiene de TS en orden creciente (estricto para evitar deadlock). En cada iteración un worker usa RDP para saber si tiene que parar. Qué busca? La tupla “stop”. Notar que como los workers NO manejan limit, es posible que hagan más trabajo del necesario antes de que el manager se dé cuenta y envíe el STOP. La solución para los workers no es óptima y requiere 2 accesos a TS para un número primo (como candidato y como resultado). En general los accesos a TS serán mucho menos eficientes que aquéllos a memoria local. 07 -6 -2004 Programación Concurrente 2004 - Clase 8 45

Los procesos WORKER Void worker ( ) { INT primes[ limit] = {2, 3};

Los procesos WORKER Void worker ( ) { INT primes[ limit] = {2, 3}; /*tabla de primos*/ INT numprimes=1, i, candidate, isprime; /* Obtener repetidamente un candidato a primo y chequearlo */ WHILE (true) { IF ( RDP (“stop”) ) RETURN; IN (“candidate”, ? candidate); /*obtiene un candidato */ OUT (“candidate”, candidate +2); /* pone el siguiente candidato */ i=0; isprime=1; WHILE (primes[i] * primes[i] <= candidate { IF (candidate % primes[i] == 0) { /*NO es primo */ isprime=0; break; } i++; IF (i > numprimes ) { /* necesito otro primo */ numprimes++; RD ( “prime” , numprimes, ? primes[numprimes]); } } OUT (“result”, candidate, isprime); /*se envia el resultado al manager */ } 07 -6 -2004 46 Programación Concurrente 2004 - Clase 8

Comunicación y Sincronización en arquitecturas distribuidas: MPI (message passing interfase) es una biblioteca de

Comunicación y Sincronización en arquitecturas distribuidas: MPI (message passing interfase) es una biblioteca de rutinas de pasaje de mensajes, que permite comunicar y sincronizar procesos secuenciales escritos en diferentes lenguajes, que se ejecutan sobre una arquitectura distribuida. MPI fue definido en 1996 como una evolución de PVM y se ha constituido en un standard de hecho. El estilo de programación en MPI es SPMD (múltiples copias del mismo proceso se ejecutan en diferentes procesadores sobre diferentes datos). Cuando un proceso tiene que sincronizar o ejecutar acciones diferentes a los demás, puede utilizar primitivas de MPI (incluso para autoidentificarse). 07 -6 -2004 47 Programación Concurrente 2004 - Clase 8

La biblioteca MPI. Un ejemplo simple. Supongamos dos procesos que deben intercambiar valores (14

La biblioteca MPI. Un ejemplo simple. Supongamos dos procesos que deben intercambiar valores (14 y 25). La solución empleando MPI tendría la siguiente forma: # include <mpi. h> main (INT argc, CHAR *argv [ ] ) { INT myid, otherid, size; INT length=1, tag=1; INT myvalue, othervalue; MPI_status; MPI_Init (&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &size); MPI_Comm_Rank (MPI_COMM_WORLD, &myid); IF (myid == 0) { otherid = 1; myvalue=14; } ELSE { otherid=0; myvalue=25; } MPI_send (&myvalue, length, MPI_INT, otherid, tag, MPI_COMM_WORLD); MPI_recv (&othervalue, length, MPI_INT, MPI_any_source, tag, MPI_COMM_WORLD, &status); printf (“process %d received a %dn”, myid, othervalue); MPI_Finalize ( ); } 07 -6 -2004 Programación Concurrente 2004 - Clase 8 48

La biblioteca MPI_Init inicializa la biblioteca MPI y obtiene una copia de los comandos

La biblioteca MPI_Init inicializa la biblioteca MPI y obtiene una copia de los comandos pasados al programa. La variable MPI_COMM_WORLD es inicializada con el conjunto de procesos que se arrancan. MPI_COMM_Size determina el número de procesos arrancados (2) MPI_COMM_Rank determina la identificación del proceso (0 a size-1) MPI_Finalize Termina este proceso y libera la bilioteca MPI_Send envía un mensaje a otro proceso. Los argumentos son: el buffer que contiene el mensaje, el número de elementos a enviar, el tipo de datos del mensaje, la identidad del proceso destino, un tag del usuario para identificar el tipo de mensaje y la variable MPI_COMM_WORLD. MPI_Recv recibe un mensaje de otro proceso. Los argumentos son: el buffer en el cual poner el mensaje, el número de elementos del mensaje, el tipo de datos del mensaje, la identidad del proceso que envía o “no importa”= MPI_any_source, un tag del usuario para identificar el tipo de mensaje, el grupo de comunicación y el status de retorno. 07 -6 -2004 Programación Concurrente 2004 - Clase 8 49

Algunos comentarios bibliográficos WWW. hensa. ac. uk/parallel tiene buena información sobre herramientas en OCCAM,

Algunos comentarios bibliográficos WWW. hensa. ac. uk/parallel tiene buena información sobre herramientas en OCCAM, comparación de OCCAM con ADA y las ideas de OCCAM 3 (aún no implementado) WWW. comlab. ox. ac. uk/oucl/publications/books/concurrency/ tiene la info del libro de ROSCOE del 98 en el que se da la última versión de CSP. Las publicaciones de Glernter sobre su Tesis y demás y la página WWW. sca. com tienen datos de LINDA. Hay varios sitios para lo de MPI o PVM. Entre ellos: WWW. mpi. nd. edu/lam/ WWW-unix. mcs. anl. gov/mpich/ WWW. epm. ornl. gov/pvm_home. html Hartley en el 98 dio un enfoque diferente de JAVA en programación distribuída. Su página es: WWW. mcs. drexel. edu/~shartley/conc. Prog. Java/ 07 -6 -2004 50 Programación Concurrente 2004 - Clase 8

Estudiar para la próxima clase de la biblioteca MPI_Barrier MPI_Bcast MPI_Scatter MPI_Gather MPI_Reduce MPI_Allreduce

Estudiar para la próxima clase de la biblioteca MPI_Barrier MPI_Bcast MPI_Scatter MPI_Gather MPI_Reduce MPI_Allreduce 07 -6 -2004 51 Programación Concurrente 2004 - Clase 8