53
Memória Compartilhada

Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

Embed Size (px)

Citation preview

Page 1: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

Memória Compartilhada

Page 2: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

Programação com memória compartilhada

• Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória pode ser acessada por qualquer processador

• Existe um espaço de endereçamento único, ou seja, cada localização de memória possui um único endereço dentro de uma extensão única de endereços

Page 3: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

Arquitetura com barramento único

Barramento

Cache

Processadores Módulos de memória

Page 4: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

Alternativas para programação

• Utilizar uma nova linguagem de programação• Modificar uma linguagem seqüencial existente• Utilizar uma linguagem seqüencial existente com

rotinas de bibliotecas• Utilizar uma linguagem de programação seqüencial e

deixar a cargo de um compilador paralelizador a geração de um código paralelo executável

• Processos UNIX• Threads (Pthreads, Java, ...)

Page 5: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

Algumas linguagens de programação paralelas

Linguagem Criador/data Comentários

Ada Depto. de defesaamericano

Nova linguagem

C* Thinking Machines,1987

Extensão a C parasistemas SIMD

Concurrent C Gehani e Roome,1989

Extensão a C

Fortran F Foz et al., 1990 Extensão a Fortranpara programaçãopor paralelismo dedados

Modula-P Braünl, 1986 Extensão a Modula 2

Pascal concorrente Brinch Hansen,1975

Extensão ao Pascal

Page 6: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

Criação de processos concorrentes utilizando a construção fork-join

Programa principal

FORK

JOIN

FORK

FORKJOIN

JOIN JOIN

Page 7: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

Processos UNIX

• A chamada do UNIX fork() cria um novo processo, denominado processo filho

• O processo filho é uma cópia exata do processo que chama a rotina fork(), sendo a única diferença um identificador de processo diferente

• Esse processo possui uma cópia das variáveis do processo pai inicialmente com os mesmos valores do pai

• O processo filho inicia a execução no ponto da chamada da rotina• Caso a rotina seja executada com sucesso, o valor 0 é retornado

ao processo filho e o identificador do processo filho é retornado ao processo pai

Page 8: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

Processos UNIX• Os processos são “ligados” novamente através das chamadas ao

sistema:– wait(status): atrasa a execução do chamador até receber um sinal ou um dos seus processos

filhos terminar ou parar– exit(status): termina o processo

• Criação de um único processo filhopid = fork();código a ser executado pelo pai e filhoif (pid == 0) exit (0); else wait (0)

• Filho executando código diferentepid = fork();if (pid == 0) { código a ser executado pelo filho} else { código a ser executado pelo pai}if (pid == 0) exit (0); else wait (0);

Page 9: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

Threads

Arquivos

IP

Pilha

CódigoHeap

Rotinas de interrupção

Processos: programas completamente separados com suas próprias variáveis, pilha e alocação de memória

Arquivos

IPPilha Código

Heap

Rotinas de interrupçãoIPPilha

Threads: as rotinas compartilham o mesmo espaço de memória e variáveis globais

Page 10: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

PthreadsInterface portável do sistema operacional, POSIX, IEEE

Programa principal

pthread_create(&thread1, NULL, proc1, &arg);

pthread_join(thread1, NULL, &status);

thread1

proc1(&arg);{

return(&status);}

Page 11: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

Barreira para Pthreads

• A rotina pthread_join() espera pelo término de uma thread específica

• Para criar uma barreira para esperar pelo término de todas as threads, pode-se repetir a chamada da rotina:for (i = 0; i < n; i++) pthread_create(&thread[i], NULL, (void *) slave, (void *) &arg); . .for (i = 0; i < n; i++) pthread_join(thread[i], NULL);

Page 12: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

Threads desunidasUma thread não precisa saber do término de uma outra por ela criada, então não executa-se a operação de união

Programa principal

pthread_create();

pthread_create();

Thread

pthread_create();Thread

Thread Término

TérminoTérmino

Page 13: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

Ordem de execução das instruções

• As execuções das instruções dos processos/threads individuais podem ser entrelaçadas no tempo

• Exemplo:Processo 1 Processo 2Instrução 1.1Instrução 2.1Instrução 1.2Instrução 2.2Instrução 1.3Instrução 2.3

Possível ordem de execução no tempo:Instrução 1.1Instrução 1.2Instrução 2.1Instrução 1.3Instrução 2.2Instrução 2.3

Page 14: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

Ordem de execução das instruções

• Se dois processos devem imprimir mensagens, por exemplo, as mensagens podem aparecer em ordens diferentes dependendo do escalonamento dos processos que chamam a rotina de impressão

• Os caracteres individuais de cada mensagem podem aparecer uns inseridos entre outros, caso as instruções de máquina das instâncias da rotina de impressão sejam divididas em passos menores que possam ser interrompidos

Page 15: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

Otimizações do compilador/processador

• O compilador ou processador pode reordenar as instruções para tentar otimizar a execução

• Exemplo:– As instruções abaixo

a = b + 5;x = y + 4;

podem ser executadas em ordem contrária:x = y + 4;a = b + 5;

e o programa continua logicamente correto

Page 16: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

Rotinas seguras para threads

• As chamadas ao sistema ou rotinas de bibliotecas são denominadas seguras para threads, quando elas podem ser acionadas por várias threads ao mesmo tempo e sempre produzem resultados corretos

• Rotinas padrão de E/S: imprimem mensagens sem permitir interrupção entre impressão de caracteres

• Rotinas que acessam dados compartilhados os estáticos requerem cuidados especiais para serem seguras para threads

• Pode-se forçar a execução da rotina somente por uma thread de cada vez, ineficiente

Page 17: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

Acessando dados compartilhados

• Considere dois processos que devem ler o valor de uma variável x, somar 1 a esse valor e escrever o novo valor de volta na variável x

Instruçãox = x + 1

Processo 1ler xcalcular x + 1escrever x

Processo 2ler xcalcular x + 1escrever x

tempo

Page 18: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

Conflito em acesso a dados compartilhados

Variável compartilhada, x

+1 +1

Processo 1 Processo 2

Ler LerEscrever Escrever

Page 19: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

Seção crítica• Devem existir mecanismos para assegurar que somente um processo

possa acessar um determinado recurso durante um certo tempo• Estabelecem-se sessões de código que envolvem o recurso,

denominadas seções críticas, e organiza-se o acesso a elas de tal modo que somente uma delas pode ser executada por um processo de cada vez

• Um processo impede que outros processos acessem as seções críticas que possui um determinado recurso compartilhado quando ele estiver acessando

• Quando um processo finaliza a execução da seção crítica, outro processo pode executá-la

• Mecanismo conhecido como exclusão mútua

Page 20: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

Lock

• Mecanismo mais simples de assegurar exclusão mútua para acesso a seções críticas

• O lock é uma variável de 1 bit que possui o valor 1 quando existe algum processo na seção crítica e 0 quando nenhum processo está na seção crítica

• Um processo que chega a uma porta da seção crítica e a acha aberta pode entrar, trancando-a para prevenir que nenhum outro processo entre

• Assim que o processo finaliza a execução da seção crítica, ele destranca a porta e sai

Page 21: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

Spin lockwhile (lock == 1) do_nothing;lock = 1; . seção crítica .lock=0;

Processo 1 Processo 2

while (lock == 1) do _nothing; while (lock == 1) do_nothing;lock =1;

seção crítica

lock=0;lock = 1;

seção crítica

lock = 0;

Page 22: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

Rotinas de lock para Pthreads

• Os locks são implementados com variáveis lock mutuamente exclusivas, ou variáveis “mutex”

• Para utilizá-la, deve-se declará-la com o tipo pthread_mutex_t e inicialiá-la:pthread_mutex_t mutex1;

.

.pthread_mutex_init(&mutex1, NULL);

• Uma variável mutex pode ser destruída utilizando-se a rotina pthread_mutex_destroy()

Page 23: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

Rotinas de lock para Pthreads

• Uma seção crítica pode ser protegida utilizando-se pthread_mutex_lock() e pthread_mutex_unlock()pthread_mutex_lock(& mutex1);

.seção crítica .pthread_mutex_unlock(&mutex1);

• Se uma thread chega em uma rotina de trancamento de uma variável mutex e a encontra trancada, ela espera até que seja destrancada

• Se mais de uma thread está esperando o destrancamento, o sistema escolhe aquela que poderá prosseguir

• Somente a thread que tranca uma variável pode destrancá-la

Page 24: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

Deadlock

• Pode ocorrer com dois processos quando um deles precisa de um recurso que está com outro e esse precisa de um recurso que está com o primeiro

R1 R2

P1 P2 Processo

Recurso

Page 25: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

Deadlock

• Pode ocorrer em modo circular com vários processos possuindo um recurso necessário a um outro

R1 R2

P1 P2

Rn-1 Rn

Pn-1 Pn

Page 26: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

Rotina para evitar deadlock em Pthreads

• Pthreads oferece uma rotina para testar se uma variável está trancada sem bloquear a thread

• pthread_mutex_trylock()– tranca uma variável mutex que esteja destrancada e retorna o valor 0, ou

retorna o valor EBUSY caso a variável esteja trancada

Page 27: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

Semáforos

• Um semáforo s é um inteiro positivo (incluindo o 0) operado por duas operações denominadas P e V

• Operação P(s)– espera até que s seja maior que 0, a decrementa de 1 e permite que o processo

continue a sua execução

• Operação V(s)– incrementa s de 1 para liberar algum processo que esteja esperando

• As operações P e V são executadas de forma indivisível• Mecanismo de espera implícito nas operações• Os processo atrasados por P(s) são mantidos parados até serem

liberados por uma operação V(s) sobre o mesmo semáforo

Page 28: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

Exclusão mútua de seções críticas

• Pode ser implementada através de um semáforo binário, que só assume os valores 0 e 1

• Funciona como uma variável lock mas as operações P e V incluem um mecanismo de escalonamento de processos

• O processo é inicializado com o valor 1, indicando que nenhum processo está na sua seção crítica associada ao semáforo

Page 29: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

Semáforo geral

• Pode ter qualquer valor positivo• Pode fornecer, por exemplo, um modo de registrar o

número de unidades do recurso disponíveis ou não disponíveis e pode ser utilizada para resolver problemas de consumidor/produtor

• Rotinas de semáforo existem para processos UNIX• Não existem para Pthreads, somente para extensão de

tempo real

Page 30: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

Monitor• Um conjunto de procedimentos que fornecem o único método de acessar

um recurso compartilhado• Os dados e operações que podem ser executadas sobre os dados são

encapsulados em uma estrutura• A leitura e escrita de dados só podem ser feitas utilizando-se

procedimentos do monitor, e somente um processo pode utilizar um procedimento de monitor em qualquer instante

• Um procedimento de monitor pode ser implementado utilizando-se semáforosmonitor_proc1(){ P(monitor_semaphore); . Corpo do monitor . V(monitor_semaphore); return;}

Page 31: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

Variáveis de condição

• Freqüentemente, uma seção crítica deve ser executada caso exista uma condição específica, por exemplo, o valor de uma variável chegou a um determinado valor

• Utilizando-se locks, a variável global tem que ser freqüentemente examinada dentro da seção crítica

• Consome tempo de CPU e podem não funcionar direito• Utilizam-se variáveis de condição

Page 32: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

Operações para variáveis de condição

• Três operações:– wait(cond_var) - espera que ocorra a condição– signal(cond_var) - sinaliza que a condição ocorreu– status(cond_var) - retorna o número de processos esperando pela condição

• A rotina wait() libera o semáforo ou lock e pode ser utilizada para permitir que outro processo altere a condição

• Quando o processo que chamou a rotina wait() é liberado para seguir a execução, o semáforo ou lock é trancado novamente

Page 33: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

Operações para variáveis de condição (exemplo)

• Considere um ou mais processos (ou threads) designados a executar uma determinada operação quando um contador x chegue a zero

• Outro processo ou thread é responsável por decrementar o contadoraction() contador(){ {. . lock(); lock(); while (x != 0) x--;wait(s); if (x == 0) signal (s);

unlock(); unlock(); take_action(); .} }

Page 34: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

Variáveis de condição em Pthreads• Associadas com uma variável mutex específica• Declarações e inicializações:

pthread_cond_t cond1;pthread_mutex_t mutex1;pthread_cond_init(&cond1, NULL);pthread_mutex_init(&mutex1, NULL);

• Utilização das rotinas de wait e signal:action() contador(){ {. . pthread_mutex_lock(mutex1); pthread_mutex_lock(&mutex1); while (c<> 0) c--; pthread_cond_wait(cond1, mutex1); if (c == 0) pthread_cond_signal(cond1);

pthread_mutex_unlock(&mutex1); pthread_mutex_unlock(&mutex1); take_action(); .} }

Page 35: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

Construções de linguagens para paralelismo

• Declaração de dados compartilhados– shared int x

• Construção par, para especificar execuções de instruções concorrentes– par {

S1; S2; . .

Sn; }

Page 36: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

Construções forall• Para iniciar execuções de múltiplos processos conjuntamente:

– forall (i = 0; i , n; i++) { S1; S2; . Sn;

}

• Geram-se n processos cada um executando as instruções que formam o corpo do loop for, S1, S2, ..., Sn e cada processo utiliza um valor diferente para i

• Exemplo para colocar o valor 0 em a[0], a[1], a[2], a[3], a[4] concorrentemente:forall (i = 0; i < 5; i++) a[i] = 0;

Page 37: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

Análise de dependência

• Identificação dos processos que podem ser executados em conjunto

• No código abaixo, a instrução do corpo do forall é independente de todas as outras e todas podem ser executadas de forma independente

• No entanto, pode a identificação de dependência pode não ser tão óbvia, necessitando-se de algoritmos de reconhecimento de dependência para compiladores paralelizadores

Page 38: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

Condições de Bernstein

• Conjunto de condições suficientes para determinar se dois processos podem ser executados simultaneamente

• Sejam Ii o conjunto de localizações de memória lidas por um processo Pi e Oj o conjunto de localizações alteradas pelo processo Pj

• Três condições suficientes para que dois processos P1 e P2 sejam executados concorrentemente– I1 O2 =

– I2 O1 =

– O1 O2 =

Page 39: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

Exemplo das condições de Bernstein

• Suponha as duas instruções em C:a = x + y;b = x + z;

• Temos:I1 = (x,y) O1 = (a)

I2 = (x,z) O1 = (b)

• Existem as três condições suficientes para que dois processos P1 e P2 sejam executados concorrentemente– I1 O2 =

– I2 O1 =

– O1 O2 =

Page 40: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

Dados compartilhados em sistemas com caches

• A memória cache é uma memória com velocidade de acesso alto para armazenar dados e código recentemente referenciados

• Protocolos de coerência da cache– política de atualização: a cópia dos dados de todas as caches é atualizada

quando uma delas é alterada– política de invalidação: quando uma das cópias é alterada, o mesmo dado

em outra cache é invalidado e essas cópias são atualizadas somente quando o processador associado a ela referenciar o dado

Page 41: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

Compartilhamento falso• Partes diferentes de um bloco de dados utilizadas por

processadores diferentes• Se um processador escrever em uma parte do bloco, a

cópia de todo bloco deve ser invalidada ou atualizada nas caches dos outros processadores

Memória principal

76543210

Bloco

Tag de endereço

Cache

Processador 1Bloco na cache

Cache

Processador 2

Page 42: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

Solução para compartilhamento falso

• O compilador deve alterar a distribuição dos dados armazenados na memória, colocando dados alterados por um único processador em blocos diferentes

Page 43: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

Exemplos de programas

• Somar os elementos de um array, a[1000]int sum, a[1000]

sum = 0;for (i = 0; i < 1000; i++)

sum = sum +a[i];

Page 44: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

Exemplo utilizando processos UNIX• O cálculo é dividido em duas partes, uma para a soma

dos elementos pares e outra para os ímparesProcesso 1 Processo 2sum1 = 0 sum2 = 0for (i = 0; i < 1000; i = i+2) for (i = 1; i < 1000; i= i+2)

sum1 = sum1 + a[i] sum2 = sum2 + a[i]

• Cada processo soma o seu resultado (sum1 ou sum2) a uma variável compartilhada sum que acumula o resultado e deve ser ter seu acesso protegido

• Estrutura de dados utilizadaArray a[]sum

addr

Page 45: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

#define array_size 1000extern char *shmat()void P(int *s);void V(int *s);int main(){int shmid, s, pid;cahr *shm;int *a, *addr, *sum;int partial_sum;int i;init init_sem_value =1 ;s = semget(IPC_PRIVATE, 1, (0600 | IPC_CREAT));if (s == -1) { perror(“semget”); exit(1);}if semctl(s, 0, SETVAL, init_sem_value) < 0) { perror(“semctl”); exit(1);}shmid = shmget(IPC_PRIVATE, (array_size*sizeof(int)+1), IPCCREAT|0600);if (shmid == -1) { perror(“shmget”); exit (1);}shm = shmat(shmid, NULL, 0);if (shm == (char*)-1) { perror(“shmat”); exit(1);}

Page 46: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

addr = (int *) shm;sum = addr;addr++;a = addr;*sum = 0;for (i = 0; i < array_size; i++) *(a+i) = i+1;pid = fork();if (pid ==0) { partial_sum=0; for (i=0; i<array_size; i=i+2) partial_sum+=*(a+i);else { partial_sum=0; for (i=1; i<array_size; i=i+2) partial_sum+=*(a+i);}P(&s);*sum+=partial_sum;V(&s);printf(“\n pid do processo = %d, soma parcial = %d \n”, pid, partial_sum);if (pid == 0) exit (0); else wait(0);printf(“A soma total é %d \n”, *sum);if (semctl(s, 0, IPC_RMID,1) == -1) { perror(“semctl”); exit(1);}if (shmctl(shmid, IPC_RMID, NULL) == -1) { perror(“shmctl”); exit(1);}}

Page 47: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

void P(int *s){ struct sembuf sembuffer, *sops; sops = &sembuffer; sops->sem_num=0; sops->sem_op=-1; sops->sem_flg=0; if (semop(*s, sops, 1) < 0) { perror (“semop”); exit (1); } return;}void V(int *s){ struct sembuf sembuffer, *sops; sops = &sembuffer; sops->sem_num=0; sops->sem_op=1; sops->sem_flg=0; if (semop(*s, sops, 1) < 0) { perror (“semop”); exit (1); } return;}

Page 48: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

Exemplo utilizando Pthreads

• São criadas n threads, cada uma obtém os números de uma lista, os soma e coloca o resultado em uma variável compartilhada denominada sum

• A variável compartilhada global_index é utilizada por cada thread para selecionar o próximo elemento de a

• Após a leitura do índice, ele é incrementado para preparar para a leitura do próximo elemento

• Estrutura de dados utilizada

Array a[]sum

addr

global_index

Page 49: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

#define array_size 1000;#define no_threads 10;

int a[array_size];int global_index = 0;int sum = 0;pthread_mutex_t mutex1;void *slave (void *ignored){ int local_index, partial_sum =0; do { pthread_mutex_lock&(mutex1); local_index = global_index; global_index++; pthread_mutex_unlock(&mutex1); if (local_index < array_size) partial_sum += *(a+local_index); } while (local_index < array_size); pthread_mutex_lock(mutex1); sum+=partial_sum; pthread_mutex_unlcok(&mutex1); return();}

Page 50: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

main() { int i; pthread_t thread[no_threads]; pthread_mutex_init(&mutex1, NULL); for (i = 0; i < array_size; i++) a[i] = i+1; for (i = 0; i < no_threads; i++) if (pthread_create(&thread[i], NULL, slave, NULL) != 0) { perror(“Pthread_create falhou”); exit(1); } for (i = 0; i < no_threads; i++) if (pthread_join(thread[i], NUL) != 0) { perror(“Pthread_join falhou”); exit(1); }printf(“A soma é %d \n”, sum)}

Page 51: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

Exemplo em Java

public class Adder{ public int [] array; private int sum = 0; private int index = 0; private int number_of_threads = 10; private int threads_quit;

public Adder () { threads_quit = 0; array = new int[1000]; initializeArray(); startThreads() }

public synchronized int getNextIndex() { if (index < 1000) return (index ++); else return (-1); }

public synchronized void addPartialSum(int partial_sum) { sum = sum + partoal_sum; if (++threads_quit == number_of_threads) System.out.println(“a soma dos números e’”+sum); }

Page 52: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

private void initializeArray() { int i; for (i = 0; i < 1000; i+=) array[i] = i; }

public void startThreads () { int i = 0; for (i = 0; i < 10; i++) { AdderThread at = new adderThread(this, i); at.start(); } } public static void main(String args[]) { Adder a = new Adder(); }}

Page 53: Memória Compartilhada. Programação com memória compartilhada Nos sistemas multiprocessadores com memória compartilhada, qualquer localização da memória

class AdderThread extends Thread{ int partial_sum = 0; Adder_parent; int number; public AdderThread (Adder parent, int number) { this.parent = parent; this.number = number; }

public void run () { int index = 0; while (index != -1) { partial_sum = partial_sum + parent.array[index]; index = parent.getNextIndex(); } parent.addPartialSum(partial_sum);) System.out.println(‘Soma parcial da thread “ + number + “é “+ partial_sum); }}