• No se han encontrado resultados

Taller de Programación Paralela

N/A
N/A
Protected

Academic year: 2021

Share "Taller de Programación Paralela"

Copied!
15
0
0

Texto completo

(1)

Taller de Programaci´

on Paralela

Fernando R. Rannou

Departamento de Ingenier´ıa Inform´atica Universidad de Santiago de Chile

April 26, 2007 Concurrencia 2 Concurrencia y sincronizaci´on . . . 3 Beneficios de concurrencia . . . 4 Ejemplo de problema . . . 5 Definici´on de t´erminos. . . 6 Modelo de concurrencia. . . 7

Requerimientos para una soluci´on . . . 8

Soluciones por hardware 1 . . . 9

Soluciones por hardware 2, testset() . . . 10

EM por instrucciones de m´aquina . . . 11

Soluciones por software 1 . . . 12

Soluci´on de Peterson. . . 13

Sem´aforos . . . 14

Primitivas sobre sem´aforos . . . 15

Sem´aforo binario o mutex . . . 16

EM usando sem´aforos . . . 17

El problema del productor/consumidor. . . 18

Soluci´on productor/consumidor con sem´aforos . . . 19

Sincronizaci´on con hebras POSIX . . . 20

Mutex . . . 21

Variables de condici´on . . . 22

Productor/consumidor usando pthreads . . . 23

El Productor . . . 24

El Consumidor . . . 25

Barreras para hebras . . . 26

Implementaci´on barreras con pthreads . . . 27

Inicializaci´on de barrera . . . 28

Espera con barreras . . . 29

(2)

Concurrencia

2 / 30

Concurrencia y sincronizaci´on

■ Cuando dos o m´a tareas (procesos o hebras) comparten alg´un recurso en forma concurrente o paralela, debe existir un mecanismo que sincronice sus actividades

■ El riesgo: corrupci´on del recurso compartido

■ Ejemplos:

1. Acceso a impresora en un sistema distribuido 2. Consulta y actualizaci´on de una base de datos

3. Ejecuci’on paralela de tareas para resolver un problema en conjunto

■ Los problemas de sincronizaci´on no s´olo ocurren en sistemas multiprocesadores, sino tambi´en (y fundamentalmente) en monoprocesadores

Fernando R. Rannou

Diinf-USACH 3 / 30

Beneficios de concurrencia

■ Aumento en el rendimiento mediante m´ultiples procesadores

u Paralelsimo

■ Aumento del throughput de las aplicaciones

u Un llamado a una operaci´on de I/O s´olo bloquea una hebra

■ Mejora en interactividad de las aplicaciones

u Asignar mayor prioridad a hebras que atiendan al usuario

■ Mejora en la estructuraci´on de aplicaciones

■ Sistemas distribuidos Fernando R. Rannou

(3)

Ejemplo de problema

■ Considere dos procesos que ejecutan concurrentemente a la funcionecho()del SO: * void echo() { chin = getchar(); chout = chin; putchar(chout); }

■ Asuma quechines variable compartida *

Proceso 1 Proceso 2

. .

chin = getchar();

<- interrupcion chin = getchar(); chout = chin; <- interrupcion chout = chin;

putchar(chout);

putchar(chout);

■ Soluci´on: permitir que s´olo un proceso ejecuteecho()a la vez Fernando R. Rannou

Diinf-USACH 5 / 30

Definici´on de t´erminos

■ Unasecci´on cr´ıtica(SC) es una secci´on de c´odigo de un proceso o hebra que accesa recursos compartidos, la cual (la secci´on) no puede ser ejecutada mientras otro proceso est´a ejecutando su SC correspondiente

■ Por ejemplo,echo()en el ejemplo anterior es SC.

■ Exclusi´on m´utuaes el requerimiento que cuando un proceso est´a en una SC que accesa ciertos recursos compartidos, ning´un otro proceso puede estar ejecutando su correspondiente SC en la cual accesa alguno de dichos recursos

■ Deadlockocurre cuando dos o m´as procesos no pueden progresar porque cada uno est´a esperando que otro proceso realize alguna acci´on

■ Inhanici´ones cuando un proceso en estado de listo, nunca es planificado en el procesador. Fernando R. Rannou

(4)

Modelo de concurrencia

■ Asumimos una colecci´on de procesos del tipo * Process(i) { while (true) { codigo no critico ... enterSC(); SC(); exitSC(); .. codigo no critico } }

■ enterSC()representa las acciones que el proceso debe realizar para poder entrar a su SC

■ exitSC()representa las acciones que el proceso debe realizar para salir la SC y dejarla habilitada a otros procesos

■ El c´odigo no cr´ıtico es cualquier c´odigo que el proceso ejecuta que no accede recursos compartidos Fernando R. Rannou

Diinf-USACH 7 / 30

Requerimientos para una soluci´on

■ El objetivo es proveer menanismos que implementenenterSC()yexitSC()que satisfagan los siguientes 3 requerimientos

1. Exclusi´on m´utua: CuandoPiest´a en su SC, ning´un otro procesoPj est´a en su correspondiente SC. Esto significa que la ejecuci´on de operaciones de las secciones cr´ıticas no son concurrentes

2. Sin deadlock: Deadlock ocurrir´ıa cuando todos los procesos quedan ejecutandoenterSC()indefinidamente, y por lo tanto, ninguno entra y ninguno progresa

3. Sin inhanici´on: Se debe garantizar que un procesoPi que ejecutaenterSC(), eventualmente lo haga

■ Notas

u Un proceso puede tener m´as de un SC

u Libre de deadlock no garantiza que alg´un proceso se bloquee indefinidamente

u Libre de inhanici´on no dice cuando un proceso entra a la SC

u La soluci´on no debe realizar suposiciones sobre la velocidad relativa y orden de ejecuci´on de los procesos Fernando R. Rannou

(5)

Soluciones por hardware 1

■ Deshabilitaci´on de interrupcionesRecordar que un proceso se ejecuta hasta que invoca un llamado al SO o es interrumpido. Entonces para garantizar EM, el proceso deshabilita las interrupciones justo antes de entrar en su SC

while (true) { deshabilitar_interrupciones(); SC(); habilitar_interrupciones(); }

■ Habilidad del procesador para hacer context-switch queda limitada

■ No sirve para multiprocesadores Fernando R. Rannou

Diinf-USACH 9 / 30

Soluciones por hardware 2, testset()

■ Uso de instrucciones especiales de m´aquinaque realizan en forma at´omica m´as de una operaci´on.

■ Por ejemplotestset()

boolean testset(var int i) { int bolts;

if (i == 0) { P(i) {

i = 1; while (true) {

return true; codigo no critico } else return false; while (!testset(bolt));

} SC(); bolt = 0; codigo no critico } } void main() { bolt = 0; parbegin(P(1), P(2), ..., P(n)); } Fernando R. Rannou Diinf-USACH 10 / 30

(6)

EM por instrucciones de m´aquina

■ Ventajas

u Aplicable a cualquier n´umero de procesos y procesadores que comparten memoria f´ısica

u Simple y f´acil de verificar

u Puede ser usada con varias SC, cada una controlada por su propia variable

■ Desventajas

u Busy-waiting(ospin-lock) consume tiempo de procesador

u Es posible inhanici´on Fernando R. Rannou

Diinf-USACH 11 / 30

Soluciones por software 1

■ Dos procesos comparten la variableturno

int turno;

P(i) { P(i) {

while (true) { while (true) { codigo no critico codigo no critico while (turno != 0); while (turno != 1);

SC(); SC();

turno = 1; turno = 0;

codigo no critico codigo no critico

} } } } void main() { turno = 0; parbegin(P(0), P(1)); }

■ Garantiza exclusi´on m´utua

■ S´olo aplicable a dos procesos

■ Alternaci´on estricta de ejecuci´on Fernando R. Rannou

(7)

Soluci´on de Peterson

■ Dos procesos comparten dos variable: flag[2]yturno

boolean flag[2]; int turno;

P(i) { P(i) {

while (true) { while (true) { codigo no critico codigo no critico flag[0] = true; flag[1] = true;

turno = 1; turno = 0;

while (flag[1] && turno == 1); while (flag[0] && turno == 0);

SC(); SC();

flag[0] = false; flag[1] = false; codigo no critico codigo no critico

} }

} }

void main(){

flag[0] = flag[1] = false; parbegin(P(0), P(1)); }

Fernando R. Rannou

Diinf-USACH 13 / 30

Sem´aforos

■ Una sem´aforo es una variable especial usada para que dos o m´as procesos se se˜nalicen m´utuamente

■ Un sem´aforo es una variable entera, pero

■ Accesada s´olo por dos operaciones

1. wait(s)decrementa el sem´aforo; si el valor resultante es negativo, el proceso se bloquea; sino, contin´ua su ejecuci´on

2. signal(s)incrementa el sem´aforo; si el valor resultante es menor o igual que cero, entonces se despierta un proceso que fue bloqueado porwait()

■ Inicializada con un n ´mero no negativo Fernando R. Rannou

(8)

Primitivas sobre sem´aforos struct semaphore { int count; queueType queue; } void wait(semaphore s) { s.count--; if (s.count < 0) {

place this process in s.queue; block this process

} } void signal(semaphore s) { s.count++; if (s.count <= 0) {

remove a process P from s.queue; place process P on ready state }

} Fernando R. Rannou

Diinf-USACH 15 / 30

Sem´aforo binario o mutex

■ Un sem´aforo binario s´olo puede tomar los valores 0 o 1

wait(s) signal(s)

{ {

if (s.value == 1) if (s.queue is empty())

s.value = 0; s.value = 1

else { else {

place this process in s.queue remove a process P from

block this process s.queue;

} place P on the ready list;

} }

} Fernando R. Rannou

(9)

EM usando sem´aforos semaphore s; Process(i) { while (true) { codigo no critico ... wait(s) SC(); signal(s); .. codigo no critico } } void main() { s = 1; parbegin(P(1), P(2),...,P(n)); } Fernando R. Rannou Diinf-USACH 17 / 30

El problema del productor/consumidor

■ Uno o m´as procesos productores generan datos y los almacenan en un buffer compartido

■ Un proceso consumidor toma (consume) los datos del buffer uno a la vez

■ Claramente, s´olo un agente (productor o consumidor) pueden accesar el buffer a la vez

producer() { consumer() {

while (true) { while (true) {

v = produce(); while (in == out); while ((in + 1) % n == out); /* do nothing */ /* do nothing */ w = b[out];

b[in] = v; out = (out + 1) % n; in = (in + 1) % n consume(w);

} }

}

■ El buffer es de largony tratado circularmente

(10)

Soluci´on productor/consumidor con sem´aforos

const int sizeofbuffer; semaphore s = 1; semaphore full = 0;

semaphore empty = sizeofbuffer;

producer() consumer() { { while(true) { while(true) { v = produce(); wait(full); wait(empty); wait(s); wait(s); w = take_from_buffer(); put_in_buffer(v); signal(s); signal(s); signal(empty); signal(full); consume(w); } } } } Fernando R. Rannou Diinf-USACH 19 / 30

Sincronizaci´on con hebras POSIX

■ Hebras POSIX definen funciones para la sincronizaci´on de hebras

1. mutexes: parecidos a los sem´aforos binarios y sirven para proveer exclusi´on m´utua a cualquier n´umero de hebras de un proceso

2. variables de condici´on: un mecanismo asociado a los mutexes. Permiten que una hebra se bloquee y libere la SC en la que se encuentra

■ Estos mecanismos no sirven para sincronizar hebras de distintos procesos Fernando R. Rannou

(11)

Mutex

■ Un mutex es la forma m´as b´asica de sincronizaci´on y provee el mismo servicio que un sem´aforo binario

■ Generalmente se utilizan para implementar acceso exclusivo a SC de las hebras *

#include <pthread.h>

int pthread_mutex_lock(pthread_mutex_t *mutex); int pthread_mutex_trylock(pthread_mutex_t *mutex); int pthread_mutex_unlock(pthread_mutex_t *mutex);

int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr); pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

int pthread_mutex_destroy(pthread_mutex_t *mutex);

■ Si una hebra invocapthread_mutex_lock(m) y el mutexmya est´a tomado, entonces la hebra se bloquea (en ese mutex), sino toma (cierra) el mutex y contin´ua su ejecuci´on

■ Si una hebra invocapthread_try_lock(m)y el mutexmya est´a tomado, entoncespthread_try_lock(m)

retorna un c´odigo de errorEBUSY; la hebra no se bloquea y puede continuar su ejecuci´on (fuera de la SC) Fernando R. Rannou

Diinf-USACH 21 / 30

Variables de condici´on

■ ¿ Qu´e suceder´ıa si una hebra se bloquea dentro de una SC?

■ Una variable de condici´on permite que una hebra se bloquee dentro de una SC y al mismo tiempo libere la secci´on cr´ıtica

int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t * mutex); int pthread_cond_signal(pthread_cond_t *cond);

int pthread_cond_broadcast(pthread_cond_t *cond); int pthread_cond_destroy(pthread_cond_t *cond);

int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t * attr); pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

■ La hebra que invocapthread_cond_wait(c, m)se bloquea hasta que la condici´oncsese˜nalice; adem´as libera el mutexm

■ pthread_cond_signal(c) se˜naliza o despierta alguna otra hebra que est´a bloqueada en la variable de condici´onc

■ pthread_cond_broadcast(c) desbloquea todas las hebras esperando enc

(12)

Productor/consumidor usando pthreads

typedef struct {

int buf[QUEUESIZE]; int head, tail; int full, empty; pthread_mutex_t mutex;

pthread_cond_t notFull, notEmpty; } buffer_t;

void main() {

buffer_t *buffer; pthread_t pro, con; buffer = bufferInit();

pthread_mutex_init(&buffer->mutex, NULL); pthread_cond_init(&buffer->notFull, NULL); pthread_cond_init(&buffer->notEmpty, NULL);

pthread_create(&pro, NULL, producer, (void *) buffer); pthread_create(&con, NULL, consumer, (void *) buffer); pthread_join (pro, NULL);

pthread_join (con, NULL); exit 0;

}

Fernando R. Rannou

Diinf-USACH 23 / 30

El Productor

void *producer(void *arg) {

int v;

buffer_t *buffer;

buffer = (buffer_t *) arg; while (true) {

v = produce();

pthread_mutex_lock (&buffer->mutex); while (buffer->full) {

pthread_cond_wait (&buffer->notFull, &buffer->mutex); } put_in_buffer(buffer, v); pthread_cond_signal(&buffer->notEmpty); pthread_mutex_unlock(&buffer->mutex); } }

(13)

El Consumidor

void *consumer (void *arg) {

int v;

buffer_t *buffer;

buffer = (buffer_t *) arg; while (true) {

pthread_mutex_lock (&buffer->mutex); while (buffer->empty) {

pthread_cond_wait (&buffer->notEmpty, &buffer->mutex); } v = take_from_buffer(buffer); pthread_cond_signal(&buffer->notFull); pthread_mutex_unlock(&buffer->mutex); } } Fernando R. Rannou Diinf-USACH 25 / 30

Barreras para hebras

■ Una barrera es un mecanismo de sincronizaci´on detener (bloquear) la ejecuci´on de un grupo de hebras en un mismo punto del programa

■ Cuando la barrera est´a a bajo las hebras se detienen en ella en el orden en que llegan

■ Cuando la barrera se levanta, las hebras contin´uan su ejecuci´on

■ Las barreras son ´utiles para implementarpuntos de sincronizaci´onglobales en un algoritmo

■ Usamos mutex y variables de condici´on para implementar barreras

■ Implementamos las siguientes funciones 1. barrier_init()

2. barrier_wait()

3. barrier_destroy()

Fernando R. Rannou

(14)

Implementaci´on barreras con pthreads

■ Una posible forma de implementaci´on es usando dos mutexes y dos variables de condici´on

■ Cada par representa una barrera struct _sb { pthread_cond_t cond; pthread_mutex_t mutex; int runners; }; typedef struct { int maxcnt; struct _sb sb[2]; struct _sb *sbp; } barrier_t; Fernando R. Rannou Diinf-USACH 27 / 30 Inicializaci´on de barrera

int barrier_init(barrier_t *bp, int count) {

int i;

if (count < 1) {

printf("Error: numero de hebras debe ser mayor que 1\n"); exit(-1);

}

bp->maxcnt = count; bp->sbp = &bp->sb[0]; for (i=0; i < 2; i++) {

struct _sb *sbp = &(bp->sb[i]); sbp->runners = count; pthread_mutex_init(&sbp->mutex, NULL); pthread_cond_init(&sbp->cond, NULL); } return(0); } Fernando R. Rannou Diinf-USACH 28 / 30

(15)

Espera con barreras int barrier_wait(barrier_t *bp) { struct _sb *sbp = bp->sbp; pthread_mutex_lock(&sbp->mutex); if (sbp->runners == 1) { if (bp->maxcnt != 1) { sbp->runners = bp->maxcnt;

bp->sbp = (bp->sbp = &bp->sb[0])? &bp->sb[1] : &bp->sb[0]; pthread_cond_broadcast(&sbp->cond);

} } else {

sbp->runners--;

while (sbp->runners != bp->maxcnt)

pthread_cond_wait(&sbp->cond, &sbp->mutex); } pthread_mutex_unlock(&sbp->wait_mutex); } Fernando R. Rannou Diinf-USACH 29 / 30 Uso de barreras

void *proceso(void *arg) { int *tidptr, tid;

tidptr = (int *) arg; tid = *tidptr;

printf("hola justo antes de la barrera%d\n", tid); barrier_wait(&barrera);

}

int main(int argc, char *argv[]) {

int i, status; pthread_t hebra[10]; barrier_init(&barrera, 10); for (i=0; i < 10; i++){

taskids[i] = (int *) malloc(sizeof(int)); *taskids[i] = i;

pthread_create(&hebra[i], NULL, &proceso, taskids[i]); }

for (i=0; i < 10; i++)

pthread_join(hebra[i], (void **) &status); barrier_destroy(&barrera);

Referencias

Documento similar

Volviendo a la jurisprudencia del Tribunal de Justicia, conviene recor- dar que, con el tiempo, este órgano se vio en la necesidad de determinar si los actos de los Estados

cv.wait espera hasta que reciba una notifiación, entonces hace lock con el mutex y pregunta por la condición (lambda).. Variables

Como asunto menor, puede recomendarse que los órganos de participación social autonómicos se utilicen como un excelente cam- po de experiencias para innovar en materia de cauces

Tras establecer un programa de trabajo (en el que se fijaban pre- visiones para las reuniones que se pretendían celebrar los posteriores 10 de julio —actual papel de los

Por PEDRO A. EUROPEIZACIÓN DEL DERECHO PRIVADO. Re- laciones entre el Derecho privado y el ordenamiento comunitario. Ca- racterización del Derecho privado comunitario. A) Mecanismos

La conclusi´ on fue que para un n´ umero peque˜ no de par´ ametros (del orden de la decena), el m´ etodo simplex es hasta 4 veces m´ as r´ apido, obteniendo unos valores del m´

En la Sentencia de 23 de marzo de 1934 se dice que en las relaciones wtre los funcionarios públicos y la Administración, a la cual sirven, ca- ben dos sistemas: el de estatutos y el

En el capítulo de desventajas o posibles inconvenientes que ofrece la forma del Organismo autónomo figura la rigidez de su régimen jurídico, absorbentemente de Derecho público por