PROJETO DE EXTENSÃO - EDUCAÇÃO FÍSICA BACHARELADO.pdf
Introdução ao Processamento Paralelo (3)
1. MIMD: Arquitetura x Modelo
• Troca de mensagens usualmente implementada por
processos (ex: MPI)
• Fork-join usualmente implementada por threads (ex:
OpenMP)
Memória Central Memória Distribuída
Troca de
√ √
Mensagens
Fork-Join √ X
1
III Semana Inverno Geofísica
2. Excursionando por MPI
Fontes:
Padrão MPI 1.1 em www.mpi-forum.org
Gropp, Lusk and Skjellum: “Using MPI”, 2nd edition, MIT Press, 1999
Snir, et al, “MPI – Vol 1, The MPI Core”, 2nd edition, MIT Press, 2001
Pacheco, P.: “Parallel Programming with MPI”, Morgan Kaufmann, 1997
2
III Semana Inverno Geofísica
3. MPI
• Ao paralelizar um programa, busque independências
– Independências permitirem execuções simultâneas
• MPI paraleliza processos que cooperam em uma mesma
computação, trocando mensagens quando necessário.
• Dificuldades:
– Os processos executam (usualmente) o mesmo (único) texto do
programa;
– O texto do programa divide o trabalho entre os processos
• Para reduzir o tempo de execução
– A computação é o conjunto dos processos em execução
• Para entender a computação, é necessário imaginar a execução simultânea
de cópias do texto do programa, cada cópia atuando no seu trecho do
trabalho
• Não ocorre em OpenMP
3
III Semana Inverno Geofísica
4. Programa Seqüencial
PROGRAM bobo
IMPLICIT NONE
INTEGER, PARAMETER :: tam=1000000000
REAL :: vec(tam)
INTEGER :: i
DO i = 1, tam
vec(i) = REAL(i - tam/2) ** 2
END DO
DO i = 1, tam
vec(i) = SQRT(vec(i))
END DO
WRITE(*,'(" maximo = ", f9.0,"; minimo =",f9.0)')&
MAXVAL(vec), MINVAL(vec)
END PROGRAM bobo
4
III Semana Inverno Geofísica
5. Estratégia de Paralelismo
• Dividir o trabalho dos laços de inicialização e de computação entre os
processos
– Pois as iterações desses laços são independentes
• Para tanto, basta dividir o espaço de índices dos laços. Transformar
DO i = 1, tam
vec(i) = REAL(i - tam/2) ** 2
END DO
DO i = 1, tam
vec(i) = SQRT(vec(i))
END DO
em
DO i = pri, ult
vec(i) = REAL(i - tam/2) ** 2
END DO
DO i = pri, ult
vec(i) = SQRT(vec(i))
END DO
onde os valores de pri e ult variam de processo para processo
5
III Semana Inverno Geofísica
6. MPI Versão 0
PROGRAM bobo
IMPLICIT NONE
INTEGER, PARAMETER :: tam=1000000000
REAL :: vec(tam)
REAL :: maxTot(0:7), minTot(0:7)
INTEGER :: i, pri, ult, tamLocal, ierr, numProc, esteProc, iproc
INCLUDE "mpif.h"
INTEGER :: status(MPI_STATUS_SIZE)
6
III Semana Inverno Geofísica
7. MPI Versão 0
Quantos processos
CALL MPI_INIT(ierr)
CALL MPI_COMM_SIZE(MPI_COMM_WORLD, numProc , ierr)
CALL MPI_COMM_RANK(MPI_COMM_WORLD, esteProc, ierr)
tamLocal = tam/numProc
pri = esteProc*tamLocal + 1
IF (esteProc == numProc-1) THEN Número deste
ult = tam Processo (0:numProc-1)
ELSE
ult = (esteProc+1)*tamLocal
Divisão de Domínio:
END IF
DO i = pri, ult Índices do laço
vec(i) = REAL(i - tam/2) ** 2 divididos entre os processos
END DO Resto no último processo
DO i = pri, ult
vec(i) = SQRT(vec(i))
END DO
7
III Semana Inverno Geofísica
8. MPI Versão 0
maxTot(esteProc) = MAXVAL(vec(pri:ult))
minTot(esteProc) = MINVAL(vec(pri:ult))
IF (esteProc /= 0) THEN
CALL MPI_SEND(maxTot(esteProc), 1, MPI_REAL, 0, &
12, MPI_COMM_WORLD, ierr)
CALL MPI_SEND(minTot(esteProc), 1, MPI_REAL, 0, &
13, MPI_COMM_WORLD, ierr)
ELSE
DO iProc = 1, numProc-1
CALL MPI_RECV(maxTot(iProc), 1, MPI_REAL, &
MPI_ANY_SOURCE, 12, MPI_COMM_WORLD, status, ierr)
CALL MPI_RECV(minTot(iProc), 1, MPI_REAL, &
MPI_ANY_SOURCE, 13, MPI_COMM_WORLD, status, ierr)
END DO
END IF
8
III Semana Inverno Geofísica
9. MPI Versão 0
IF (esteProc == 0) THEN
WRITE(*,'(" maximo = ", f12.0,"; minimo =",f12.0)')&
MAXVAL(maxTot(0:numProc-1)), &
MINVAL(minTot(0:numProc-1))
END IF
CALL MPI_FINALIZE(ierr)
END PROGRAM bobo
9
III Semana Inverno Geofísica
10. MPI – Versão 0
Processos Tempo CPU (s) Speed-up
1 167,87 1,00
2 84,78 1,98
3 56,90 2,95
4 --- ---
5 --- ---
6 --- ---
10
III Semana Inverno Geofísica
11. MPI Versão 0
• A Versão 0 usa, por processo, a mesma quantidade de memória do
programa seqüencial
– Os p processos da Versão 0 do programa MPI usam, no total, p vezes
a memória do programa seqüencial.
– Pode esgotar a memória em máquinas de memória central (como no
exemplo)
• Para que o programa paralelo use (aproximadamente) a mesma
quantidade de memória do programa seqüencial, é necessário
reescrever o seqüencial alocando a cada processo apenas a
memória necessária
• Tipicamente, duas formas:
1. Mantém os índices do programa seqüencial e aloca os objetos apenas
nos índices necessários;
– Trivial em Fortran
2. Mapeia os índices do programa seqüencial em 1:N (ou 0:N-1), onde N
é o tamanho do domínio neste processo;
– Translação de indices (indice global = indice local + deslocamento)
11
III Semana Inverno Geofísica
12. Dificuldades da forma 2
• Dificuldade 1: particionar o vetor entre os
processos para reduzir memória
• Vec(1:tamLocal) vai representar o trecho pri:ult do
vetor global “vec”
• Dificuldade 2: Ao particionar o vetor, mudam os
índices (há índices locais ao processo que
representam índices globais ao objeto)
• No laço abaixo, i é índice global, mas Vec será
indexado por índices locais (problema na expressão
no lado direito da atribuição)
DO i = 1, tamLocal
vec(i) = REAL(i - tam/2) ** 2
END DO
Indice local Indice global
12
III Semana Inverno Geofísica
13. Particionar Objetos
• Para reduzir a memória é necessário particionar os objetos entre os
processos
• MPI cria nProc processos, numerados de 0 a nProc-1
• Particionar array de tamanho tam entre nProc processos:
tamLocal = tam/nProc
resto = tam – tamLocal*nProc
If (esteProc < resto) then
tamLocal = tamLocal+1
end if
• Exemplo tam=10 nProc=4
Proc 0 Proc 1 Proc 2 Proc 3
tamLocal 3 tamLocal 3 tamLocal 2 tamLocal 2
13
III Semana Inverno Geofísica
14. Índices Locais e Globais
• Array global indexado 1:tam
• Array local indexado 1:tamLocal
• Indice global = indice local + deslocamento
tamLocal = tam/nProc
resto = tam – tamLocal*nProc
If (esteProc < resto) then
tamLocal = tamLocal+1
desloc = esteProc * tamLocal
else
desloc = esteProc*tamLocal + resto
end if
• Ex: tam=10, nProc=4
Índice global 1 2 3 4 5 6 7 8 9 10
Índice local 1 2 3 1 2 3 1 2 1 2
Proc 0 Proc 1 Proc 2 Proc 3
deslocamento 0 3 6 8
tamLocal3 tamLocal3 tamLocal2 tamLocal2
14
III Semana Inverno Geofísica
15. MPI Versão 1
PROGRAM bobo
IMPLICIT NONE
INTEGER, PARAMETER :: tam=1000000000
REAL, ALLOCATABLE :: vec(:)
REAL :: maxTot(0:7), minTot(0:7)
INTEGER :: i, tamLocal, resto, ierr, numProc, esteProc, iproc
INCLUDE "mpif.h"
INTEGER :: status(MPI_STATUS_SIZE)
15
III Semana Inverno Geofísica
16. MPI Versão 1
CALL MPI_INIT(ierr)
CALL MPI_COMM_SIZE(MPI_COMM_WORLD, numProc , ierr)
CALL MPI_COMM_RANK(MPI_COMM_WORLD, esteProc, ierr)
tamLocal = tam/numProc
resto = tam – tamLocal * numProc
IF (esteProc < resto) THEN
tamLocal=tamLocal+1; ult = tamLocal; desloc=esteProc*tamLocal
ELSE
desloc=esteProc*tamLocal + resto
END IF
ALLOCATE(vec(tamLocal))
DO i = 1, tamLocal
vec(i) = REAL(i+desloc - tam/2) ** 2
END DO
DO i = 1, tamLocal
vec(i) = SQRT(vec(i))
END DO
16
III Semana Inverno Geofísica
17. MPI Versão 1
maxTot(esteProc) = MAXVAL(vec(tamLocal))
minTot(esteProc) = MINVAL(vec(tamLocal))
IF (esteProc /= 0) THEN
CALL MPI_SEND(maxTot(esteProc), 1, MPI_REAL, 0, &
12, MPI_COMM_WORLD, ierr)
CALL MPI_SEND(minTot(esteProc), 1, MPI_REAL, 0, &
13, MPI_COMM_WORLD, ierr)
ELSE
DO iProc = 1, numProc-1
CALL MPI_RECV(maxTot(iProc), 1, MPI_REAL, &
MPI_ANY_SOURCE, 12, MPI_COMM_WORLD, status, ierr)
CALL MPI_RECV(minTot(iProc), 1, MPI_REAL, &
MPI_ANY_SOURCE, 13, MPI_COMM_WORLD, status, ierr)
END DO
END IF
17
III Semana Inverno Geofísica
18. MPI Versão 1
IF (esteProc == 0) THEN
WRITE(*,'(" maximo = ", f12.0,"; minimo =",f12.0)')&
MAXVAL(maxTot(0:numProc-1)), &
MINVAL(minTot(0:numProc-1))
END IF
CALL MPI_FINALIZE(ierr)
END PROGRAM bobo
18
III Semana Inverno Geofísica
19. MPI – Versão 1
Processos Tempo CPU (s) Speed-up Eficiência
1 167,87 1,00 100,00%
2 84,78 1,98 99,00%
3 56,90 2,95 98,33%
4 43,37 3,87 96,75%
5 35,26 4,76 95,20%
6 30,19 5,56 92,16%
19
III Semana Inverno Geofísica
20. Conclusões da Excursão Inicial
• Paralelismo MPI explora independências no algoritmo
– Enquanto OpenMP explora independências na codificação
• Ou seja, o volume de trabalho para paralelizar um programa
seqüencial em OpenMP depende do algoritmo (como MPI) e de
detalhes da codificação seqüencial
• Ao contrário de OpenMP, paralelismo MPI muda
substancialmente o programa, pois requer:
– Dividir o trabalho explicitamente
– Dividir a memória explicitamente
• Entretanto, aplica-se a máquinas de memória central,
memória distribuída e clusters
20
III Semana Inverno Geofísica
22. Padrão MPI
• Implementa o modelo de troca de mensagens por
chamadas a biblioteca de procedimentos padronizada
– esconde “detalhes” da comunicação entre processos
• Padrão de facto (www.mpi-forum.org)
• Construído pela necessidade de portabilidade de
programas paralelos, quando haviam múltiplas
implementações proprietárias e não padronizadas de
bibliotecas de troca de mensagens
• Esforço comunitário:
– grupos de usuários, acadêmicos e indústria
– 1992-1998: MPI-1 e MPI-2
– 2008-...: MPI-3 em elaboração
22
III Semana Inverno Geofísica
23. Compilação de programas MPI
• Padrão MPI não define como compilar programas MPI
(pois depende do Sistema Operacional)
• Implementações de MPI tipicamente fornecem scripts
para compilação
• Para compilar programa MPI Fortran no LINUX:
Use mpif90 (script que invoca f90 com chaves MPI)
Aceita demais chaves de compilação de f90
• Para compilar programa MPI C no LINUX:
Use mpicc (script que invoca cc com chaves MPI)
Aceita demais chaves de compilação de cc
23
III Semana Inverno Geofísica
24. Execução de programas MPI
• Padrão MPI não define como executar programas MPI
(pois depende do Sistema Operacional)
• Implementações de MPI tipicamente fornecem scripts
para execução. Na implementação MPICH no Linux:
mpirun <argumentos> <executável>
• Múltiplos argumentos. Dentre os principais:
1. Número de processos na execução (obrigatório):
-np < número de processos>
2. Em que máquinas os processos são criados (opcional, há
default):
-machinefile <arquivo>
24
III Semana Inverno Geofísica
25. Índice do Padrão MPI
1. Introduction to MPI 1
2. MPI Terms and Conventions 6
3. Point-to-Point Communication 16
4. Collective Communication 91
5. Groups, Contexts and Communicators 132
6. Process Topologies 176
7. MPI Environmental Management 191
8. Profiling Interface 201
Bibliography 207
A. Language Binding 210
MPI Function Index 230
25
III Semana Inverno Geofísica
27. Constantes Simbólicas MPI
• Implementações de MPI fornecem arquivos com
constantes simbólicas
• Para incluir constantes simbólicas MPI em programas
Fortran:
– include “mpif.h”, ou use mpi
– Linhas do arquivo mpif.h:
INTEGER, PARAMETER :: MPI_SUCCESS=0
INTEGER, PARAMETER :: MPI_COMM_WORLD=90
• Similar em C
27
III Semana Inverno Geofísica
28. MPI:
Manejo do Ambiente
28
III Semana Inverno Geofísica
29. Manejo do ambiente
• Inicia a computação MPI:
C: int MPI_Init (int *argc, char ***argv)
Fortran: MPI_INIT (ierr)
integer, intent(out) :: ierr
• Inscreve o processo na computação MPI
• Término ordenado da computação MPI:
C: int MPI_Finalize(void)
Fortran: MPI_FINALIZE (ierr)
integer, intent(out) :: ierr
• Ultimo procedimento MPI a invocar
• Uso típico:
– MPI_Init o mais próximo possível ao primeiro comando do programa
– MPI_Finalize é o último comando do programa
29
III Semana Inverno Geofísica
30. Manejo do ambiente
• Quantos processos em um comunicador: (size)
C: int MPI_Comm_size(MPI_Comm comm, int *size)
Fortran: MPI_COMM_SIZE (comm, size, ierr)
integer, intent(in) :: comm
integer, intent(out) :: size
integer, intent(out) :: ierr
• Qual é o número deste processo no comunicador: (id)
C: int MPI_Comm_rank (MPI_Comm comm, int * id)
Fortran: MPI_COMM_RANK (comm, id, ierr)
integer, intent(in) :: comm
integer, intent(out) :: id
integer, intent(out) :: ierr
• Tipicamente (em C):
MPI_Comm_size(MPI_COMM_WORLD, size);
MPI_Comm_rank(MPI_COMM_WORLD, id);
30
III Semana Inverno Geofísica
31. MPI:
Comunicação Ponto a
Ponto
Bloqueante
31
III Semana Inverno Geofísica
32. Comunicação Ponto a Ponto
• Processos trocam mensagens contendo dados
• Um processo solicita o envio de uma mensagem para
outro processo (MPI_SEND)
• Outro processo solicita a recepção de uma mensagem
do primeiro (MPI_RECV)
• Mensagem composta por
– Envelope
– Dados
32
III Semana Inverno Geofísica
33. Comunicação Ponto a Ponto:
Envelope
• Envelope da mensagem:
– Identificação do comunicador MPI
– Identidade (no comunicador MPI) do processo que
envia;
– Identidade (no comunicador MPI) do processo que
recebe;
– Tag (inteiro identificador da mensagem)
33
III Semana Inverno Geofísica
34. Comunicação ponto a ponto: Dados
• Dados a trafegar:
– Os valores:
• Endereço da primeira posição de buffer na memória
• O buffer é o espaço de posições contíguas de memória que
contém:
– A seqüência de valores a enviar, ou
– Espaço para armazenar os valores recebidos
– O tamanho de buffer:
• Quantos valores do tipo MPI (não quantos bytes)
• Inteiro não negativo, permitindo mensagens vazias
– O tipo MPI dos valores comunicados:
• Mesmo tipo para todos os valores
34
III Semana Inverno Geofísica
35. Tipos de Dados MPI e Fortran
MPI Fortran
MPI_INTEGER INTEGER
MPI_REAL REAL
MPI_DOUBLE_PRECISION DOUBLE PRECISION
MPI_COMPLEX COMPLEX
MPI_LOGICAL LOGICAL
MPI_CHARACTER CHARACTER(1)
MPI_BYTE
MPI_PACKED
35
III Semana Inverno Geofísica
36. Tipos de Dados MPI e C
MPI C
MPI_INT signed int
MPI_SHORT signed short int
MPI_LONG signed long int
MPI_UNSIGNED unsigned int
MPI_UNSIGNED_SHORT unsigned short int
MPI_UNSIGNED_LONG unsigned long int
MPI_FLOAT float
MPI_DOUBLE double
MPI_LONG_DOUBLE long double
MPI_CHAR signed char
MPI_UNSIGNED_CHAR unsigned char
MPI_BYTE
MPI_PACKED
36
III Semana Inverno Geofísica
37. Envio Bloqueante de Mensagem
MPI_Send (buf, cnt, datatype, dest, tag, comm, ierr)
<type>, intent(in) :: buf(:) Primeira posição dos dados a enviar
integer, intent(in) :: cnt Quantos dados a enviar (≥0);
Size(buf) ≥ cnt; posições contíguas
integer, intent(in) :: datatype Tipo MPI dos dados a enviar
integer, intent(in) :: dest Número do processo a receber a
mensagem (no comunicador)
integer, intent(in) :: tag Identificador da mensagem (≥0 e
≤MPI_TAG_UB)
integer, intent(in) :: comm Comunicador da mensagem
integer, intent(out) :: ierr Código de retorno
37
III Semana Inverno Geofísica
38. Recepção Bloqueante de
Mensagem
MPI_Recv (buf, cnt, datatype, src, tag, comm, status, ierr)
<type>, intent(out) :: buf(:) Primeira posição dos dados a receber
integer, intent(in) :: cnt Tamanho de buf (≥0); recebe ≤ cnt
elementos ou reporta “overflow”
integer, intent(in) :: datatype Tipo MPI dos dados a receber
integer, intent(in) :: src Número do processo que a mensagem (no
comunicador)
integer, intent(in) :: tag Identificador da mensagem (≥0 e
≤MPI_TAG_UB)
integer, intent(in) :: comm Comunicador da mensagem
integer, intent(out) :: Informações sobre a mensagem recebida
status(MPI_STATUS_SIZE)
integer, intent(out) :: ierr Código de retorno
38
III Semana Inverno Geofísica
39. Tamanho da Mensagem
• Semântica de cnt:
– O padrão afirma que cnt é o número de elementos em bfr, mas:
• Em SEND, cnt é a quantidade de dados a enviar;
– Logo, size(buf) ≥ cnt;
• Em RECV, cnt é o tamanho de buf
– o número de elementos recebidos é ≤ cnt
39
III Semana Inverno Geofísica
40. Seleção da Mensagem a Receber
• Dentre as mensagens existentes, MPI seleciona a
mensagem correspondente a um dado MPI_RECV se e
somente se:
– O comunicador da mensagem é o mesmo do RECV;
– A mensagem é enviada para o processo que emite o RECV;
– O tag da mensagem está de acordo com o tag do RECV;
– O processo que envia a mensagem está de acordo com o src do
RECV
• Observe que:
– Nenhuma informação sobre os dados é utilizada para escolher a
mensagem a receber;
– Um processo pode enviar mensagem para ele mesmo.
40
III Semana Inverno Geofísica
41. MPI:
Modos de Comunicação
41
III Semana Inverno Geofísica
42. Modos de Comunicação Ponto a
Ponto
• Os dois principais modos de comunicação ponto
a ponto de MPI são:
– Comunicação síncrona (synchronous)
– Comunicação assíncrona (buffered)
– Há outros...
• Os dois modos diferem em:
– Obrigatoriedade do par SEND-RECV ter sido emitido
(sincronização ou não)
– O que significa a invocação a SEND ou a RECV
42
III Semana Inverno Geofísica
43. Comunicação Síncrona
• MPI copia os dados (e envia a mensagem) diretamente
para o bfr do receptor
• SEND termina apenas quando o receptor recebe a
mensagem (e avisa o emissor)
• RECV termina apenas quando os dados estão no
próprio bfr
• Características:
– Mensagem não local no processo que emite o SEND;
– Possibilita sincronização, pois SEND termina apenas após a
recepção correspondente terminar;
– Usa pouca memória (não há buffer intermediário); minimiza
cópias
43
III Semana Inverno Geofísica
44. Comunicação Assíncrona
• MPI copia bfr do SEND para outro armazém local e
envia o novo armazém para o processo destino
• SEND termina quando dados do seu próprio bfr forem
copiados para o armazém
• RECV termina apenas quando os dados estão no
próprio bfr
• Características:
– Mensagem local no processo que emite o SEND;
– Não há sincronização (a recepção correspondente não precisa
ter começado para o SEND terminar)
– Requer mais memória (e cópias) que o modo síncrono
44
III Semana Inverno Geofísica
45. Semântica de MPI_SEND,
MPI_RECV
• O mesmo MPI_RECV é utilizado para comunicação
síncrona e assíncrona
– Diferença apenas no SEND
• MPI possui rotinas específicas para SEND síncrono e
para SEND assíncrono; MPI_SEND não é nenhuma
delas
• MPI_SEND e MPI_RECV utilizam terceiro modo de
comunicação, denominado padrão (“standard”)
45
III Semana Inverno Geofísica
46. Modo Padrão
• Uma implementação de MPI é livre para escolher entre
comunicação síncrona e assíncrona na implementação
de MPI_SEND
• Motivo: Para garantir a correção de programas portáteis, não é
possível obrigar qualquer sistema a possuir memória suficiente
para comunicação assíncrona.
• Ao deixar a comunicação síncrona ou assíncrona a
critério da implementação, MPI impõe semântica a
MPI_SEND e MPI_RECV tal que:
• Semântica correta em qualquer dos dois modos
• Permite uma implementação escolher, dinamicamente, um dos
modos de comunicação dependendo das circunstâncias
• Permite que a implementação melhore o desempenho do
programa, se há espaço suficiente para comunicação assíncrona
• Mantém correção de programas portáteis.
46
III Semana Inverno Geofísica
47. Semântica de MPI_SEND
• O MPI_SEND é bloqueante.
– Retorna apenas quando os dados e o envelope forem salvos em
algum outro lugar
– Consequentemente, ao retornar de MPI_SEND, o bfr pode ser
re-escrito
• O término de MPI_SEND não garante que a mensagem
chegou ao destino, mas
• O término de MPI_SEND pode requerer o término do
MPI_RECV correspondente.
47
III Semana Inverno Geofísica
48. Semântica de MPI_RECV
• O MPI_RECV é bloqueante.
– Retorna apenas quando os dados e o envelope enviados
chegaram ao destino
– Consequentemente, ao retornar de MPI_RECV, o bfr contém os
dados a receber
• O término de MPI_RECV garante que o MPI_SEND
correspondente foi iniciado e enviou os dados
• O término de MPI_RECV requer o início do MPI_SEND
correspondente (mas não garante que o MPI_SEND
terminou).
48
III Semana Inverno Geofísica
49. Sumário
• A semântica do modo padrão de comunicação MPI não
é baseada no sincronismo (ou não) da operação; é
baseada no reuso do bfr
– MPI_SEND termina apenas quando o bfr pode ser reusado;
– MPI_RECV termina apenas quando o bfr foi recebido.
• Para garantir a correção de um programa MPI, é
necessário:
– Garantir que pares MPI_SEND e MPI_RECV correspondentes
possam ser executados simultaneamente, ou seja, que nenhum
fluxo de execução impeça a execução de um dos dois
49
III Semana Inverno Geofísica
50. Problema Clássico: Deadlock
Escreva um programa com dois processos
MPI no qual cada processo envia seu
número (identidade) no comunicador para
o outro processo.
50
III Semana Inverno Geofísica
51. Deadlock Versão 1
program deadlock ! 2 processos!!!
implicit none
include “mpif.h”
integer :: nProc, esteProc, outroProc
integer :: ierr
integer :: status(MPI_STATUS_SIZE)
call MPI_INIT (ierr)
call MPI_COMM_SIZE (MPI_COMM_WORLD, nProc, ierr)
call MPI_COMM_RANK (MPI_COMM_WORLD, esteProc, ierr)
call MPI_RECV (outroProc, 1, MPI_INTEGER, mod(esteProc+1,2),
10, MPI_COMM_WORLD, status, ierr)
call MPI_SEND (esteProc, 1, MPI_INTEGER, mod(esteProc+1, 2),
10, MPI_COMM_WORLD, ierr)
print *, “este e outro proc =“, esteProc, outroProc
call MPI_FINALIZE (ierr)
end program deadlock
51
III Semana Inverno Geofísica
52. Erro em Deadlock Versão 1
• Os dois processos esperam eternamente em
MPI_RECV, pois os MPI_SEND correspondentes não
são executados.
• O programa não garante que os pares SEND – RECV
correspondentes sejam executados
– pois a execução do MPI_SEND pressupõe o término da
execução do MPI_RECV anterior.
52
III Semana Inverno Geofísica
54. Deadlock Versão 2
(inverte a ordem de SEND e RECV)
program deadlock
implicit none
include “mpif.h”
integer :: nProc, esteProc, outroProc
integer :: ierr
integer :: status(MPI_STATUS_SIZE)
call MPI_INIT (ierr)
call MPI_COMM_SIZE (MPI_COMM_WORLD, nProc, ierr)
call MPI_COMM_RANK (MPI_COMM_WORLD, esteProc, ierr)
call MPI_SEND (esteProc, 1, MPI_INTEGER, mod(esteProc+1, 2),
10, MPI_COMM_WORLD, ierr)
call MPI_RECV (outroProc, 1, MPI_INTEGER, mod(esteProc+1,2),
10, MPI_COMM_WORLD, status, ierr)
print *, “este e outro proc =“, esteProc, outroProc
call MPI_FINALIZE (ierr)
end program deadlock
54
III Semana Inverno Geofísica
55. Erro em Deadlock Versão 2
• A semântica do par MPI_SEND e MPI_RECV não
garante que MPI_SEND seja executado sem que o
MPI_RECV correspondente seja emitido.
• Os dois processos podem esperam eternamente em
MPI_SEND, pois os MPI_RECV correspondentes
podem não são executados, caso a implementação MPI
escolha utilizar o modo síncrono de comunicação.
• O programa não garante que os pares SEND – RECV
correspondentes (tag 10) sejam executados
– pois a execução do MPI_SEND pode requerer o início da
execução do MPI_RECV posterior.
55
III Semana Inverno Geofísica
57. Versão sem Deadlock
if (esteProc == 0) then
call MPI_RECV (outroProc, 1, MPI_INTEGER,
mod(esteProc+1,nProc), 10, MPI_COMM_WORLD, status, ierr)
call MPI_SEND (esteProc, 1, MPI_INTEGER, mod(esteProc+1,
nProc), 20, MPI_COMM_WORLD, ierr)
else
call MPI_SEND (esteProc, 1, MPI_INTEGER, mod(esteProc+1,
nProc), 10, MPI_COMM_WORLD, ierr)
call MPI_RECV (outroProc, 1, MPI_INTEGER,
mod(esteProc+1,nProc), 20, MPI_COMM_WORLD, status, ierr)
end if
57
III Semana Inverno Geofísica
58. Porque versão correta?
• Versão correta apenas para 2 processos
– Mecanismo conhecido como red-black ordering
– Pode ser estendido para pares de processos
• O par SEND-RECV com tag 10 é executado
“simultaneamente”; não pressupõe nada sobre a forma
de comunicação.
• O par SEND-RECV com tag 20 também é executado
“simultaneamente”; só pressupõe que o par SEND-
RECV anterior termina.
• Obs: tags 10 e 20 apenas por razões didáticas; os dois
tags poderiam ser os mesmos.
58
III Semana Inverno Geofísica
60. Sumário
• Compilação e Execução de Programas MPI
• Comunicador MPI
• Manejo do ambiente MPI
• Mensagem: Envelope e Dados
• Comunicação Ponto a Ponto Bloqueante
• Modos de Comunicação:
– Síncrona
– Assíncrona
– Padrão
• Deadlock
60
III Semana Inverno Geofísica
61. MPI:
Comunicação Ponto a Ponto
Não Bloqueante
61
III Semana Inverno Geofísica
62. Para que Comunicação Não
Bloqueante?
• Para evitar “deadlocks”
– SENDs e RECVs bloqueantes geram deadlock
• Para permitir simultaneidade entre computação
e comunicação
– Impedido por comunicações bloqueantes
62
III Semana Inverno Geofísica
63. Modelo de Comunicação Não
Bloqueante
1. Processo requisita o início da comunicação invocando
Isend ou Irecv
2. MPI inicia a comunicação e retorna controle ao
processo
3. Processo continua sua computação enquanto MPI
executa a comunicação
4. Quando conveniente, o processo:
– Invoca Wait para aguardar o fim da comunicação, ou
– Invoca Test para investigar o fim da comunicação
63
III Semana Inverno Geofísica
64. Requisições
• Como relacionar as duas partes da comunicação
(requisição, investigação) ?
– Ou seja, o par (ISEND/IRECV, WAIT/TEST)?
– Podem haver múltiplas comunicações pendentes
– Logo, múltiplos pares (ISEND/IRECV, WAIT/TEST)
• A operação que requer a comunicação retorna um
identificador da requisição denominado “request”
• A operação que aguarda/investiga o fim da comunicação
utiliza, como argumento de entrada, o “request”
• Ao término da comunicação, o “request” recebe o valor
MPI_REQUEST_NULL
64
III Semana Inverno Geofísica
65. Requisita Envio Não Bloqueante
MPI_Isend (buf, cnt, datatype, dest, tag, comm, request, ierr)
<type>, intent(in) :: buf(:) Primeira posição dos dados a enviar
integer, intent(in) :: cnt Quantos dados a enviar (≥0);
Size(buf) ≥ cnt
integer, intent(in) :: datatype Tipo MPI dos dados a enviar
integer, intent(in) :: dest Número do processo a receber a
mensagem (no comunicador)
integer, intent(in) :: tag Identificador da mensagem (≥0 e
≤MPI_TAG_UB)
integer, intent(in) :: comm Comunicador da mensagem
integer, intent(out) :: request Identificador da comunicação
Integer, intent(out) :: ierr Código de retorno
65
III Semana Inverno Geofísica
66. Requisita Recepção Não Bloqueante
MPI_Irecv (buf, cnt, datatype, src, tag, comm, request, ierr)
<type>, intent(out) :: buf(:) Primeira posição dos dados a receber
integer, intent(in) :: cnt Tamanho de buf (≥0); recebe ≤ cnt
elementos ou reporta “overflow”
integer, intent(in) :: datatype Tipo MPI dos dados a receber
integer, intent(in) :: src Número do processo que a mensagem (no
comunicador)
integer, intent(in) :: tag Identificador da mensagem (≥0 e
≤MPI_TAG_UB)
integer, intent(in) :: comm Comunicador da mensagem
integer, intent(out) :: request Identificador da comunicação
integer, intent(out) :: ierr Código de retorno
66
III Semana Inverno Geofísica
67. Espera Bloqueante do Término da
Mensagem
MPI_Wait (request, status, ierr)
Identificador da
integer, intent(inout) :: request
comunicação
Informações sobre a
integer, intent(out) :: status(mpi_status_size)
comunicação
integer, intent(out) :: ierr Código de retorno
• Espera até que a mensagem termine
• No retorno, request = MPI_REQUEST_NULL
67
III Semana Inverno Geofísica
68. Investigação do Término da Mensagem
MPI_Test (request, flag, status, ierr)
Identificador da
integer, intent(inout) :: request
comunicação
Operação completa ou
logical, intent(out) :: flag
incompleta
Informações sobre a
integer, intent(out) :: status(mpi_status_size)
comunicação
integer, intent(out) :: ierr Código de retorno
• Retorna, em flag, se comunicação terminou ou não
• Não bloqueante
• Se operação completa, request retorna MPI_REQUEST_NULL
68
III Semana Inverno Geofísica
69. Semântica da Comunicação Não
Bloqueante
• O retorno de IRECV/ISEND indica:
– O início da comunicação solicitada
– Que buf não pode ser usado/modificado
– Nada sobre a comunicação correspondente à solicitada
• O retorno de WAIT indica
– Término da comunicação solicitada
– Que buf já pode ser usado/modificado
– Se a comunicação foi solicitada por IRECV, indica que o ISEND correspondente
começou
– Se a comunicação foi solicitada por ISEND, nada indica sobre o IRECV
correspondente
• O retorno de TEST com flag=.true. tem a mesma semântica que o retorno
de WAIT
• O retorno de TEST com flag=.false. Indica:
– Que a comunicação não terminou
– Que buf ainda não pode ser usado/modificado
– Nada sobre a comunicação correspondente III Semana Inverno Geofísica
69
70. Exemplo
• Escreva um programa com dois processos MPI no qual
cada processo envia seu número (identidade) no
comunicador para o outro processo.
• A identidade do processo é esteProc
• A identidade do outro processo é outroProc
70
III Semana Inverno Geofísica
71. Exemplo (fração do programa)
call MPI_IRECV (outroProc, 1, MPI_INTEGER, mod(esteProc+1,2), 10,
MPI_COMM_WORLD, request1, ierr)
call MPI_ISEND (esteProc, 1, MPI_INTEGER, mod(esteProc+1, 2), 10,
MPI_COMM_WORLD, request2, ierr)
flag1=.false.; flag2=.false.
do
if (.not. flag1) call MPI_TEST(request1, flag1, status, ierr)
if (.not. flag2) call MPI_TEST(request2, flag2, status, ierr)
if (flag1 .and. flag2) exit
end do
Livre de Deadlock!!!
71
III Semana Inverno Geofísica
72. Outras operações não bloqueantes
• Há muitas outras operações
• MPI_WAITALL, MPI_WAITANY, MPI_WAITSOME
– Aguarda todas, qualquer uma, algumas comunicações
• Idem para TEST
• Etc...
72
III Semana Inverno Geofísica
73. MPI:
Comunicações Coletivas
73
III Semana Inverno Geofísica
74. Comunicações Coletivas
• Uma comunicação coletiva envolve múltiplos processos.
• Todos os processos do comunicador emitem a mesma
operação
• O término indica que o processo pode acessar ou alterar
o buffer de comunicação
• Veremos apenas uma de 16 operações
74
III Semana Inverno Geofísica
75. Comunicações Coletivas:
BARREIRA
MPI_Barrier (comm, ierr)
– Integer, intent(in) :: comm
– Integer, intent(out) :: ierr
• Todos os processos que invocam MPI_BARRIER são
bloqueados até que todos os processos do comunicador
invoquem a barreira.
• Sincroniza todos os processos do comunicador
• Cuidado: garanta que todos os processos no
comunicador invoquem a barreira
75
III Semana Inverno Geofísica
76. Sumário MPI
• MPI implementa modelo de troca de mensagens
• Espaço de endereçamento distintos
• Para reduzir memória, é necessário mapear índices e
re-escrever o programa
• Índice global = índice local + deslocamento
• Troca de mensagens bloqueante pode gerar deadlock
• Garanta que pares send/recv correspondentes possam ser
executados simultaneamente
• Outra possibilidade: troca de mensagens não
bloqueante
76
III Semana Inverno Geofísica