computação paralela -...
TRANSCRIPT
Computação Paralela
Especificação de Concorrência/Paralelismo
João Luís Ferreira SobralDepartamento do Informática
Universidade do Minho
Outubro 2006
Computação Paralela 2
Especificação de Concorrência/Paralelismo
� Actividades concorrentes/paralelas
� Fio de execução versus processo
� Paralelismo lógico versus paralelismo físico
� Preempção de fios de execução
� Escalonamento dos fios e prioridades
� Vantagens da utilização de concorrência
� Programas que requerem a execução de várias tarefas (reactivos)
� Existem objectos do mundo real que são activos
� Melhora a disponibilidade de serviços
� Possibilita as mensagens/invocações de métodos assíncronas
� Tira partido do paralelismo quando existem vários CPU/core
� Concorrência requerida (em Java várias classes executam de forma concorrente, ex. Swing, applet, beans)
Computação Paralela 3
Especificação de Concorrência/Paralelismo
� Problemas relacionados com a concorrência
� Segurança (safety) – inconsistências na execução de programas
� Vivacidade (liveness) – impasses na execução de programas
� Introduz não determinismo na execução dos programas
� Em sistemas OO existem menos actividades assíncronas que objectos
� Pouco útil na execução local de métodos, num modelo chamada/resposta
� Introduz uma sobrecarga devido à criação, escalonamento e sincronização dos fios de execução
� Concorrência em aplicações tradicionais
� Modelos de fork/join, cobegin/coend, e parfor.� A sincronização é efectua com semáforos, barreiras ou monitores.
� Processos activos (CSP)� Efectuam processamento através de um corpo activo, interactuando através da
passagem de mensagens, síncrona com bloqueio, síncrona sem bloqueio ou assíncrona.
Computação Paralela 4
Especificação de Concorrência/Paralelismo
� Concorrência em aplicações orientadas ao objecto� Invocações síncronas (modelos tradicionais)
� o cliente fica bloqueado enquanto o método é executado pelo servidor, mesmo que não exista um valor de retorno.
� Invocações assíncronas sem valor de retorno (one way)� Quando o método invocado não retorna um valor pode ser efectuada uma invocação
assíncrona, podendo o cliente prosseguir a execução em simultâneo com a execução do método no servidor.
� Invocações assíncronas com valor de retorno � Quando existe um valor de retorno as invocações também podem ser assíncronas,
existindo, no entanto, três alternativas para o retorno do resultado da operação:� Síncrona diferida - O cliente efectua uma segunda invocação ao servidor para obter o resultado
tempo
Cliente Servidor
tarefa()
resultado()
Computação Paralela 5
Especificação de Concorrência/Paralelismo
� Concorrência em aplicações orientadas ao objecto (cont.)
� Invocações assíncronas com valor de retorno (cont)
� Com chamada de retorno (callback)– O servidor efectua uma invocação de um método pré-definido do cliente, quando a execução terminou
� Com futuros – A invocação é delegada a outro objecto que armazena o resultado da operação.
Cliente Servidor
tarefa()
resultado()
Cliente Futuro
tarefa()
resultado()
Servidor
tarefa()
Computação Paralela 6
Programação Concorrente em Java
� JAVA é das poucas linguagens com suporte à programação concorrente
� Classe java.lang.Thread:� Thread() ou Thread(Runnable r); // construtor da classe
� start(); // cria um fio de execução e invoca r.run()
� join(); // espera pelo fim da execução do fio
� sleep(int ms); // suspende o fio de execução
� setPriority(int Priority); // altera a prioridade
� Interface Runnable� Deve ser implementado por todas as classes pretendam ser directamente
executadas por um fio de execução.
� O método run() contém o código a executar pelo fio de execução.
interface Runnable {
public void run();
}
Computação Paralela 7
Programação Concorrente em Java
• Exemplo
� Dois fios de execução que incrementam cada um o seu contador
public class Cont extends Thread { // implícito: implements Runnable
public Cont() { }
public void run() {
for (int i=0; i<100; i++) System.out.println(“ i= “ + i);
}
}
� Execução sequencial:...
new Cont().run();
new Cont().run();
... // join
� Execução concorrente:...new Cont().start();new Cont().start();// ou new Cont().run();
... // join, para esperar pelo fim da execução
Computação Paralela 8
Programação Concorrente em Java
• Exemplo (formulação alternativa)
� Dois fios de execução que incrementam cada um o seu contador
public class Cont implements Runnable {
public Cont() { }
public void run() {
for (int i=0; i<100; i++) System.out.println(“ i= “ + i);
}
}
� Execução sequencial:...
new Cont().run();
new Cont().run();
... // join
� Execução concorrente:...Thread t1 = new Thread(new Cont()).start();Thread t2 = new Thread(new Cont()).start();// ou new Cont().run();
... // t1.join, para esperar pelo fim da execução
Computação Paralela 9
Programação Concorrente (em Java)
� Segurança – nada de mau deve acontecer num programa
� Vivacidade – algo de bom deve acontecer num programa
� Exemplo de falta de segurança:
� execução do método inc() por dois fios em simultâneo pode originar um valor incoerente da variável ct
public class Cont {
protected long ct;
public Cont() { ct=0; }
public void inc() { ct = ct + 1; }
}
Thread 1
ct = ct +1
ct?
Load $R1,ct
Inc $R1
Store $R1,ct
Load $R2,ct
Inc $R2
Store $R2,ct
Thread 2
ct = ct +1
Computação Paralela 10
Programação Concorrente (em Java)
� Especificação de sincronização (aumenta a segurança)
� Blocos de código e métodos synchronized (mutex)
synchronized metodo() { ... } // metodo tem o acesso exclusivo ao objectosynchronized(umObj) { ... } // obtém o acesso exclusivo a umObj
� Modelo de memória de Java
� Um fio de execução pode manter cópias locais de valores. Os blocos synchronizedgarantem que todos os fios “veem” valores consistentes
� Com monitores (implementados pela classe Object)
wait() – espera pelo acesso ao monitorwait(int timeout) – wait, com temporizaçãonotify() – acorda um fio à espera de acessonotifyAll() – acorda todos os fios à espera
Computação Paralela 11
Programação Concorrente (em Java)
� Exemplo de falta de vivacidade (deadlock):
� execução de método inc() por dois fios em simultâneo em objectos com referências cruzadas:
Obj2/Thread2:...
synchronized void inc() {obj1.inc()
}
Obj1/Thread1:...
synchronized void inc() {obj2.inc()
}
Computação Paralela 12
Programação Concorrente (em Java)
� Padrões para melhorar a segurança
� objectos imutáveis ou sem estado (exemplo classe String)public int[] sort(int[] arr) {
int[] copy = arr.clone(); // cópia local
… // sort
return(copy);
}
� Objectos contidos em outros objectos
� Padrões para melhorar a vivacidade� Os métodos que apenas lêem o estado do objecto geralmente não
necessitam de ser sincronizados (excepto para double e long)
� Não é necessário sincronizar as variáveis que são escritas apenas uma vez:
void setEnd() { end = True; }
Computação Paralela 13
Programação Concorrente (em Java)
� Padrões para melhorar a vivacidade (cont.)
� Utilizar, sempre que possível, a sincronização separada, para acesso a cada parte do estado (ou dividir o estado em dois objectos)
class doisPontos {Ponto p1, p2;public void movexp1(int x) {
synchronized (p1) { p1.movex(x); }}public void movexp2(int x) {
synchronized (p2) { p2.movex(x); }}
}
� Os recursos devem ser acedidos sempre pela mesma ordem para minimizar os impasses.
public void update() {synchronized(obj1) {
synchronized(obj2) {... // do update
}}
}
Computação Paralela 14
Acções Dependentes do Estado dos Objectos
� Que acção tomar quando um objecto não pode satisfazer um pedido?
� Ignorar o pedido
� Retornar uma indicação de falha (excepção?)
� Suspender o cliente até que a condição se verifique
� Tomar uma acção provisória
� Prosseguir por forma a poder repor o estado se algo correr mal
� Repetir a acção até ser possível executá-la
� Estratégias pessimistas versus estratégias optimistas
� Representação lógica do estado versus representação física do estado
� Estado lógico: normalmente definido por predicados: expressões Booleanas em função do estado (ex. buffer cheio, meio e vazio)
� O estado lógico pode ser representado explicitamente em variáveis
Computação Paralela 15
Acções Dependentes do Estado dos Objectos
� Suspensão do cliente através de guardas
� Métodos wait(), notify() e notifyAll() da classe Object
� Exemplopublic class GuardedClass {
protected boolean cond=false;
public synchronized void guardedAction() {
while(!cond) {
try { wait(); }catch (InterruptedException e) {}
}
}
public synchronized void setCond() {
cond=true;
notifyAll();
}
}
� Problemas com monitores encadeados: wait() apenas liberta o fecho desse monitor e não do monitor do objecto exterior
Computação Paralela 16
Invocações assíncronas de métodos
� Sem valor de retorno � Implementada através de um padrão comando, onde o comando é executado em
paralelo com o cliente. Os parâmetros do comando são passados no seu construtor.
� Exemplo: escrita de dados em ficheiro em background – activada pelo cliente:
public class FileWriter extends Thread {
private String nm;
private byte[] d;
public FileWriter(String n, byte data[]) {
nm = n;
d = data;
}
public void run() {
writeBytes(nm,d);
}
}
// código do cliente
(new FileWriter(“Pic”,rawPicture)).start();
Computação Paralela 17
Invocações assíncronas de métodos
� Síncrona diferida
� Utilizando o Método Thread.join()r = new Service().start();
.. // doWork();
r.join();
r.getResult();
� Futuros
� O futuro irá conter o resultado da operação e bloqueia o cliente caso seja requerido o valor antes de estar disponível.
class Future extends Thread { private Task tk=null;
public Future(Task tsk) {
tk = tsk;
start();
}
public Task getResult() {
join();
return(tk);
}
public void run() { tk = doTask(); } // realiza a tarefa
}
tempo
Cliente Service
start()
getResult()
Cliente Futuro
Future(t)
getResult()
Servidor
doTask()
Computação Paralela 18
Invocações assíncronas de métodos
� Chamadas de retorno
public interface Client {
public void opOK(Task);
}
class OPCallBack extends Thread {
private Client cl=null;
private Task tk=null;
public OPCallBack(Task tsk, Client clk) {
tk = tsk;
cl = clk
start();
}
public run() {
tk = doTask(tk);
cl.opOK(tk); // callback
}
}
Cliente Servidor
OPCallBack()
opOK()
Computação Paralela 19
Invocações assíncronas de métodos
� Suportadas em .Net (C#) através de delegatespublic class BaseObject {
[OneWay]
public void writeBytes(string, int);
}
// delegate para uma função void xxx(string,int)
delegate void writeBytesDelegate(string, int);
static void Main(string[] args) {
ob = new BaseObject();
// cria um delegate para ab.writeBytes
writeBytesDelegate wbd = new writeBytesDelegate(ob.writeBytes);
// inicia a invocação
IAsyncResul as = wbd.BeginInvoke(“Pic”,rawPic,null,null);
// EndInvoke() retorna imediatamentewbd.EndInvoke(as);
}
Computação Paralela 20
Biblioteca de Concorrência (investigação)
� Implementada com anotações de Java 5 e AspectJ
Chamadas OneWaypublic class BaseObject {
@OneWaypublic void writeBytes(string, int) { … }
}
Métodos Synchronized@Synchronized public void writeBytes(string, int) { … }
Métodos Readers e Writer@Writerpublic void writeBytes(string, int);@Readerpublic int getLen();
Valores ThreadLocalpublic class BaseObject {
@ThreadLocalint value;…
}
Outros: Futuros, Objecto Activo, Barreira, Scheduled, Waiting Guards
Computação Paralela 21
Extensões de Concorrência em Java 5
� Executores (Thread Pool)
Void Executor.execute(Runnable task) Thread Pool //
Future<T> Executor.submit(Callable<T> task)
� Concurrent implementations of Map, List, and Queue
� high-performance lock implementation in java.util.concurrent.locks
� General purpose synchronization classes, including semaphores, mutexes, barriers, latches, and exchangers
� Atomic variable implementations in java.util.concurrent.atomic
Computação Paralela 22
Especificação de Concorrência/Paralelismo
• Exercícios
� Codificar e executar o programa exemplo dos dois contadores em paralelo.
� Alterar o programa anterior para que o “output” dos dois contadores não apareça misturado (embora execute de forma concorrente)
� Desenvolver um programa que implemente um relógio, com uma precisão de segundos e que execute em simultâneo com o resto do programa. Utilize o seguinte método para suspender um fio de execução durante um tempo predefinido:
void sleep(miliseconds) throws InterruptedException;