computação paralela e distribuída - ufflucia/so/aula1so.pdf · – comunicação com o mundo...
TRANSCRIPT
Computação Paralela e Distribuída
Profa. Cristina Boeres e Lúcia Drummond
Rio de Janeiro - 26 de fevereiro de 2007
Em convênio com: IC – Instituto de ComputaçãoUFF – Universidade Federal Fluminense
Introdução e Conceitos Básicos
• Por que computação paralela e distribuída• Computação de Alto Desempenho• Arquitetura de computadores• Ambientes de programação paralela• Modelos de programação paralela
Por que computação paralela e distribuída?
Sistemas de computadores seqüenciais cada vez mais velozes– velocidade de processador
– memória
– comunicação com o mundo externo
Quanto mais se tem, mais se quer......– Demanda computacional está aumentando cada vez mais: visualização, base de
dados distribuída, simulações, etc.
limites em processamento seqüencial – velocidade da luz, termodinâmica
Por que computação paralela e distribuída?
que tal utilizar vários processadores?
dificuldades encontradas
– mas como?
– paralelizar uma solução?
Ex ist e m v á r io s d e sa f io s e m C o m p u t a ç ã o P a ra le la e D ist r ib u íd a
Computação de Alto Desempenho
Os grandes desafios (Levin 1989):– química quântica, mecânica estatística e física relativista;
– cosmologia e astrofísica;
– dinâmica e turbulência computacional dos fluídos;
– projeto de materiais e supercondutividade;
– biologia, farmacologia, seqüência de genomas, engenharia genética, dobramento de proteínas, atividade enzimática e modelagem de células;
– medicina, modelagem de órgãos e ossos humanos;
– clima global e modelagem do ambiente
Computação de Alto Desempenho
utilizando modelagem, simulação e análise computacional
CAD/CAM
Aerospace
Digital Biology Military Applications
cortesia de RajKumar Buyya
Life Sciences Internet & Ecommerce
Definindo melhor alguns conceitos
• Concorrência
termo mais geral, um programa pode ser constituído por mais de um thread/processo concorrendo por recursos
• Paralelismo
uma aplicação é executada por um conjunto de processadores em um ambiente único (dedicados)
• Computação distribuída
aplicações sendo executadas em plataformas distribuídas
Definindo melhor alguns conceitos
Qualquer que seja o conceito, o que queremos?
estabelecer a solução do problema
lidar com recursos independentes
aumentar desempenho e capacidade de memória
fazer com que usuários e computadores trabalhem em espírito de colaboração
O que paralelizar?
Concorrência pode estar em diferentes níveis de sistemas computacionais atuais– hardware– Sistema Operacional– Aplicação
As principais questões que são focadas são– Desempenho– Corretude– possibilidade de explorar o paralelismo
Por que paralelizar?
Aplicação Paralela
– várias tarefas
– vários processadores• redução no tempo total de execução
Modelos de Programação Paralela
Criação e gerenciamento de processos– estático ou dinâmico
Comunicação– memória compartilhada
• visão de um único espaço de endereçamento global
– memória distribuída • troca explícita de mensagens
Modelos de Programação Paralela
Expressão de Paralelismo: Paradigmas– SPMD– MPMD
Metas– aumento no desempenho – maior eficiência
Objetivos
Visão geral– arquitetura de computadores– ambientes de programação paralela– modelos de programação paralela
Motivar ⇒ Sistemas de Alto Desempenho
Arquitetura de Computadores
Classificação de Computadores
– Computadores Convencionais
– Memória Centralizada
– Memória Distribuída
Arquitetura de Computadores
Sistema Paralelo
– vários processadores
– vários módulos de memória
– comunicação: estruturas de interconexão
Plataforma de Execução Paralela
Conectividade ⇒ rede de interconexão
Heterogeneidade ⇒ hardware e software distintos
Compartilhamento ⇒ utilização de recursos
Imagem do sistema ⇒ como usuário o percebe
Escalabilidade ⇒ + nós > desempenho/eficiência
Classificação de Sistemas Paralelos
Proposta por Flynn– quantidade de instruções e dados processados em um determinado momento
SISD (single instruction single data)– Um contador de programa– Computadores seqüenciais
SIMD (single instruction multiple data)– Um contador de programa, uma instrução executada por diversos processadores
sobre diferentes dados– Computadores
Classificação de Sistemas Paralelos
Proposta por Flynn
MISD (multiple instructions single data)– Não aplicável
MIMD (multiple instructions multiple data)– Vários contadores de programa– Diferentes dados– Os vários computadores paralelos e distribuídos atuais
Plataforma de Execução Paralela
Diferentes plataformas do MIMD de acordo com os seguintes critérios
– espaço de endereçamento – mecanismo de comunicação
Podem ser agrupadas em quatro gruposSMPs (Symmetric MultiProcessors)
MPPs (Massively Parallel Processors)
Cluster ou NOWs (Network Of Worstations)
Grades Computacionais
SMPs
SMPs ou Multiprocessadores
– único espaço de endereçamento lógico• mecanismo de hardware (memória centralizada)
– comunicação ⇒ espaço de endereçamento compartilhado• operações de loads e stores
– Acesso a memória é realizada através de leitura (load) e escrita (store), caracterizando desta forma, a comunicação entre processadores
SMPs
Sistema homogêneoCompartilhamento – Compartilhamento total da mesma memória
Uma única cópia do Sistema OperacionalImagem única do sistema Excelente conectividade – fortemente acoplados
Não escalável Exemplos: – Sun HPC 10000 (StarFire), SGI Altix, SGI Origin, IBM pSeries, Compac
AlphaServer
SMPs
Multiprocessadores
Memória
CPU
CPU
...CPU
MPPs (Multicomputadores)
Diferem quanto a implementação físicaMódulos ou elementos de processamento contendo:– múltiplos processadores com memória privativa– computadores completos
Espaço de endereçamento – não compartilhado - memória distribuída
Comunicação– troca de mensagens
Rede de interconexão– diferentes topologias
Fracamente acoplados Escaláveis
MPPs
Sistema homogêneo ou heterogêneo
Interconexão: redes dedicadas e rápidas
Cada nó executa sua própria cópia do Sistema Operacional
Imagem única do sistema
– visibilidade dos mesmos sistemas de arquivo
Um escalonador de tarefas
– partições diferentes para aplicações diferentes
MPPs
Partições dedicadas a cada aplicação
Aplicações não compartilham recursos
– Pode ocorrer que uma aplicação permaneça em estado de espera
Exemplos:
– Cray T3E, IBM SP2s, clusters montados pelo próprio usuário, com propósito de ser um MPP
MPPs
Multicomputadores
...CPU CPU CPU
Mem. Mem. Mem.
requisições
Escalonador
Cluster de computadores ou NOWs
Conjunto de estações de trabalho ou PCs
Interconexão: redes locais
Nós: elementos de processamento = processador + memória
Diferenças em relação a MPPs:– não existe um escalonador centralizado– redes de interconexão tendem a ser mais lentas
Cluster de computadores ou NOWs
Resultado das diferenças:– Cada nó tem seu próprio escalonador local– Compartilhamento de recursos ⇒ sem partição dedicada a uma aplicação – Aplicação ⇒ deve considerar impacto no desempenho ⇒ não tem o sistema dedicado
– Possibilidade de compor um sistema de alto desempenho e um baixo custo (principalmente quando comparados com MPPs).
Cluster ou NOWs
...CPU CPU CPU
Mem. Mem. Mem.
requisições requisições requisições
Grades Computacionais (Computational Grids)
Utilização de computadores – independentes– geograficamente distantes
Diferenças: clusters X grades
– heterogeneidade de recursos– alta dispersão geográfica (escala mundial)– compartilhamento – múltiplos domínios administrativos– controle totalmente distribuído
Grades Computacionais
Componentes – PCs, SMPs, MPPs, clusters– controlados por diferentes entidades ⇒ diversos domínios administrativos
Não têm uma imagem única do sistema a princípio– Vários projetos tem proposto o desenvolvimento de middlewares de
gerenciamento ⇒ camada entre a infra-estrutura e as aplicações a serem executadas na grade computacional
Aplicação deve estar preparada para: – Dinamismo – Variedade de plataformas– Tolerar falhas
Grades Computacionais
Sistema não dedicado e diferentes plataformas– Usuários da grades devem obter autorização e certificação para acesso aos
recursos disponíveis na grade computacional
Falhas nos recursos tanto de processamento como comunicação são mais freqüentes que as outras plataformas paralelas– Mecanismos de tolerância a falhas devem tornar essas flutuações do ambiente
transparente ao usuário
Para utilização eficiente da grade computacional– Gerenciamento da execução da aplicação através de políticas de escalonamento
da aplicação ou balanceamento de carga– Escalonamento durante a execução da aplicação se faz necessário devido as
variações de carga dos recursos da grade
Grades Computacionais
Escalonador de Aplicação
Escalonador de Aplicação
Escalonador de Recursos
Escalonador de Recursos
Escalonador de Recursos
usuário usuário usuário
MPP SMP
SMP
Cluster
Grades Computacionais
Cluster
Workstation
Internet
MPP
MPPSMP
SMP
Computador convencional
Servidor
Workstation
Resumo
Plataformas de Execução Paralela
Características SMPs MPPs NOWs GridsConectividade excelente muito boa boa média/ruimHeterogeneidade nula baixa média altaCompartilhamento não não sim simImagem do Sistema única comum comum múltiplaEscalabilidade 10 1.000 1.000 100.000
Top500 Supercomputer (atualizada)
54204.843480200610424Jaguar - Cray XT3, 2.4 GHzCray Inc.
Oak Ridge National LaboratoryUnited States
82124.847380200611088STSUBAME Grid Cluster - Sun Fire x4600 Cluster, Opteron 2.4/2.6 GHz and ClearSpeed Accelerator, InfinibandNEC/Sun
GSIC Center, Tokyo Institute of TechnologyJapan
6096051870200410160Columbia - SGI Altix 1.5 GHz, Voltaire InfinibandSGI
NASA/Ames Research Center/NASUnited States
63795.25284020069968Tera-10 - NovaScale 5160, Itanium2 1.6 GHz, QuadricsBull SA
Commissariat a l'Energie Atomique (CEA)France
64972.85300020069024Thunderbird - PowerEdge 1850, 3.6 GHz, InfinibandDell
NNSA/Sandia National Laboratories United States
9420862630200610240MareNostrum - BladeCenter JS21 Cluster, PPC 970, 2.3 GHz, MyrinetIBM
Barcelona Supercomputing CenterSpain
9278175760200612208ASC Purple - eServer pSeries p5 575 1.9 GHzIBM
DOE/NNSA/LLNLUnited States
11468891290200540960BGW - eServer Blue Gene SolutionIBM
IBM Thomas J. Watson Research CenterUnited States
127411101400200626544Red Storm - Sandia/ Cray Red Storm, Opteron 2.4 GHz dualCray Inc.
NNSA/Sandia National LaboratoriesUnited States
3670002806002005131072BlueGene/L - eServer Blue Gene SolutionIBM
DOE/NNSA/LLNLUnited States
Rpeak Rmax YearProcsComputerSite
Rmax Maximal LINPACK performance achieved Rpeak Theoretical peak performance GFlpos
1
2
3
4
5
6
7
8
9
10
Top500 Supercomputer (Máquinas Brasileiras)
6169299220041008bw7 – Cluster platform 3000 DL140G3 Xeon 3.06 GHz GigEthernet Hewlett-Packard
PETROBRASBrazil
44803182.382006448BladeCenter JS21 Cluster, PPC970, 2.5 GHz, MyrinetIBM
University of San PauloBrazil
7956373920041300Rbwr1 Cluster platform 3000 DL140G3 Xeon 3.06 GHz GigEthernetHewlett-Packard
PETROBRASBrazil
6266.88375520041024xSeries Cluster Xeon 3.06 GHz – Gig-EIBM
Petroleum Company (C)Brazil
Rpeak Rmax YearProcsComputerSite
Rmax Maximal LINPACK performance achieved Rpeak Theoretical peak performance GFlpos
273
275
363
418
Computação em Cluster
• Um conjunto de computadores (PCs)
• não necessariamente iguais heterogeneidade
• Filosofia de imagem única
• Conectadas por uma rede local
Para atingir tais objetivos, necessidade de uma camada de software ou middleware
Computação em Grid
• Computação em Cluster foi estendido para computação ao longo dos sites distribuídos geograficamente conectados por redes metropolitanas
Grid Computing
• Heterogêneos
• Compartilhados
• Aspectos que devem ser tratados
• Segurança
• Falhas de recursos
• Gerenciamento da execução de várias aplicações
Computação em Grid
O sonho do cientista (The Grid Vision)
Computação em Grid adota tanto o nome quanto o conceito semelhantes aqueles da Rede de Potência Elétrica para capturar a noção ou a visão de:
− Oferecer desempenho computacional eficientemente; − De acordo com a demanda; − A um custo razoável;− Para qualquer um que precisar.
O sucesso da computação em grid depende da comunidade de pesquisadores – A possibilidade de construir tal ambiente (hardware e software)– Necessidade de atingir seus objetivos.
Computação em Grid
SETI@home: Search for Extraterrestrial Intelligence at Home
Computação em Grid
• Grid middlewares: tem como objetivo facilitar a utilização de um ambiente grid
• APIs para isolar usuários ou programas da complexidade deste ambiente
• Gerenciar esses sistemas automaticamente e eficientemente para executar aplicações no ambiente grid (grid-enabled applications)
E as aplicações não habilitadas a execução em ambiente grids?
Computação em Grid
Como o usuário (dono da aplicação) escolhe? Vários middlewares existem, qual o mais apropriado? Vários estão ainda sendo desenvolvidosNão há a garantia de suportePouca comparação entre os middlewares, por exemplo, desempenho, grau de intrusão. É difícil encontrar grids com o mesmo tipo de software instalado
Algoritmos Paralelos
Definindo melhor alguns conceitos
Processamento Paralelo: processamento de informação concorrente que pertencem a um ou mais processos que resolvem um único problema.
Processamento Distribuído: processamento de informações em um sistema cujos recursos estão sendo compartilhados por vários programas
Computador Paralelo: computador de múltiplos processadores capaz de realizar processamento paralelo
Supercomputador: computador de propósito geral capaz de resolver problemas em alta velocidade, comparando com outras máquinas da mesma época.
A vazão de um dispositivo é o número de resultados produzidos por unidade de tempo. (throughtput)
Speedup (aceleração): razão entre o tempo de execução necessário para o algoritmo sequencial mais eficiente e o tempo necessário para se realizar a mesma computação numa máquina paralela
Existem diversas definições de speedup:– speedup absoluto(n)= T(melhor alg. seq. )/ T( prog // c/ n proc.)– speedup aproximado(n)= T(prog.// c/1 proc.)/T( prog // c/ n proc.)– speedup relativo (n)= T(prog. // c/(n-1) proc.)/T(prog.// c/ n proc.)
Terminologia
Computação concorrente
Duas formas de se explorar a concorrência em computação em computação– Paralelismo de controle e de dados
tempo t
7 + 3 string ==“casa”? 32 * 14
7 + 3 10 + 200 33 + 329
Paralelismo de Controle
alcançado aplicando-se operações diferentes a diferentes dados simultaneamente.– fluxo de dados entre processos pode ser arbitrariamente complexo
Exemplo:
– Pipelining: cada estágio trabalha em velocidade plena sobre uma parte particular da computação. A saída de um estágio é a entrada do estágio seguinte
Paralelismo de Controle
tempo
info 1
E4E1 E2 E3
info 2 info 1
info 3 info 1info 2
info 3info 4 info 1info 2
Paralelismo de Dados
uso de vários processadores para executar a mesma operação ao mesmo tempo sobre elementos distintos de dados
Um aumento de k vezes no número de unidades funcionais levaria a um aumento de k vezes a vazão do sistema
7 + 3 10 + 200 33 + 329
Aplicações
Aplicações ou programas podem ser executados mais rapidamente, considerando duas formas de paralelismo
– tratar o programa seqüencial como uma série de tarefas– cada tarefa = uma instrução ou blocos de instruções
OU
– especificar um programa paralelo, que resolve o problema através da especificação de tarefas ou processos concorrentes
Exploração de paralelismo
Particionamento– identificar em um programa, as tarefas que possam ser executadas em
paralelo (simultaneamente em mais de um processador)
– caso extremo: cada linha do programa correspondendo a uma tarefa
um bom desempenho só é alcançado se um número máximo de comandos são executados simultaneamente
É preciso considerar dependências de dados
problema: se quase todos os comandos são dependentes
Exemplo: programa seqüencial paralelismo de instruções
program nothing(){input (A,B,C);if A>B then {
C=A-B; output (C);
} else { C = B-A;
output (A,B,C) }A=0; B=1;for i=1 to 3 { input(C); A=A+C; B=B*C;
}output (A,B,C);
}
Exemplo
Tarefa T1input (A,B,C);if A>B then{
C=A-B; output (C); }else{
C = B-A;output (A,B,C)
}
Tarefa T3B=1;
Tarefa T4for i=1 to 3 { input(C); A=A+C; B=B*C; } output (A,B,C)
Tarefa T2A = 0;
Exemplo
T1T3T2
T416
1 1
4
Exemplo: Soma n números
P r o b l e m a : s o m a r n n úm e r o s q u a i s q u e r
Programa sequencial:
read (n, vetor);soma = 0;for (i = 0; i < n; i++) soma = soma + vetor[i];
Como paralelizar o problema?
Terminologias
• Um algoritmo é escalável se o nível de paralelismo aumenta no mínimo linearmente com o tamanho do problema.
• Uma arquitetura é dita escalável se continua a alcançar o mesmo desempenho por processador, mesmo para problemas maiores, com o aumento de processadores.
– Se aplicável, o usuário pode resolver problemas maiores no mesmo intervalo de tempo através da compra de uma máquina paralela com maiores dimensões
Algoritmos paralelos-de-dados são mais escaláveis do que algoritmos com paralelismo de controle– o nível de paralelismo de controle é geralmente constante, independente do
tamanho do problema, enquanto o nível do paralelismo de dados é uma função crescente do tamanho do problema
Convergência entre Computação Paralela & Distribuída
• Existia uma grande dificuldade de manter máquinas paralelas a frente aos projetos de chip-único– Computadores paralelos se tornaram mais difíceis de se construir e se usar do
que se esperava.
Motivo desta dificuldade: software
⇓Paralelizar e gerenciar algoritmos paralelos não é uma tarefa fácil
Programação Paralela
• No início dos anos 90: processamento paralelo foi retomado. • O problema de programação paralela seria bem mais difícil de atacar do
que se imaginava.• Pesquisa na área de programação em paralelo tem sido um tópico
importante.
Mas ao mesmo tempo....
Internet
• Enquanto muitos estudavam processamento paralelo associado processadores ligados internamente em uma máquina, um outro grupo se concentrava em paralelismo externo através de redes de computadores
• a internet possibilitou a especificação de um tipo de paralelismo através de uma conexões entre processadores
Sistema Paralelo e Distribuído
processamento distribuído renasceu como uma forma de paralelismo mais lenta
computação distribuída e paralela são dois extremos num espectro de computação concorrente
Sistema paralelo e distribuído é uma coleção de componentes de hardware e software que otimizam o desempenho por problema, vazão de múltiplos problemas e confiabilidade, ou uma combinação destes
Sistema Paralelo e Distribuído
• Problemas: a aglomeração de muitos processadores através de canais de comunicação: o desempenho pode cair muito.
• Para alcançar o máximo dos sistemas paralelos e distribuídos: projetistas e desenvolvedores de software precisam compreender a interação entre hardware e software
Sistema Paralelo e Distribuído
computação distribuída é mais abrangente e universal do que computação paralela
Paralelismo - forma restrita de computação distribuída
sistema paralelo : voltado à solução de um problema único no menor tempo possível (otimização)
Computação distribuída é mais geral e reúne outras formas de otimização...
Paralelismo é interessante ?
Na natureza, os eventos ocorrem em paralelo
programação seqüencial ordena eventos paralelosessa ordenação dificulta a trabalho do compiladormas, maior desempenho com o uso de paralelismo– no entanto, não é trivial atingir alto desempenho em
computadores paralelos
aplicações como os Grandes Desafios são limitados computacionalmente
Investindo em paralelismo
Dificuldades encontradas
pensar em paralelo é difícil
conhecimento em paralelismo é recente
pouco conhecimento sobre representações abstratas de computações paralelas
Investindo em paralelismo
Em relação a características da máquina
Relação entre a velocidade do processador – Elementos de processamento heterogêneos
Desempenho da interconexão de comunicação– Latência de comunicação– Congestionamento– Topologia da rede
Hierarquia de memória
Tendência hoje:
– memória compartilhada distribuída
– superprocessadores distribuídos
Portabilidade
transferência de programas seqüenciais entre diferentes máquinas não é tão custoso
mesmo não pode ser afirmado para sistemas paralelos
pode significar um re-projeto e re-implementação do software
qual é a melhor arquitetura paralela?
Quais características importantes das aplicações ?
Processos/tarefas
existe comunicação entre essas tarefas– pode ser vantajoso executar várias tarefas em um só processador– a tarefa perde o processador quando precisa de um dado a ser
comunicado
paralelismo virtual X real– Por exemplo: existem 100 processadores disponíveis– cada processador pode estar executando vários processos: virtualmente
existem um total de 300 processos
Quais características importantes das aplicações ?
difícil definir processos/tarefas totalmente independentes – comunicação entre processos pode gerar um tráfego de mensagens
pesado
comunicação entre processos:– troca de mensagens: considera a topologia da rede de interconexão– memória compartilhada: utilização de semáforos para proteção de
regiões críticas– direct remote-memory access: existência de processadores dedicados à
comunicação
Modelos de Computação Paralela
interface - uma máquina abstrata
a abstração se faz necessária para facilitar a programação sem se preocupar com detalhes da máquina– um modelo deve ser estável para ser um padrão
um modelo contém os aspectos importantes tanto para os projetistas de software quanto para os da máquina
as decisões de implementações são feitas para cada máquina destino, não havendo necessidade de se refazer programas
Aspectos Explorados pelo Modelo
Independência da arquitetura
Fácil entendimento
Aspectos Explorados pelo Modelo
Facilidade de programação
O programador não deve se preocupar com detalhes da máquina destino– modelos abstratos: programação mais fácil
O compilador é que deve traduzir para uma estrutura do programa em execução considerando o sistema computacional destino– tarefa do compilador: mais árdua
nível de abstração
nível de máquina
Aspectos Explorados pelo Modelo
O modelo deve ser capaz de oferecer facilidades tais que seja fácil:
Decompor o programa em tarefas paralelas
Mapear as tarefas nos processadores físicos
– custo de comunicação
– heterogeneidade dos processadores
Sincronização entre tarefas: é preciso ter conhecimento do estado global da estrutura de execução do programa (quando é necessário sincronizar?)
Abstraindo para Programar
Maior facilidade de programação: o esforço intelectual é reduzido quando nos concentrarmos em "uma coisa de cada vez”
duas dimensões:
– dimensão espacial
– dimensão temporal
Dimensão Espacial
A cada momento, conjuntos de tarefas independentes são implementadas– cada tarefa ou processador não sabe o que acontecerá "a seguir"
detalhamento de informações globais levam a uma programação difícil
Dimensão Temporal
programas são composições de ações seqüenciais que preenchem o sistema computacional como um todo:pode-se definir com maior conhecimento o que vai acontecer a seguir
Níveis de Paralelismo
Dependendo do nível considerado, a exploração do paralelismo é diferente
nível de aplicações ou fases de aplicações a nível de tarefas a nível de instruções - a execução da instrução necessita da busca, análise e execução propriamente dita dentro dos circuitos aritméticos
Algoritmos
Quando queremos resolver um problema computacionalmente, temos que analisar a complexidade deste. No domínio seqüencial, se procura definir um algoritmo que resolva o problema em tempo mínimo.
Mas quando se tratando de algoritmos paralelos, mais um parâmetro– número de processadores– operações independentes devem ser executadas em paralelo.
qual o tamanho dos processos? noção de granulosidade (granularity) – a razão entre o tempo de computação necessário para executar
uma tarefa e a sobrecarga de comunicação durante essa computação.
Modelos de Computação
Modelo de Computação Sequencial: von Neumann plataforma base para que usuários e projetistas – complexidade de tempo do pior caso: tempo máximo que o
algoritmo pode levar para executar qualquer entrada com nelementos
– complexidade de tempo esperado: complexidade média – critério de custo uniforme: qualquer instrução RAM leva uma
unidade de tempo para ser executada e também o acesso a registradores
Modelo de Computação ParalelaO desempenho do programa paralelo depende de certos fatores dependentes da máquina: – grau de concorrência; – escalonamento e alocação de processadores; – comunicação e sincronização.
Modelo PRAM – modelo ideal
conjunto de p processadores operando sincronamente sob o controle de um único relógio, compartilhando um espaço global de memória
é possível que diferentes fluxos de instruções sejam executados– aspecto não muito explorado pelos algoritmos
algoritmos desenvolvidos para este modelo geralmente são do tipo SIMD– todos os processadores executam o mesmo conjunto de
instruções, e ainda a cada unidade de tempo, todos os processadores estão executando a mesma instrução mas usando dados diferentes.
Modelo PRAM – modelo ideal
propriedades chaves: – execução síncrona sem nenhum custo adicional para a
sincronização – comunicação realizada em uma unidade de tempo, qualquer que
seja a célula de memória acessada – comunicação é feita usando a memória global
Passo do algoritmo PRAM
fase de leitura: os processadores acessam simultaneamente locais de memória para leitura. Cada processador acessa no máximo uma posição de memória e armazena o dado lido em sua memória local
fase de computação: os processadores executam operações aritiméticas básicas com seus dados locais
fase de gravação: os processadores acessam simultaneamente locais de memória global para escrita. Cada processador acessa no máximo uma posição de memória e grava um certo dado que está armazenado localmente
Modelo PRAM
análise e estudo de algoritmos paralelos
definição de paradigma de programação paralela
avaliação do desempenho desses algoritmos independentemente das máquinas paralelas
se o desempenho de um algoritmo paralelo para o modelo PRAM não é satisfatório, então não tem sentido implementá-lo em qualquer que seja a máquina paralela
se eficiente, no entanto, podemos simulá-lo em uma máquina real : simulação deve ser eficiente
Padrões de Acesso no Modelo PRAM
Exclusive Read (ER): vários processadores não podem ler ao mesmo tempo no mesmo localExclusive Write (EW): vários processadores não pode escrever no mesmo local de memóriaConcurrent Read (CR): vários processadores podem ler ao mesmo tempo o mesmo local de memóriaConcurrent Write (CW): vários processadores podem escrever no mesmo local de memória ao mesmo tempo
Combinações são usadas para formar as variantes do PRAM: EREW, CREW, ERCW e CRCW
Prioridades do CRCW
Para resolver conflitos no caso de vários processadores tentarem escrever ao mesmo tempo no mesmo local de memória global:
Comum - vários processadores concorrem a escrita no mesmo local de memória global durante o mesmo instante de relógio - todos devem escrever o mesmo valor;
Arbitrário - dentre os vários processadores, um é selecionado arbitrariamente e seu valor armazenado no local de memória disputado;
Prioridade - dentre os vários processadores, aquele com o menor índice é escolhido para escrever o seu valor no local concorrido.
Memória Global
P1 P2 P3 P4 Pn
Comunicação em uma máquina PRAM
Comunicação através da memória global: Pi quer passar x para Pj
– Pi escreve x em um local de memória global em um determinado passo
– Pj pode acessar o dado naquele local no próximo passo
d1d1
Memória compartilhada
P1 P2d2
P3d3
Pndn
PASSO 1PASSO 2
d1
Observações
os processadores operam sincronamente: a cada passo, todas os processadores executam a mesma instrução sobre dados distintos
uma instrução pode ser simplesmente uma operação aritmética ou uma comparação de dois números
processadores ativos: somente um subconjunto de processadores executem uma instrução e processadores restantes ficam ociosos/inativos
ExemploV ⇒ vetor com n elementos. x ⇒ um dado valor
Problema: x ∈ V ? Ambiente: P processadores tipo EREW PRAM
Analisando o problema:
todos os processadores tem que saber o valor de x não podem acessar a célula de x simultaneamentedepois, cada processador tem que olhar os elementos de V sinalização da localização do valor x no vetor V
Solução
todos os processadores devem saber sobre x: broadcasting ou difusão
Pior caso deste procedimento log2 P passos
– P1 acessa a memória global:
– P2 comunica com P1 ou seja, de alguma forma, P1 informa x para P2
– P1 e P2 informam x para P3 e P4
– assim por diante
processadores não têm permissão de acesso simultâneo ⇒ gravam xem lugares distintos: Mi é um dos P locais de memória global
Um vetor M auxiliar é utilizado
Solução do broadcasting (leitura)
P1 lê x
P1 escreve x em M1
P2 lê M1
P2 escreve em M2
P3 e P4 lêem M1 e M2
P3 e P4 escrevem em M3 e M4
P5, P6, P7 e P8 lêem M1, M2, M3 e M4
P5, P6, P7 e P8 escrevem M5, M6, M7 e M8
e assim por diante
a cada passo: duas vezes o número de processadores ativos do passo anterior podem ler e escrever ⇒ log P passos
x xx
Memória compartilhada
P1
x
PASSO 1
x
P2
x
x
x
x
x
P3
x
P4
x x
P5 P6 P7 P8
x x
x x
PASSO 2 PASSO 3 PASSO 4
M1 M2 M3 M4 M5 M6 M7 M8
A Procura
o vetor V é divido em P pedaços: S1, S2, …, SN
– Pi procura por x em Si
– pior caso: n/P passos
Total: log N + n/N passos, no pior caso
Como o algoritmo poderia ser melhorado??– Definição de uma variável Achou
Com computador mais poderoso ⇒ algoritmo mais rápido.
PRAM mais poderoso: CREW PRAMpara achar x, o algoritmo executa n/P passosleituras concorrentes são permitidas– todos os processadores podem acessar x em um passo – todos os processadores podem consultar Achou em um passo– mas ao encontrar, o processador tem que atualizar Achou
Quantos passos nas seguintes situações?– somente um dos elementos tem valor x– x pode ser um valor repetido em V
• mais de um processador pode atualizar Achou simultaneamente.
Relações entre Modelos
EREW PRAM ⇒ mais fraco
CREW PRAM ⇒ pode executar EREW na mesma quantidade de tempo – simplesmente leituras concorrentes não são feitas
CRCW PRAM ⇒ pode executar EREW na mesma quantidade de tempo– simplesmente leituras concorrentes não são feitas
Simulando Múltiplos Acessos em EREW
um só processador pode acessar a um local de memória a em um determinado instante
o modelo é bastante flexível – pode ser executado em qualquer outra PRAM– permite a simulação de múltiplos acessos mesmo que o espaço de
armazenamento aumente ou o tempo de execução aumente
Simulando Múltiplos Acessos em EREW
Por que a simulação? O simulação pode ser necessária caso uma das razões aconteça:– se os computadores paralelos disponíveis são do tipo EREW -
então executar algoritmos tipo: CREW e CRCW através de simulação
– para computadores paralelos com um grande número de processadores:
• o número de processadores que podem acessar a um mesmo local de memória simultaneamente é limitado
Simulando CW comum em um EREW
N acessos simultâneos por um EREW PRAM por N processos no mesmo local– leituras simultâneas: valor difundido, conforme já descrito: log N
passos– escritas simultâneas: procedimento simétrico à difusão
CW comum:todos processadores podem escrever no mesmo local de memória global se o valor for o mesmo.Suponha que Pi queira escrever o valor ai (1≤ i ≤ N)
variável auxiliar para cada processador Pi : bi
Simulando CW comum em um EREW
Dividindo a série ai em dois grupos
compare ai com ai+(N/2)
se forem iguais, Pi seta bi para verdadeiro (1)
Dividindo a série ai em quatro grupos
compare ai com ai+(N/4) e bi com bi i+(N/4)
se forem iguais, Pi seta bi para verdadeiro (1)
P2P1
= == 1 ?= ?1
Memória compartilhada
a2 a3 a4 a5 a6 a7 a8.......... b1 b2 b3 b4
P3 P4
5 5 5 55555
= ?1 1= ?
5555555
a1
5
= ?1 = ?1
5 5
= ?&
= == 1 ?
1 15 55
= ?&
= == 1 ?
1 1
1 1
5 5 1 1
&
Modelos Fortes e FracosO que quer dizer mais forte? Se um algoritmo é simulado em um modelo mais fraco, o número de passos pode aumentar
CR ⇒ N leituras podem ser feitas concorrentemente ER ⇒ uma leitura é feita por mais de uma passo
[EcKstein,1979][Vishkin,1983] p processadores CRCW com prioridade, é simulado por um EREW PRAM com complexidade de tempo aumentado por um fator Θ (log p).
em um CRCW com prioridade, os acessos simultâneos seria imediatos, mas não no EREW
Algoritmos PRAM
para um problema: se um algoritmo PRAM tem complexidade de tempo menor que a do algoritmo seqüencial ótimo, então o paralelismo pode ser usado
Como iniciar um algoritmo PRAM: ativar os P processadores que farão parte da computação– os processadores serem ativados um a um– através do algoritmo de difusão: log P passos
depois da ativação, o algoritmo paralelo pode ser executado
Identificando Paralelismoparadigmas de computação paralela
algoritmos aqui falados consideram o modelo PRAM. Exemplos:
Árvore Binária: o fluxo de dados (e controle) se dá da raiz até as folhas– Difusão: a partir de um processador, o fluxo (controle ou dados)
passa para dois processadores e assim, dobrando a cada iteração.– Divisão e Conquista: um problema é subdividido em subproblemas
cada vez menores
ou contrário, das folhas até a raíz:– Redução: dado n valores, a operação X é uma binária associativa
Redução: Somasoma de n elementos: A = < 4, 3, 8, 2, 9, 1, 0, 5, 6, 3, 10, 2, 4, 7, 11, 3>
Soma_PRAM_Pi (){Para ( 1≤ h ≤ log n ) faça
se ( i ≤ n/2h ) faça A[i] := A[2i] + A[2i -1];
}
A[i] := A[2i] + A[2i -1]; ⇒ leitura: A[2i] e A[2i -1]; computa: A[2i] + A[2i -1]; escreve: A[i]
34
P1 P2 P3 P4 P5 P6 P7 P8
4 3 8 2 9 1 0 5 6 3 10 2 4 7 11 3
Memória compartilhada
8 2 9 1 0 5
77 1010
6 3 10 2 4 7 11 39
1010 55 99 1212 1111 1414
7 10 10 5
25
12 11 14
17 15 2117 15 21 25
17 15 21 25
32 4632 46
32 46
7878
Redução: Soma
primeiro loop: não há necessidade de mais do que n/2 processadores
processadores acessam dois locais de memória simultaneamente, mas distintos
processadores escrevem em um local de memória (cada) simultaneamente, mas distintos
para somar, log n iterações são necessárias, cada uma tem tempo constante
Complexidade do Algoritmo: O ( log n) com O ( n/2 ) processadores
Noções de Complexidade
Existem algoritmos PRAM cuja complexidade de tempo é menor do que o algoritmo correspondente seqüencial ótimo, mas podem desempenhar mais operações do que o seqüencial
Complexidade de tempo do pior caso em função do tamanho da entrada. Cada passo corresponde: – uma fase de computação– uma fase de comunicação
é importante especificar– o número máximo de processadores usados, como função da
entrada– o modelo arquitetural sendo usado
Noções de ComplexidadeParalelismo Limitado
algoritmo p-paralelo se implementado em um modelo com pprocessadores, fixo
T(n) e P(n): o tempo de execução e a quantidade de processadores do algoritmo paralelo
se o número de passos é T(n) considerando p processadores, então esse algoritmo é p computável neste tempo
se T(n) é polinomial e p é limitado superiormente por polinômio, então o número de processadores é limitado polinomialmente, senão, ilimitado
Algumas Definições
Custo do Algoritmo Paraleloproduto tempo-processador T(n) × P(n) – ignora ociosidade de processador
Algoritmo paralelo de custo ótimo: Ts = T(n) × P(n)
– Ts o tempo de execução do melhor algoritmo seqüencial
p < P(n) processadores: cada processador executa sequencialmente o que P(n)/ p processadores executam– T(n) × P(n)/p unidades de tempo
A - algoritmo paralelon - o tamanho da entrada
Algumas DefiniçõesSpeedup , dado o número de processadores p
Se o S(A(n),p) é linear então todos os processadores são efetivamente utilizados– difícil de ser alcançado devido a natureza dos algoritmos e do
ambiente computacional paralelo
– difícil decompor o algoritmo em tarefas completamente independentes, onde cada tarefa leva Ts /p unidades de tempo para ser executada
Algumas Definições
Eficiência do algoritmo paralelo
razão entre S(A(n),p) e o número de processadores p E(A(n),p) = S(A(n),p)/p
– mostra como os processadores são efetivamente utilizados: quanto maior, melhor a utilização de cada processador
se E(A(n),p) = 1 o algoritmo paralelo é de custo ótimo
Algumas Definições
Trabalho de um Algoritmo Paralelo
um algoritmo é descrito como uma seqüência de unidades de tempo, onde em cada unidade um conjunto de instruções concorrentes
trabalho de um algoritmo paralelo é o número total de operações executadas, não incluindo os tempos ociosos de certos processadores
são somadas, a cada unidade de tempo, o número de operações concorrentes podem estar sendo executadas
Exemplo: soma de n elementosT(n) e P(n): n/2 processadores executam em O(log n) unidades de tempo Custo de O(n log n) em O(log n) unidades de tempo
Usando p < P(n) processadores: O(n log n/p)
– 1a unidade de tempo - n/2 operações (somas em paralelo)
– 2a unidade de tempo - n/4 operações (somas em paralelo)
– 3a unidade de tempo - n/8 operações (somas em paralelo)
– j-ésima unidade de tempo - n/2j operações
Total de operações: ∑O(log n) n/2j = O(n)
..............
Reduzindo o número de processadores
Princípio de Brent
“ Qualquer algoritmo paralelo com complexidade de tempo T(n) usando um número suficientemente grande de processadores e que ainda consistindo de O(e) operações elementares, pode ser implementado em p processadores com complexidade de tempo
O( e/p + T(n))
P ro v a ??
P2 PpP1
. . . . . .
Total de Operações: e Total de Processadores: p
Unidadede
Tempo
1
2
3
4
.
.
.
T(n)
Númerode
Operações
e1
e2
e3
e4
.
.
.
eT
Pk
Tempo Total ∑
i
i
pe ∑
+
i
i
pe 1 )(nT
pei +
≤≤ ≤
Outra vez: soma de n elementos
seja um modelo PRAM com p = 2q ≤ n = 2k processadores: P1,..., Pp
seja l = n/p = 2 k - q
Ps é responsável por A[l(s - 1) + 1] , …. , A[ls]
cada elemento é um vértice de uma árvore bináriao número de computações concorrentes corresponde ao número de vértices em cada nível dividido pelos processadores disponíveis
Análise do AlgoritmoSeja o algoritmo em que n elementos são somados usando pprocessadores (Obs.: O algoritmo só considera o trabalho de um dado processador Ps:
primeiro passo: O(n/p) unidades de temposegundo passo?
Soma de n Elementos (JáJá)Soma_Paralela_Ps ( A, p ){
for j =1 to l do /* l = n/p */B(l(s - 1) + j): =A(l(s - 1) + j);
for h = 1 to log n do if (k - h - q ≥ 0) then
for j = 2k-h-q(s - 1) + 1 to 2k-h-q s doB(j): = B(2j - 1) + B(2j);
else if (s ≤ 2k-h) thenB(s): = B(2s - 1) + B(2s);
if (s = l) then S: = B(1);}
P3P2
0
P4
011
11
P1
Memória compartilhada
3 2 1 5 3 2 7 38 10 119 44 64 3 8 2 9 1 5 6 3 10 2 4 7 11 3
7
10
10
5
9
12
11
14
7
10
10
5
9
12 14
7 10 10 5 9 12 14
17 15 21 2517 15 21 25
17 15 21 25
32 46
32 46
32 46
7878
Perguntas:
qual o número de operações?qual o trabalho?qual o custocomplexidade?tipo do PRAM?teria alguma outra versão com um menor de trabalho ou custo?qual o número de comunicações?
1 Responda as perguntas considerando as duas versões discutidas na sala de aula
2 especificar o pseudo-algoritmo da segunda versão discutida.
Pointer Jumping
T = (V,E) : árvore direcionadaodg(v) e idg(v): graus de saída e entrada do vértice v ∈ V∃ um vértice r tal que
� ∀ v ∈ V-{r}, odg(v) = 1, odg(r)=0� ∀ v ∈ V-{r}, ∃ um caminho de v a r
O vértice r é dita raíz de T
P o in t e r J u m p in g é uma técnica usada para processamento de dados armazenados em forma de um conjunto de árvores direcionadas enraizadas
Pointer Jumping - árvore direcionada
ProblemaF: floresta de árvores direcionadas enraizadasespecificação: através de um vetor F de n elementos onde – F(i) = j se (i,j) ∈ E (é um arco) ⇒ j é o pai ou predecessor imediato de i– F(i) = i se i é a raíz
Problema: determinar a raíz S(j) da árvore contendo o vértice jSolução Sequencial - resolve o problema em tempo linear:
identificação das raízes: achar todos os vértics v tal que F(v) = v em O(n)reversão dos arcos: pois estamos considerando que se (i,j) ∈ E então jé pai de i em O(n)execução de uma busca em profundidade ou largura: nesta busca, podemos saber a partir da raíz r quem são seus descendentes
Solução ParalelaUm algoritmo eficiente foi proposto, sendo um esquema totalmente diferente do esquema sequencial
inicialmente: ∀ i ∈ V, S(i) é o pai de i
a técnica po inter jumping consiste em atualizar o sucessor de cada vértice pelo sucessor do sucessor– percorrendo desta maneira, corresponde a cada iteração chegar mais e
mais próximo doa raíz da árvore– a cada iteração, a distância entre o vértice i e seu sucessor S(i) dobra– o ponto de parada: quando S(i) é a raíz procurada;
Pointer Jumping
início : S[1] = 2 S[2] = 3 S[3] = 4 S[4] = 5 S[5] = 5 1o passo: S[1] = 3 S[2] = 4 S[3] = 5 S[4] = 5 S[5] = 5 2o passo: S[1] = 4 S[2] = 5 S[3] = 5 S[4] = 5 S[5] = 5 3o passo: S[1] = 5 S[2] = 5 S[3] = 5 S[4] = 5 S[5] = 5……..k-ésimo passo: S[1] = raíz ⇒ d(1, S[1]) = 2k (término do Algoritmo)
Pointer Jumping
1 2 3 4 5 R
Complexidade e Corretude do Algoritmocomo podemos provar que o algoritmo está correto?simplesmente definimos um algoritmo e o executamos?– seja h a altura máxima de uma árvore qualquer na floresta de árvores
enraizadas direcionadas– por indução em h
Temos que analisar tal algoritmo, considerando a altura da maior ávore dentre as da floresta: domina o tempo de execução do algoritmo– cada passo j, definição de distância entre i e S[i]
dj(i,S[j]) = 2dj-1(i,S[i])
– por indução em k: supondo verdade que dk-1(i,S[i]) = 2k-1
Complexidade e Corretude do Algoritmo
– assim, no passo kdk(i,S[j]) = 2 dk -1(i,S[i]) = 2 * 2k-1
– logo, por definição da distância máxima, tem-se h = 2k e assim, o número máximo de iterações é k = O(log h)
em cada iteração, o tempo paralelo é O(1). Temos um total de O(log h) iterações. Ainda, o número de processadores é n
o algoritmo paralelo não tem custo ótimo. Por que?
é um algoritmo CREW PRAM
Soma de Prefixos
si = x1 ⊗ x2 ⊗ …. ⊗ xi
saída: n elementos : s1, s2, …., sn
Aplicações: concatenação de strings, soma, multiplicação, etc
Algoritmo Sequencial Soma_Prefixos_Sequencial( x){
s1 := x1 ; Para i = 2, …., n si = si-1 ⊗ xi ; }
Complexidade: O(n)
Soma de Prefixos
Definição
Seja X = { x1, x2, …., xn } e uma operação ⊗ binária ea operação ⊗ é fechada sobre X ou seja, se xi e xj são elementos de X então xi ⊗ xj também é a operação ⊗ é associativa
Soma de Prefixos - pointer jumping
representação dos elementos é feita através de uma árvore direcionada enraizada– cada vértice i da árvore tem um peso associado xi
– pointer jumping é usado, armazenando as somas intermediárias a cada iteração
– como várias árvores podem ser percorridas ao mesmo tempo, várias seqüências podem ser resolvidas ao mesmo tempo
algoritmo para soma de prefixos: temos a informação de quem é pai do vértice i, ou seja, F[i] – em seqüência de n elementos F[i] = i+ 1, i = 1,…., n-1– a árvore seria uma lista linear
Soma de Prefixo – outro paradigma
si = x1 ⊗ x2 ⊗ …. ⊗ xi
saída: n elementos : s1, s2, …., sn
Paradigma: ávores binárias
A[i] = xi
B[h,j] e C[h,j] onde 1 ≤ j ≤ n/2h (1 ≤ h ≤ log n especifica o nível)ao final: sj = C[0,j]
Algoritmo Paralelo não RecursivoSoma_Prefixos_Paralela_nRecursivo( A ){1. Para 1 ≤ i ≤ n faça em // : B[0,j] := A[j];2. Para 1 ≤ h ≤ log n faça 2.1 Para 1 ≤ j ≤ n/2h faça em // 2.1.1 B[h,j] := B[h - 1, 2j-1] * B[h - 1, 2j];
3. Para h = log n … 0 faça 3.1 Para 1 ≤ j ≤ n/2h faça em // 3.1.1 se j é par, então C[h,j] := C[h + 1,j/2]; 3.1.2 se j == 1, então C[h,1] := B[h,1];3.1.3 se j é ímpar, então C[h,j] := C[h + 1,(j-1)/2] * B[h,j]; }
P1 P2 P3 P4 P5 P6 P7 P8B[0,1]=X1 B[0,2]=X2 B[0,3]=X3 B[0,4]=X4 B[0,5]=X5 B[0,6]=X6 B[0,7]=X7 B[0,8]=X8
B[1,1]=B[0,1]+B[0,2]
X1+X2
B[1,2]=B[0,3]+B[0,4]
X3+X4
B[1,3]=B[0,5]+B[0,6]
X5+X6
B[1,4]=B[0,7]+B[0,8]
X7+X8
B[2,1]=B[1,1]+B[1,2]
X1+X2+x3+x4
B[2,2]=B[1,3]+B[1,4]
X5+X6+x7+x8
B[3,1]=B[2,1]+B[2,2]
X1+X2+...+x7+x8
C[3,1]=B[3,1]
X1+X2+...+x7+x8
C[2,1]=B[2,1]
X1+X2+x3+x4
C[2,2]=B[3,1]
X1+X2+...+x7+x8
C[1,1]=B[1,1]
X1+X2
C[1,2]=C[2,1]
X1+X2+X3+X4
C[1,3]=C[2,1]+B[1,3]
X1+X2+...+X5+X6
C[1,4]=C[2,2]
X1+X2+...+X7+X8
C[0,1]=B[0,1]
X1
C[0,2]=C[1,1]
X1+X2
C[0,3]=C[1,1]+B[0,3]
X1+X2+X3
C[0,4]=C[1,2]
X1+X2+X3+X4
C[0,5]=C[1,2]+B[0,5]
X1+X2+X3+X4+X5
C[0,6]=C[1,3]
X1+X2...X5+X6
C[0,8]=C[1,4]
X1+X2...X7+X8
C[0,7]=C[1,3]+B[0,7]
X1+X2+...+X6+X7
Soma de Prefixos Não Recursivo
Princípio de Brenttempo de execução do algoritmo // A para P(n) processadores: T(n)w operações do algoritmo Atempo paralelo do algoritmo considerando p processadores de acordo com o princípio de Brent:
Tp(n) = w/p + T
Aplicação do Princípionecessário saber quantas operações são executadas a cada passoalgoritmo de soma de prefixos com n = 2k - número de passos:
2log n + 2 ⇒ 2k+2– qual o número de operações?– qual o custo?
Princípio de Brent
w1,1 : número de operações no passo 1considerando o único loop
w2,m : número de operações executadas no passo 2 na m-ésima iteração
w3,m : número de operações executadas no passo 3 na m-ésima iteração
Então:w1,1 = n
w2,m = n/2m = 2k /2m para 1 ≤ m ≤ k
w3,m = 2m para 0 ≤ m ≤ k
Assim:w = w1,1 + ∑ w2,m + ∑ w3,m
w = n + ∑ n/2m + ∑ 2m
w = n + n(1-1/n) + 2n-1 = 4n-2w = O(n)
Divisão e Conquista
usada quando identificamos problemas que podem ser particionados em subproblemas menores, que são mais simples de serem resolvidos
– divisão da entrada em partições menores de mesmo tamanho (ou quase)
– resolução recursiva de cada subproblema definido por cada partição
– combinação das soluções de cada subproblema, produzindo a solução do problema como um todo
tende a ser eficiente se a decisão e resolução podem ser feitas recursivamenteeficiente no mundo seqüencialnatural na exploração de paralelismo
Divisão e Conquista
Problema da Envoltória ConvexaSeja S = { p1 , p2 , …. , pn } um conjunto de n pontos em um plano, cada um representado por suas coordenadas (xi, yi). A envoltória convexa planar de S é o menor polígono convexo que contém todos os pontos de S
observação: um polígono é convexo quando, para qualquer dois pontos, (xi, yi) ≤ (xj, yj), a reta [(xi, yi),(xj, yj)] está dentro do polígono.
o problema: determinar a lista ordenada de pontos S que formam o polígono convexo. Essa lista será denotada por CH(S) (convex hull).
Divisão e Conquista
Problema da Envoltória Convexaé um problema muito importante em geometria planar:– estatística– processamento de imagem– reconhecimento de padrões– computação gráfica– problemas geométricos
resolvido sequencialmente através de divisão e conquista O(n log n)– o algoritmo de ordenação de pontos resolve esse problema mais
eficientemente
Divisão e Conquista Paralelo
Dado um conjunto S de n pontos, sejam:p ∈ S o ponto com o menor xi
q ∈ S o ponto com o maior xj
ordenação paralela: em O(log n) em uma PRAM EREW com O(n log n ) operações
particionam CH(S) em:envoltório superior UH(S) = < todos os pontos de p a q pertencentes a CH(S) seguindo o sentido horário >
envoltório inferior LH(S) = < todos os pontos de q a p pertencentes a CH(S) seguindo o sentido horário >
O Problema da Envoltória Convexa
pq
CH(S)
S
envoltória inferior
LH(S)
envoltória superior
UH(S)
Divisão e Conquista Paralelo
pq
pq
Merging de duas envoltórias superiores
Merging de duas envoltórias superiores
pq
Tangente Comum Superior
• sequencial – O(log n)• busca binária
Entrada: n pontos ordenados tais que x(p1) < x(p2) < .... < x(pn)
Saída: UH(S)
4) Se n <= 4 então ache UH(S) por força bruta e retorne5) S1 = (p1, ..., pn/2) e S2 = (pn/2+1, pn). Compute UH(S1) e
UH(S2) em paralelo, recursivamente6) Ache a tangente comum superior entre UH(S1) e UH(S2) e
defina UH(S)
8) O(1) 9) T(n/2)10) TCS(UH(S1), UH(S2)) em O (log n) Combinar as duas curvas dada a tangente produzindo S
– em O(1) com n processadores leituras concorrentes serão realizadas.
Algoritmo
Algoritmo
Explicar: – ComplexidadeT(n) = O(log2 n) com O(n) processadores
Qual o número de operações?
Desempenho de computação paralela
o paralelismo existente na aplicação
decomposição do problema em subproblemas menores
a alocação destes subproblemas aos processadores
o modo de acesso aos dados:
– a existência de uma memória global
– ou distribuída comunicação por trocas de mensagens
a estrutura de interconexão entre os processadores
a velocidade dos processadores, memórias e rede de interconexão. Em ambientes distribuídos, a meta é de explorar e tirar proveito ao máximo do potencial
computacional, sendo assim questões relacionadas ao gerenciamento de recursos do sistema muito importante
Escalonamento de Aplicações
Um algoritmo que estabelece como executar um algoritmo paralelo em um determinado sistema de computadores
Para implementar um escalonador, o problema tem que ser especificado:
– As características da aplicação devem ser especificadas
– As características cruciais do sistema de processadores em questão devem ser estabelecidas
Modelagem
Representação do problema
Representação do ambiente de solução
Simplificação, sem omitir as características que afetam o desempenho em geral
Qual o objetivo?
Escalonar aplicações em um sistema paralelo e distribuído tal que o tempo de execução seja minimizado
Escalonar aplicações em um número limitado de processadores tal que o tempo de execução seja minimizado, considerando custo de comunicação
Escalonar aplicações em um número limitado de processadores tal que o tempo de execução seja minimizado considerando tempos limites (deadline), considerando custo de comunicação
⇓o objetivo deve estar especificado
Uma Classe de Problemas
Escalonamento de Aplicações em um Sistema de Computadores Distribuídos
classe de aplicações
– especificada pelo modelo da aplicação
a arquitetura enfocada constitui em um sistema de processadores de memória distribuída que se comunicam por trocas de mensagens
– modelo arquitetural apresenta as características importantes a serem consideradas
Escalonamento de Aplicações
Alguns conceitosTarefa – uma unidade de computação
job = conj. de tarefas com objetivo comum
aplicação paralela tarefas que seguem uma ordem parcial
Escalonamento de Aplicações
Escalonamento local X globalglobal tarefas são associadas a processadores mapeamento, task placement, matchinglocal várias tarefas em um processador
No escalonamento global:- migração – custoso e nem sempre usado (sala contexto, trasfere contexto
para o novo processador, reinicializa tarefa)- geralmente se refere a balanceamento de carga
Balanceamento de Carga
sender-initiated
P1 P2 P1 P2
receiver-initiated
Mais conceitos
preempção tarefas/jobs em execução podem ser transferidas (migradas) – mais custos
não preempção geralmente em relação às tarefas– tarefas não são interrompidas– migração somente para tarefas ainda por executar
Escalonamento de Aplicações
Estático
conhecimento de características associadas às aplicações antes da execução desta (estimativas)
relação de precedência entre os componentes da aplicação
Dinâmico
estimativas são conhecidas antes da execução e não as características reais.
a especificação do escalonamento é feita ao longo da execução da aplicação
– balanceamento de carga, por exemplo
Escalonamento Estático de Aplicações
O Problema de Escalonamento de Tarefas em um conjunto de processadores é, em sua forma geral, NP-completo.
Uma variedade de heurísticas de escalonamento foram propostas, principalmente para um conjunto de processadores homogêneos, considerando ou não custo de comunicação associado à troca de mensagens
Alguns heurísticas que consideram um conjunto de processadores homogêneos foram analiticamente avaliadas, e foi concluído que escalonamento produzidos estão dentro de um fator do ótimo.
Algumas instâncias do problema possuem solução ótima
Modelo da Aplicação
uma aplicação da classe de aplicações abordadas é constituída por um conjunto de tarefas, ordenadas parcialmente por uma relação de precedência
a classe de aplicações aqui discutida pode ser representada por um grafo acíclico direcionado (GAD) G = (V,E, ε, ω), onde
– as tarefas da aplicação são representadas pelo conjunto de n vértices
V = { v1 , v2 , ... , vn }
– as relações de precedência que correspondem a dependência de dados são representadas pelo conjunto de dados
E = { (vi , vj ) }
Modelo da Aplicação
o peso de computação ε(vi) pode estar associado a cada tarefa de G (estimativa) correspondendo ao número de unidades de tempo necessários para executar a tarefa vi
o peso de comunicação ω(vi, vj ) pode estar associado a cada arco (vi, vj ) de G (estimativa) correspondendo à quantidade de dados a serem enviados da tarefa vi para a vj
seja pred (vi) o conjunto de predecessores imediatos da tarefa vi , ou seja,
pred (vi) = {vj / (vj ,vi ) ∈ E }
seja succ (vi) o conjunto de sucessores imediatos da tarefa vi , ou seja,
succ (vi) = {vj / (vi , vj ) ∈ E }
Modelo da Arquitetura
definição de características que afetam o desempenho
processadores homogêneos e heterogêneos
número limitado ou não de processadores
memória distribuída ou compartilhada
topologia da rede de interconexão
modelo de comunicação
– latência de comunicação
– sobrecargas de envio e recebimento
– etc
Heurísticas de Escalonamento
Heurísticas de Escalonamento Estático
heurísticas de construção: um algoritmo polinomial no tamanho da entrada que a cada iteração, especifica para uma tarefa o seu escalonamento
– tupla (tarefa, processador, tempo de início)
– ao final, uma só solução foi formada
– escalonamento deve ser válido (respeitar as relações de precedência e as características do modelo arquitetural)
difícil classificação
– técnica empregada
– modelo considerado
Heurísticas de Escalonamento
Heurísticas de Escalonamento Estático
List Scheduling
Algomeração de Tarefas
Minimização de Caminho Crítico
Replicação de Tarefas
List Scheduling
Estratégia (extremamente) gulosa
tradicional e bastante conhecida (utilizada) devido a sua simplicidade (baixa complexidade)
– escalonamento de instruções em unidades funcionais
– escalonamento em processadores heterogêneos (em número limitado)
Alguns conceitos importantes
tarefa livre - todos os seus predecessores imediatos já foram escalonados;
processador ocioso - em um determinado instante tk , não existe nenhuma tarefa sendo executada neste instante;
List Scheduling Framework
Definição da prioridade das tarefas vi ∈ V;
Enquanto ( existir vi não escalonado ) faça {
vi = a tarefa livre de maior prioridade;
pj = o processador ocioso onde vi começa mais cedo;
escalone vi no processador pj ;
determine as novas tarefas livres;
}
1
6
321
0
pesos de execução em pesos dos arcos em
5
4
4
5 2 7
6
6
3
2 48
1 32
54
Um Exemplo de GAD
6
0
4
Custos Unitários
3
21
8
7
5
11
10
9
Programação Distribuída
Introdução e Conceitos Básicos
Conceitos Básicos
Sistema Distribuído: – Não há compartilhamento de memória– Troca de informação através de troca de mensagens
Programa Distribuído: Conjunto de processos que trabalham em conjunto para solucionar um problema
Programas Distribuídos são executados em Sistemas Distribuídos
Conceitos Básicos
Áreas de demanda:– Otimização combinatória– Mineração de dados– Simulações– Meteorologia– Bioinformática– Computação gráfica
Computação intensiva !!
Conceitos Básicos
Seqüencial ≠ Distribuído - Determinação de estado não é trivial
Distribuído
if (x proc a = 1) and
(y proc b = 2) then
Não é trivial !!!
Seqüencial
if (x=1) then
Conceitos Básicos
Seqüencial ≠ Distribuído - Ausência de uma base de tempo global
Inst 1Inst 2Inst 3......Inst z......Inst w
Inst 1Inst 2...Inst x............Inst y
msg
tem
po
tem
po
Conceitos Básicos
Distribuído ≠ Centralizado - Não determinístico
P(i)
P(j)
P(k)
P(i)
P(j)
P(k)
Modelos de Computação
Assíncrono:– Sem coordenação global– Atraso na transmissão das mensagens é finito mas não determinado– Desenvolvimento mais complexo– Realístico
Síncrono:– Com coordenação global– Comunicação em “pulsos”– Desenvolvimento mais simples– Menos realístico
Modelo utilizado
Um programa paralelo distribuído é representado por um grafo não orientado G = (N,E) onde:– N : conjunto de nós que representam processos– n = |N|– E : conjunto de arestas que representam canais de comunicação– e = |E|
Para i = 1, 2, 3, ..., n, pi ∈ N é um processo que pode se comunicar exclusivamente por troca de mensagens com os processos pj tal que (pi, pj) ∈ E
Canais de comunicação bidirecionais de capacidade infinita
Métricas para Avaliação
CORRETUDE
Número/Tamanho das mensagens enviadas
Tempo de convergência:– Síncrono: Nr. de pulsos– Assíncrono: Maior cadeia de mensagens com relação de “causalidade”
Introdução ao MPI
Introdução
O MPI é um padrão para desenvolvimento de aplicações distribuídas
Disponível na forma de bibliotecas para linguagens C, C++ e Fortran
SPMD – Single Program Multiple Data – todos os processos executam o MESMO programa
Síntese de diversos sistemas anteriores
Histórico Breve
Desenvolvido por um fórum aberto internacional composto por representantes da indústria, universidade e entidades governamentais
Influenciado por outras plataformas e comunidades: Zipcode, Chimp, PVM, Chamaleon e PICL
Padronização iniciada em abril de 1992
Objetivos
Eficiência na comunicação
Ambientes para desenvolvimento e execução heterogêneos
Fácil aprendizado para atuais programadores de aplicações distribuídas (interface parecida com a do PVM)
Características
Supõe que a subcamada de comunicação é confiável
Garante ordem de entrega das mensagens
Trabalha com o conceito de COMUNICADORES, que definem o universo de processos envolvidos em uma operação de comunicação
Cada processo ganha uma identificação numérica (rank)
Comandos de incialização e finalização
MPI_Init : Inicializa o ambiente de execução
MPI_Comm_rank: Determina o rank (identificação) do processo no comunicador
MPI_Comm_size: Determina o número de processos no comunicador
MPI_Finalize: Termina o ambiente de execução
Comunicação Ponto a Ponto
O que acontece se um processo tentar receber uma mensagem que ainda não foi enviada?
– Função BLOQUEANTE de recebimento (MPI_Recv) : bloqueia a aplicação até que o buffer de recepção contenha a mensagem
– Função NÃO BLOQUEANTE de recebimento (MPI_Irecv) : retorna um handle request, que pode ser testado ou usado para ficar em espera pela chegada da mensagem
MPI_Send
int MPI_Send(void* message, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm)
message: endereço inicial da informação a ser enviada
count: número de elementos do tipo especificado a enviar
datatype: MPI_CHAR, MPI_INT, MPI_FLOAT, MPI_BYTE, MPI_LONG, MPI_UNSIGNED_CHAR, etc
dest: rank do processo destino
tag: identificador do tipo da mensagem
comm: especifica o contexto da comunicação e os processos participantes do grupo. O padrão é MPI_COMM_WORLD
MPI_Recv
int MPI_Recv(void* message, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status* status)
message: Endereço inicial do buffer de recepçãocount: Número máximo de elementos a serem recebidosdatatype: MPI_CHAR, MPI_INT, MPI_FLOAT, MPI_BYTE, MPI_LONG, MPI_UNSIGNED_CHAR, etc.source: rank do processo origem ( * = MPI_ANY_SOURCE)tag: tipo de mensagem a receber ( * = MPI_ANY_TAG)comm: comunicadorstatus: Estrutura com três campos: MPI_SOURCE_TAG, MPI_TAG, MPI_ERROR
MPI_Irecv
Menos utilizada
Parâmetros iguais ao bloqueante, acrescido de uma estrutura (request) que armazena informações que possibilitam o bloqueio posterior do processo usando a função MPI_Wait(&request, &status)
Comunicação Coletiva
mais restritivas que as comunicações ponto a ponto:– quantidade de dados enviados deve casar exatamente com a
quantidade de dados especificada pelo receptor– Apenas a versão bloqueante das funções está disponível– O argumento tag não existe
Todos os processos participantes da comunicação coletiva chamam a mesma função com argumentos compatíveis
Algumas Funções para Comunicação Coletiva
MPI_Barrier: Bloqueia o processo até que todos os processos associados ao comunicador chamem essa função
Inst 1Inst 2Inst 3......MPI_Barrier(comm)......
Inst 1Inst 2Inst 3......MPI_Barrier(comm)......
Inst 1Inst 2Inst 3......MPI_Barrier(comm)......
Algumas Funções para Comunicação Coletiva
MPI_Bcast: Faz a difusão de uma mensagem do processo raiz para todos os processos associados ao comunicador
Inst 1
Inst 2
Inst 3
...
...
MPI_Bcast(....)
...
...
P(i) P(j) P(k)
msg
Algumas Funções para Comunicação Coletiva
MPI_Reduce: Combina todos os elementos presentes no buffer de cada processo do grupo usando a operação definida como parâmetro e coloca o valor resultante no buffer do processo especificado. O exemplo abaixo soma todas as variáveis “x” armazenando o total na variável “tot” do processo 2.
Processo 2Inst 1Inst 2...x=3;MPI_Reduce(&x, &tot, MPI_INT, MPI_SUM, 2, comm)......
Processo 1Inst 1Inst 2...x=10;MPI_Reduce(&x, &tot, MPI_INT, MPI_SUM, 2, comm)......
Processo 0Inst 1Inst 2...x=1;MPI_Reduce(&x, &tot, MPI_INT, MPI_SUM, 2, comm)......
Programa Exemplo (1/3)
#include <stdio.h>#include <string.h>#include “mpi.h”
main(int argc, char** argv){
int meu_rank, np, origem, destino, tag=0;char msg[100];MPI_Status status;MPI_Init(&argc, &argv);MPI_Comm_rank(MPI_COMM_WORLD, &meu_rank);MPI_Comm_size(MPI_COMM_WORLD,&np);
Programa Exemplo (2/3)
if (my_rank != 0) { sprintf(msg, “Processo %d está vivo!”, meu_rank); destino = 0; MPI_Send(msg,
strlen(msg)+1,MPI_CHAR,destino,tag,MPI_COMM_WORLD);
}
Programa Exemplo (3/3)
else { // if (my_rank == 0) for (origem=1; origem<np; origem++) { MPI_Recv(msg,
100, MPI_CHAR, origem, tag,MPI_COMM_WORLD, &status);
printf(“%s\n”,msg); }}MPI_Finalize( ); }
Alguns Algoritmos Distribuídos
•Propagação de Informação•Propagação com Realimentação•Integral Definida•Conectividade em Grafos•Distância Mínima
Grafo para testes
int matrizVizinhanca[6][6] = { {0,1,1,0,0,0},
{1,0,1,1,1,0}, {1,1,0,0,0,1}, {0,1,0,0,0,0}, {0,1,0,0,0,0}, {0,0,1,0,0,0}};
0
1 2
3 4 5
Propagação de Informações
Propagação de Informações
Nó 0 gera uma informação que tem de ser encaminhada a todos os demais.
0
1 2
3 4 5
Propagação de Informações - Algoritmo
Variáveis: alcançado = falso
Ação para fonte inicial da informação (inf):alcançado := verdadeiro;envie inf a todos os vizinhos;
Ao receber infse alcançado = falso;
alcançado := verdadeiro;envie inf a todos os vizinhos;
Propagação de Informações - Execução
Nó 0 gera uma informação e a encaminha a todos os seus vizinhos
0
1 2
3 4 5
Propagação de Informações - Execução
Nós 1 e 2 recebem a informação e a encaminham a todos os seus vizinhos
0
1 2
3 4 5
Propagação de Informações - Execução
Nós 3, 4 e 5 recebem a informação e a encaminham a todos os seus vizinhos
0
1 2
3 4 5
Propagação de Informações
Será possível aumentar a eficiência do algoritmo?
Será necessária a propagação para TODOS os vizinhos?
Inclusive o remetente da mensagem?
Considere outra possível execução, representada nas próximas telas…
Propagação de Informações - Execução
Nó 0 gera uma informação e a encaminha a todos os seus vizinhos
0
1 2
3 4 5
Propagação de Informações - Execução
Nós 1 recebe a informação e a encaminha a todos os seus vizinhos mas canal de comunicação 0 - 2 está muito lento, e 2 recebe a informação de 1 antes de 0
0
1 2
3 4 5
Propagação de Informação - Complexidades
Mensagens: 2e => O(e)
Tempo: n-1 => O(n)
1 2 3 n
Propagação de Informação - Implementação
#include <stdio.h>#include <mpi.h>
/*Definir o grafo da aplicação antes de executar*/int numeroDeTarefas = 6;int matrizVizinhanca[6][6] = { {0,1,1,0,0,0}, {1,0,1,1,1,0}, {1,1,0,0,0,1}, {0,1,0,0,0,0}, {0,1,0,0,0,0}, {0,0,1,0,0,0} };
Propagação de Informação - Implementação
/*retorna o número de vizinhos da tarefa myRank*/int contaNumeroDeVizinhos(int myRank){ int i; int contador = 0; for (i = 0; i < numeroDeTarefas; i++) if (matrizVizinhanca[myRank][i] == 1) contador++; return contador;}
Propagação de Informação - Implementação
/*programa principal*/int main(int argc, char** argv){ int i; int numeroDeVizinhos; int myRank; int source; int tag = 50; char message[100] = "Oi!"; MPI_Status status;
//inicialização do MPI MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &myRank);
numeroDeVizinhos = contaNumeroDeVizinhos(myRank);
Propagação de Informação - Implementação
if (myRank == 0) { /*enviando para todos os vizinhos de myRank*/
for (i = 0; i < numeroDeTarefas; i++) if (matrizVizinhanca[myRank][i] == 1) { printf("Enviando mensagem para %d\n", i); MPI_Send(message, strlen(message)+1, MPI_CHAR, i,
tag, MPI_COMM_WORLD); } /*recebendo de todos os vizinhos de myRank*/
for(i = 0; i < numeroDeVizinhos; i++){
MPI_Recv(message, 100, MPI_CHAR, MPI_ANY_SOURCE, tag, MPI_COMM_WORLD, &status); printf("Recebendo msg de %d\n", status.MPI_SOURCE); }}
Propagação de Informação - Implementação
else {
/*recebendo msg de uma tarefa vizinha qualquer*/MPI_Recv(message, 100, MPI_CHAR, MPI_ANY_SOURCE, tag,
MPI_COMM_WORLD, &status);/*enviando para todos os vizinhos de myRank*/for (i = 0; i < numeroDeTarefas; i++) if (matrizVizinhanca[myRank][i] == 1)
MPI_Send(message, strlen(message)+1, MPI_CHAR, i, tag, MPI_COMM_WORLD); /*recebendo de todos os vizinhos de myRank menos 1*/
for(i = 0; i < (numeroDeVizinhos - 1); i++) MPI_Recv(message, 100, MPI_CHAR, MPI_ANY_SOURCE, tag, MPI_COMM_WORLD, &status);
}
// Finalização do MPIMPI_Finalize();
}
Propagação de Informações com Realimentação
Propagação de Informações com Realimentação
Nó 0 gera uma informação que tem de ser encaminhada a todos os demais e recebe uma confirmação quando a informação já estiver completamente disseminada.
0
1 2
3 4 5
Propagação de Informações com Realimentação - Algoritmo
Variáveispai := nil;count := 0;alcançado := falso;
Ação para fonte inicial da informação (inf):alcançado := verdadeiro;envie inf a todos os vizinhos;
Ao receber inf: count := count +1; se alcançado = falso alcançado := verdadeiro; pai := origem(inf); envie inf a todos os vizinhos exceto pai; se count := |vizinhos| e pai ≠ nil envie inf para pai;
Propagação de Informações com Realimentação - Execução
Nó 0 gera uma informação e a encaminha a todos os seus
vizinhos
0
1 2
3 4 5
Propagação de Informações com Realimentação - Execução
Nós 1 e 2 recebem a informação e a encaminham a todos os seus vizinhos, exceto pai
0
1 2
3 4 5
Propagação de Informações com Realimentação - Execução
Nós 3, 4 e 5 recebem a informação e como são folhas, a retornam para seus pais.
0
1 2
3 4 5
Propagação de Informações com Realimentação - Execução
Nós 1 e 2 receberam o retorno de seus filhos e podem informar ao seus pais
0
1 2
3 4 5
Propagação de Informações com Realimentação - Execução
Nó 0 recebeu o retorno de todos os seus filhos e pode concluir que todos os nós do sistema já receberam a informação.
0
1 2
3 4 5
Propagação de Informações com Realimentação - Complexidade
Mensagens: 2e => O(e)
Tempo: 2(n-1) => O(n)
1 2 3 n
Propagação de Informações com Realimentação - Implementação
#include <stdio.h>#include <mpi.h>
/*Definir o grafo da aplicação antes de executar*/int numeroDeTarefas = 6;int matrizVizinhanca[6][6] = { {0,1,1,0,0,0}, {1,0,1,1,1,0}, {1,1,0,0,0,1}, {0,1,0,0,0,0}, {0,1,0,0,0,0}, {0,0,1,0,0,0} };
Propagação de Informações com Realimentação - Implementação
/*retorna o número de vizinhos da tarefa myRank*/int contaNumeroDeVizinhos(int myRank){ int i; int contador = 0; for (i = 0; i < numeroDeTarefas; i++) if (matrizVizinhanca[myRank][i] == 1) contador++; return contador;}
Propagação de Informações com Realimentação - Implementação
/*programa principal*/int main(int argc, char** argv){ int i; int numeroDeVizinhos; int myRank; int source; int tag = 50; int pai; char message[100] = "Oi!"; MPI_Status status;
//inicialização do MPI MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &myRank);
numeroDeVizinhos = contaNumeroDeVizinhos(myRank);
Propagação de Informações com Realimentação - Implementação
if (myRank == 0){
/*enviando para todos os vizinhos de myRank*/ for (i = 0; i < numeroDeTarefas; i++) if (matrizVizinhanca[myRank][i] == 1) { printf("Enviando mensagem para %d\n", i); MPI_Send(message, strlen(message)+1, MPI_CHAR, i,
tag, MPI_COMM_WORLD); } /*recebendo de todos os vizinhos de myRank*/ for(i = 0; i < numeroDeVizinhos; i++)
{ MPI_Recv(message, 100, MPI_CHAR, MPI_ANY_SOURCE, tag, MPI_COMM_WORLD, &status); printf(“Confirmação do filho %d\n", status.MPI_SOURCE); }
}
Propagação de Informações com Realimentação - Implementação
else {
/*recebendo msg de uma tarefa vizinha qualquer*/MPI_Recv(message, 100, MPI_CHAR, MPI_ANY_SOURCE, tag,
MPI_COMM_WORLD, &status);pai = status.MPI_SOURCE;
/*enviando para todos os vizinhos de myRank menos seu pai*/for (i = 0; i < numeroDeTarefas; i++)
if ( (matrizVizinhanca[myRank][i] == 1) && (i != pai) ) MPI_Send(message, strlen(message)+1, MPI_CHAR, i, tag, MPI_COMM_WORLD); /*recebendo de todos os vizinhos de myRank menos 1*/
for(i = 0; i < (numeroDeVizinhos - 1); i++) MPI_Recv(message, 100, MPI_CHAR, MPI_ANY_SOURCE, tag, MPI_COMM_WORLD, &status); MPI_Send(message, strlen(message)+1, MPI_CHAR, pai, tag, MPI_COMM_WORLD);
}
Propagação de Informações com Realimentação - Implementação
//Finalização do MPIMPI_Finalize();
}
Integral Definida
Método do Trapezóide
Integral Definida
f(x)
x
y
a b
∫b
a
f(x) dx
Integral Definida – Método do Trapezóide
f(x)
x
y
a b
h=(b-a)/n (constante)
b1=f( x i-1 )
b2=f(x i )Área do trapézio = h (b1+b2) / 2
xixi-1
Área do i-ésimo trapésio: (h/2)[ f(xi-1) + f(xi) ]
∫b
a
f(x) dx =
(h/2)[f(x0)+f(x1) ] + (h/2)[f(x1)+f(x2) ] + (h/2)[f(x2)+f(x3)] + ... + (h/2)[f(xn-1)+f(xn)] = (h/2)[ f(x0) + 2 f(x1) + 2 f(x2) + 2 f(x3) + ... + 2 f(xn-1) + f(xn) ] = h [ f(x0)/2 + f(xn)/2 + f(x1) + f(x2) + f(x3) + ... + f(xn-1) ]
Integral Definida - Algoritmo
Variáveis: h := (b-a)/nrTrapézios; local_n := nrTrapézios / nrProcessos; local_a := a + my_rank * local_n * h; local_b := local_a + local_n * h;
Ação inicial para todos os nós: x := local_a; integral :=(f(local_a)+f(local_b))/2.0; para i variando de 1 até local_n-1 faça x := x + h; integral := integral + f(x); integral := integral * h;
f(x)
x
y
loca
l_b(
0)=l
ocal
_a(1
)
h
loca
l_a(
0)
supondo: nrProcessos=3 nrTrapézios=6 =>local_n=2
loca
l_b(
1)=l
ocal
_a(2
)
loca
l_b(
2)
Integral Definida - Algoritmo
se my_rank = 0 total := integral; para i variando de 1 até nrProcessos – 1 receba valor na variável integral; total = total + integral; imprima “Valor calculado: “ + total; senão envie integral para nó 0;
Integral Definida - Implementação
#include <stdio.h>#include <mpi.h>main(int argc, char** argv) { int my_rank; int p; // número de processos float a=0.0, b=1.0;// intervalo a calcular int n=1024; // número de trapezóides float h; // base do trapezóide float local_a, local_b; // intervalo local int local_n; // número de trapezóides local float integral; // integral no meu intervalo float total; // integral total int source; // remetente da integral int dest=0; // destino das integrais (nó 0)
int tag=200; // tipo de mensagem (único) MPI_Status status;
Integral Definida - Implementação
float calcula(float local_a, float local_b, int local_n, float h);
MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); MPI_Comm_size(MPI_COMM_WORLD, &p);
h = (b-a) / n; local_n = n / p; local_a = a + my_rank * local_n * h; local_b = local_a + local_n * h;
integral = calcula(local_a, local_b, local_n, h);
Integral Definida - Implementação
if(my_rank == 0) { total = integral; for(source=1; source<p; source++) { MPI_Recv(&integral, 1, MPI_FLOAT, source, tag, MPI_COMM_WORLD, &status); total +=integral;
} } else MPI_Send(&integral, 1, MPI_FLOAT, dest, tag, MPI_COMM_WORLD); if(my_rank == 0) printf(“Resultado: %f\n”, total); MPI_Finalize();}
Integral Definida - Implementação
float calcula(float local_a, float local_b, int local_n, float h) { float integral; float x, i;
float f(float x); // função a integrar
integral = ( f(local_a) + f(local_b) ) /2.0; x = local_a; for( i=1; i<=local_n-1; i++) { x += h; integral += f(x); } integral *= h; return integral; }
Integral Definida – Implementação
float f(float x) { float fx; // valor de retorno
// esta é a função a integrar // exemplo: função quadrática fx = x * x;
return fx;}
Conectividade em Grafos
Conectividade em Grafos
O problema trata da desco- berta, por cada nó, das identificações de todos os outros nós aos quais está conectado.
0
1 2
3 4 5
1,2,3,4,5
0,2,3,4,5
0,1,3,4,5
0,1,2,3,40,1,2,3,50,1,2,4,5
Conectividade em Grafos - Algoritmo
Variáveis: initiate = false; para todos os nós k de N; parent(k) := nil; count(k) := 0; reached(k) := false;
Ação se n ∈ N(0): initiate := true; reached(id) := true; envie id para todos os vizinhos;
Conectividade em Grafos - Algoritmo
Input: id(k) recebido do nó j se initiated = false initiated := true; reached(id) := true; envie id para todos os vizinhos;
Conectividade em Grafos - Algoritmo
count(k) := count(k) + 1; se reached(k) = false reached(k) := true; parent(k) := j; para todos os vizinhos exceto parent(k) envie id(k);
se count(k) = nr de vizinhos de i se parent(k) ≠ nil envie id(k) para parent(k)
Conectividade em Grafos - Execução
0
1 2
3 4 5
False0nil1
False
False
False
False
False
reached
0nil5
0nil4
0nil3
0nil2
0nil0
count
parent
nó
False0nil1
False
False
False
False
False
reached
0nil5
0nil4
0nil3
0nil2
0nil0
count
parent
nó
False0nil1
False
False
False
False
False
reached
0nil5
0nil4
0nil3
0nil2
0nil0
count
parent
nó
False0nil1
False
False
False
False
False
reached
0nil5
0nil4
0nil3
0nil2
0nil0
count
parent
nó
False0nil1
False
False
False
False
False
reached
0nil5
0nil4
0nil3
0nil2
0nil0
count
parent
nó
False0nil1
False
False
False
False
False
reached
0nil5
0nil4
0nil3
0nil2
0nil0
count
parent
nó
Conectividade em Grafos - Execução
0
1 2
3 4 5
True0nil1
False
False
False
False
False
reached
0nil5
0nil4
0nil3
0nil2
0nil0
count
parent
nó
False0nil1
False
False
True
False
False
reached
0nil5
0nil4
0nil3
0nil2
0nil0
count
parent
nó
False0nil1
False
True
False
False
False
reached
0nil5
0nil4
0nil3
0nil2
0nil0
count
parent
nó
False0nil1
True
False
False
False
False
reached
0nil5
0nil4
0nil3
0nil2
0nil0
count
parent
nó
False0nil1
False
False
False
True
False
reached
0nil5
0nil4
0nil3
0nil2
0nil0
count
parent
nó
False0nil1
False
False
False
False
True
reached
0nil5
0nil4
0nil3
0nil2
0nil0
count
parent
nó
1
1
1
1
0 0
2
2
2
43
5
Conectividade em Grafos - Execução
0
1 2
3 4 5
True0nil1
False
True
True
True
True
reached
0nil5
144
133
122
100
count
parent
nó
True111
False
False
True
False
False
reached
0nil5
0nil4
0nil3
0nil2
0nil0
count
parent
nó
True111
False
True
False
False
False
reached
0nil5
0nil4
0nil3
0nil2
0nil0
count
parent
nó
False0nil1
True
False
False
True
False
reached
0nil5
0nil4
0nil3
122
0nil0
count
parent
nó
True111
True
False
False
True
True
reached
155
0nil4
0nil3
0nil2
100
count
parent
nó
True111
False
False
False
True
True
reached
0nil5
0nil4
0nil3
122
0nil0
count
parent
nó
1
0,1
0,5
2
11
0,2,4 0,2,3
0,3,4
2
2,3,4 1,5
Conectividade em Grafos - Execução
0
1 2
3 4 5
True2nil1
True
True
True
True
True
reached
125
144
133
222
200
count
parent
nó
True111
False
True
True
True
True
reached
0nil5
114
0nil3
112
110
count
parent
nó
True111
False
True
True
True
True
reached
0nil5
0nil4
113
112
110
count
parent
nó
True121
True
False
False
True
True
reached
0nil5
0nil4
0nil3
122
120
count
parent
nó
True211
True
True
True
True
True
reached
155
114
113
1nil2
200
count
parent
nó
True211
True
True
True
True
True
reached
125
114
113
222
0nil0
count
parent
nó
2,3,4
3,4
1,5
0,2,30,2,4
5 5
0,1
5 3,4
Conectividade em Grafos - Execução
0
1 2
3 4 5
True3nil1
True
True
True
True
True
reached
225
244
233
422
400
count
parent
nó
True111
True
True
True
True
True
reached
115
114
0nil3
112
110
count
parent
nó
True111
True
True
True
True
True
reached
115
0nil4
113
112
110
count
parent
nó
True121
True
True
True
True
True
reached
0nil5
124
123
122
120
count
parent
nó
True311
True
True
True
True
True
reached
155
214
213
2nil2
300
count
parent
nó
True211
True
True
True
True
True
reached
225
214
213
222
0nil0
count
parent
nó
53,4
553,4
2
0
1
0
Conectividade em Grafos - Execução
0
1 2
3 4 5
True4nil1
True
True
True
True
True
reached
425
344
333
422
400
count
parent
nó
True111
True
True
True
True
True
reached
115
114
0nil3
112
110
count
parent
nó
True111
True
True
True
True
True
reached
115
0nil4
113
112
110
count
parent
nó
True121
True
True
True
True
True
reached
0nil5
124
123
122
120
count
parent
nó
True311
True
True
True
True
True
reached
255
314
313
3nil2
300
count
parent
nó
True211
True
True
True
True
True
reached
225
214
213
222
2nil0
count
parent
nó
5 3,4
Conectividade em Grafos - Execução
0
1 2
3 4 5
True4nil1
True
True
True
True
True
reached
425
444
433
422
400
count
parent
nó
True111
True
True
True
True
True
reached
115
114
0nil3
112
110
count
parent
nó
True111
True
True
True
True
True
reached
115
0nil4
113
112
110
count
parent
nó
True121
True
True
True
True
True
reached
0nil5
124
123
122
120
count
parent
nó
True311
True
True
True
True
True
reached
355
314
313
3nil2
300
count
parent
nó
True211
True
True
True
True
True
reached
225
214
213
222
2nil0
count
parent
nó
53 4
Conectividade em Grafos - Execução
0
1 2
3 4 5
True4nil1
True
True
True
True
True
reached
425
444
433
422
400
count
parent
nó
True111
True
True
True
True
True
reached
115
114
1nil3
112
110
count
parent
nó
True111
True
True
True
True
True
reached
115
1nil4
113
112
110
count
parent
nó
True121
True
True
True
True
True
reached
1nil5
124
123
122
120
count
parent
nó
True311
True
True
True
True
True
reached
355
314
313
3nil2
300
count
parent
nó
True211
True
True
True
True
True
reached
225
214
213
222
2nil0
count
parent
nó
Conectividade em Grafos – Implementação
#include <stdio.h>#include <mpi.h>
int numeroDeTarefas = 8;int matrizVizinhanca[8][8] = { {0,1,1,0,0,0,0,0}, {1,0,1,1,1,0,0,0}, {1,1,0,0,0,0,0,0}, {0,1,0,0,0,0,0,0}, {0,1,0,0,0,0,0,0}, {0,0,0,0,0,0,1,1}, {0,0,0,0,0,1,0,1}, {0,0,0,0,0,1,1,0}, };
Conectividade em Grafos – Implementação
/*retorna o número de vizinhos da tarefa myRank*/int contaNumeroDeVizinhos(int myRank){ int i; int contador = 0;
for (i = 0; i < numeroDeTarefas; i++) if (matrizVizinhanca[myRank][i] == 1) contador++;
return contador;}
Conectividade em Grafos – Implementação
int finaliza(int contador[], int numeroDeVizinhos, int myRank) {
int i, todosiguaisa0=1;
if(contador[myRank]!=numeroDeVizinhos) return 0;
elsereturn 1;}
Conectividade em Grafos – Implementação
/*programa principal*/int main(int argc, char** argv){
int i, j;int numeroDeVizinhos;int myRank;int source;int tag = 50;int pai[numeroDeTarefas];int contador[numeroDeTarefas];int reached[numeroDeTarefas];int id;int origem;MPI_Status status;
Conectividade em Grafos – Implementação
//inicialização do MPIMPI_Init(&argc, &argv);MPI_Comm_rank(MPI_COMM_WORLD, &myRank);
numeroDeVizinhos = contaNumeroDeVizinhos(myRank);
//inicializando variáveisfor (i=0; i<numeroDeTarefas; i++){
pai[i]=-1;contador[i]=0;reached[i]=0;
}reached[myRank]=1;
Conectividade em Grafos – Implementação
//enviando minha id para os vizinhosfor (i=0; i<numeroDeTarefas; i++){
if (matrizVizinhanca[myRank][i]==1) MPI_Send(&myRank, 1, MPI_INT, i, tag,
MPI_COMM_WORLD);}
Conectividade em Grafos – Implementação
while (!finaliza(contador, numeroDeVizinhos, myRank)){
MPI_Recv(&id, 1, MPI_INT, MPI_ANY_SOURCE, tag, MPI_COMM_WORLD, &status);
origem=status.MPI_SOURCE;contador[id]++;if (reached[id]==0) { reached[id]=1; pai[id]=origem; for (j=0; j<numeroDeTarefas; j++) if (matrizVizinhanca[myRank][j]==1 && j!=pai[id])
MPI_Send(&id, 1, MPI_INT, j, tag, MPI_COMM_WORLD);
}
Conectividade em Grafos – Implementação
if (contador[id]==numeroDeVizinhos)if (pai[id]!=-1)
MPI_Send(&id, 1, MPI_INT, pai[id], tag, MPI_COMM_WORLD);
}//imprimindo resultadoprintf("processo %d: Elementos conectados: ", myRank);for (i=0; i<numeroDeTarefas; i++)
if (contador[i]!=0) printf("%d ", i);printf("\n");fflush(stdout);
//Finalização do MPIMPI_Finalize();
}
Distância Mínima
Algoritmo SíncronoAlgoritmo Assíncrono
Distância Mínima
Ao final do algoritmo, cada nó deve conhecer a distância mais curta para cada um dos demais, e através de qual vizinho se atinge outro nó com esta distância.
0
1 2
3 4 5
225
124
123
212
111
firstdist.nó
225
414
313
212
010
firstdist.nó
234
233
232
221
220
firstdist.nó
Por exemplo, estas são as informações dos nós 0, 1 e 5.
Distância Mínima – Algoritmo Síncrono
Variáveis: dist(i) := 0; dist(k) := n para todo nó k ≠ i; first(k) = nil para todo nó k ≠ i; set = {id};
Inicio: s=0, msg(0)={} se n ∈ N(0): envie set para todos os vizinhos
Distância Mínima – Algoritmo Síncrono
Entrada: 0<s≤n-1, msg(s) com set`s recebidos de nós n(j);
set := {}; para cada set recebido em msg para cada id(k) em set se dist(k)>s dist(k) := s; first(k) := n(j); set := set U {id(k)} envie set para todos os vizinhos
Distância Mínima – Algoritmo Assíncrono
Variáveis: dist(i) := 0; dist(k) := n para todo nó k ≠ i; first(k) := nil para todo nó k ≠ i; set := {id}; level(j) := 0 para todos os vizinhos de i; state := 0; initiate := false;
Ação se n ∈ N(0): initiate := true; envie set para todos os vizinhos;
Distância Mínima – Algoritmo Assíncrono
Input: set(j); Se initiate = false initiate := true; envie set para todos os vizinhos; se state < n-1 level(j) := state + 1; para cada id(k) em set se dist(k) > level(j) dist(k) := level(j); first(k) := n(j);
Distância Mínima – Algoritmo Assíncrono
se state < level(j) para todo j vizinho state := state + 1; set := {id(k) | dist(k) = state}; envie set para todos os vizinhos;
Distância Mínima – Execução
0
1 2
3 4 5
---6nil1
---
-1
-1
-1
-1
Level
6nil5
6nil4
6nil3
6nil2
6nil0
DistFirstnó
-16nil1
---
---
---
---
---
Level
6nil5
6nil4
6nil3
6nil2
6nil0
DistFirstnó
-16nil1
---
---
---
---
---
Level
6nil5
6nil4
6nil3
6nil2
6nil0
DistFirstnó
---6nil1
---
---
---
-1
---
Level
6nil5
6nil4
6nil3
6nil2
6nil0
DistFirstnó
-16nil1
-1
---
---
---
-1
Level
6nil5
6nil4
6nil3
6nil2
6nil0
DistFirstnó
-16nil1
---
---
---
-1
---
Level
6nil5
6nil4
6nil3
6nil2
6nil0
DistFirstnó
State=0
State=0
State=0
State=0 State=0 State=0
1
1
1
1
0 0
2
2
2
43
5
Distância Mínima – Execução
0
1 2
3 4 5
---6Nil1
---
0
0
0
0
Level
6nil5
144
133
122
100
DistFirstnó
0111
---
---
---
---
---
Level
6nil5
6nil4
6nil3
6nil2
6nil0
DistFirstnó
0111
---
---
---
---
---
Level
6nil5
6nil4
6nil3
6nil2
6nil0
DistFirstnó
---6nil1
---
---
---
0
---
Level
6nil5
6nil4
6nil3
122
6nil0
DistFirstnó
0111
0
---
---
---
0
Level
155
6nil4
6nil3
6nil2
100
DistFirstnó
0111
---
---
---
0
---
Level
6nil5
6nil4
6nil3
122
6nil0
DistFirstnó
State=1
State=1
State=1
State=1 State=1 State=1
1
0,1
0,5
2
11
0,2,4 0,2,3
0,3,4
2
2,3,4 1,5
Conectividade em Grafos - Execução
0
1 2
3 4 5
2,3,4
3,4
1,5
0,2,30,2,4
5 5
0,1
5 3,4
---6Nil1
---
1
1
1
1
Level
225
144
133
122
100
DistFirstnó
1211
---
---
---
---
---
Level
6nil5
214
6nil3
612
210
DistFirstnó
1111
---
---
---
---
---
Level
6nil5
6nil4
213
212
210
DistFirstnó
---221
---
---
---
1
---
Level
6nil5
6nil4
6nil3
122
220
DistFirstnó
1111
---
---
---
1
---
Level
225
214
213
122
6nil0
DistFirstnó
State=2
State=2
State=2
State=2 State=2 State=2
1611
1
---
---
---
1
Level
655
214
213
622
600
DistFirstnó
Conectividade em Grafos - Execução
0
1 2
3 4 5
---6Nil1
---
2
2
2
2
Level
225
144
133
122
100
DistFirstnó
2211
---
---
---
---
---
Level
6nil5
214
6nil3
612
210
DistFirstnó
2111
---
---
---
---
---
Level
6nil5
6nil4
213
212
210
DistFirstnó
---221
---
---
---
2
---
Level
6nil5
6nil4
6nil3
122
220
DistFirstnó
2111
---
---
---
2
---
Level
325
314
313
122
6nil0
DistFirstnó
State=3
State=3
State=3
State=3 State=3 State=3
2611
2
---
---
---
2
Level
655
214
213
622
600
DistFirstnó
Algoritmo prossegue trocando mensagens vazias enquanto state<n-1
Distância Mínima – Implementação
#include <stdio.h>#include <mpi.h>
/*Definir o grafo da aplicação antes de executar*/int numeroDeTarefas = 6;int matrizVizinhanca[6][6] = { {0,1,1,0,0,0}, {1,0,1,1,1,0}, {1,1,0,0,0,1}, {0,1,0,0,0,0}, {0,1,0,0,0,0}, {0,0,1,0,0,0} };
Distância Mínima – Implementação
/*retorna o número de vizinhos da tarefa myRank*/int contaNumeroDeVizinhos(int myRank){
int i;int contador = 0;
for (i = 0; i < numeroDeTarefas; i++)if (matrizVizinhanca[myRank][i] == 1)
contador++;
return contador;}
Distância Mínima – Implementação
/*programa principal*/int main(int argc, char* argv[]){
int i, j, contador;int numeroDeVizinhos;int myRank;int source;int tag=50;int pai;MPI_Status status;int origem;int state;//marca o pulso atual deste processoint dist[numeroDeTarefas];//distânciaint first[numeroDeTarefas];//primeiro nó no caminho int set[numeroDeTarefas];int level[numeroDeTarefas];//pulso dos meus vizinhos
Distância Mínima – Implementação
//inicialização do MPIMPI_Init(&argc, &argv);MPI_Comm_rank(MPI_COMM_WORLD, &myRank);
numeroDeVizinhos = contaNumeroDeVizinhos(myRank);printf("iniciando...\n");fflush(stdout);//inicializando vetor dist e firstfor (i=0; i<numeroDeTarefas; i++){ dist[i]=numeroDeTarefas;//considerado como infinito
first[i]=-1;set[i]=0;level[i]=0;
}dist[myRank]=0;set[myRank]=1;state=0;
Distância Mínima – Implementação
//enviando meu conjunto para os meus vizinhosfor (i = 0; i < numeroDeTarefas; i++)
if (matrizVizinhanca[myRank][i] == 1){
//pede aos vizinhos para enviarMPI_Send(set, numeroDeTarefas, MPI_INT,
i, tag, MPI_COMM_WORLD);}
Distância Mínima – Implementação
while (state < numeroDeTarefas-1){
MPI_Recv(set, numeroDeTarefas, MPI_INT, MPI_ANY_SOURCE, tag, MPI_COMM_WORLD, &status);
origem=status.MPI_SOURCE;level[origem]++;for (i=0; i<numeroDeTarefas; i++){
if (set[i]==1){
if (dist[i]>level[origem]){
dist[i]=level[origem];first[i]=origem;
}
Distância Mínima – Implementação
//testando se meu state é menor ou igual ao //level de todos os meus vizinhosint continua=1;for (j=0; j<numeroDeTarefas; j++)if (matrizVizinhanca[myRank][j]==1 &&
state>=level[j]){
continua=0;break;
}
Distância Mínima – Implementação
if (continua){state++;//se minha distancia até j for igual a state, //então o adiciono a setfor (j=0; j<numeroDeTarefas; j++){
if (dist[j]==state)set[j]=1;
}for (j=0; j<numeroDeTarefas; j++) if (matrizVizinhanca[myRank][j]==1) MPI_Send(set, numeroDeTarefas, MPI_INT, j,
tag, MPI_COMM_WORLD);}
} } printf("processo %d: state=%d\n", myRank, state); fflush(stdout);}
Distância Mínima – Implementação
//imprimindo as distânciasprintf("processo %d: ", myRank);for (i=0; i<numeroDeTarefas; i++)
printf("dist(%d)=%d, ", i, dist[i]);printf("\n");printf("processo %d: ", myRank);for (i=0; i<numeroDeTarefas; i++)
printf("first(%d)=%d, ", i, first[i]);printf("\n");fflush(stdout);//Finalização do MPIMPI_Finalize();
}
Exercício
Desenvolva uma aplicação paralela em MPI para multiplicar duas matrizes.
Referências
[1] N. MacDonald et alli, Writing Message Passing Programs with MPI, Edinburgh Parallel Computer Centre Englewood Cliffs, NJ, Prentice--Hall, 1988[2] P. S. Pacheco, Parallel Programming with MPI, Morgan Kaufman Pub, 1997[3] Message Passing Interface Forum, MPI: A Message Passing Interface Standard, International Journal of Supercomputer Applications, vol. 8, n. 3/4, 1994[4] Valmir C. Barbosa, An Introduction to Distributed Algorithms, MIT Press, 1996[5] Nancy A. Lynch, Distributed Algorithms, Morgan Kaufman Pub, 1997[6] J. Jájá, Introduction to Parallel Algorithms, Addison-Wesley, 1992.[7] M. J. Quinn, Parallel Computing Theory and Practice, 2nd edition, McGraw-Hill, 1994.[8] Ian Foster, Designing and Building Parallel Programs, Addison-Wesley, 1995.[9] S. Akl, Parallel Computation – Models and Methods, Prentice-Hall, 1997.