MIMD: Arquitetura x Modelo    • Troca de mensagens usualmente implementada por      processos (ex: MPI)    • Fork-join usu...
Excursionando por                        OpenMPFontes:• Padrão OpenMP em www.openmp.org• Chandra, Menon, Dagum, Kohr: “Par...
Padrão OpenMP    • Padrão de facto (www.openmp.org) com interfaces para      C, C++ e Fortran    • O padrão é emitido pelo...
Padrão OpenMP    • Implementa o modelo fork-join de paralelismo por meio      de diretivas (comentários identificados), va...
Padrão OpenMP    • Use a chave de compilação que “liga” OpenMP        • chave não padronizada, varia de compilador para co...
OpenMP    • Ao paralelizar um programa, busque independências       – Independências permitirem execuções simultâneas    •...
Programa Sequencial    PROGRAM simple                                   Constantes simbólicas e     USE omp_lib           ...
OpenMP Versão 0    PROGRAM simple     USE omp_lib     IMPLICIT NONE     INTEGER, PARAMETER :: vSize=1000000000     REAL ::...
OpenMP Versão 0    Procs       Tempo (s)   Speed-up     1           167,87       1,00     2           128,20       1,31   ...
OpenMP Versão 0 – O que falta?         PROGRAM simple          USE omp_lib          IMPLICIT NONE          INTEGER, PARAME...
OpenMP Versão 1     PROGRAM simple      USE omp_lib      IMPLICIT NONE      INTEGER, PARAMETER :: vSize=1000000000      RE...
OpenMP Versão 1      Procs   Speed-up       1       1,00       2       1,41       3       1,83       4       2,07       5 ...
OpenMP Versão 1 – O que falta?         PROGRAM simple          USE omp_lib          IMPLICIT NONE          INTEGER, PARAME...
Medindo Tempo de Execução                 Trecho        % Tempo Exec              Initialização         7,79              ...
Como Paralelizar a Escrita?       PROGRAM simple         USE omp_lib         IMPLICIT NONE         INTEGER, PARAMETER :: v...
OpenMP Versão 2     PROGRAM simple      USE omp_lib      IMPLICIT NONE      INTEGER, PARAMETER :: vSize=1000000000      RE...
OpenMP Versão 2 - Detalhe                    REAL :: ... maxTot(0:7), minTot(0:7)                    maxTot = -1.0; minTot...
OpenMP – Versão 2      Procs   Speed-up        1      1,00        2      2,00        3      2,99        4      3,98       ...
Conclusões da Excursão Inicial     • Paralelismo OpenMP explora independências na       codificação do programa        – P...
Detalhando      OpenMP20                  III Semana Inverno Geofísica
Elementos de OpenMP     1.       Diretivas          •     Sintaxe          •     Região Paralela          •     Cooperação...
Sintaxe das Diretivas em Fortran     • Sintaxe:            !$OMP nome-da-diretiva <lista-de-clausulas>       onde         ...
Sintaxe das Diretivas em C e C++     • Sintaxe:            #pragma omp nome-da-diretiva <lista-de-clausulas> new-line     ...
Elementos de OpenMP     1.       Diretivas          •     Sintaxe          •     Região Paralela          •     Cooperação...
Região Paralela     •   Fortran:                 !$OMP PARALLEL <lista-de-clausulas>                 <structured-block>   ...
Modelo de Execução     •   OpenMP implementa o modelo fork-join de execução         paralela:         1. Um programa OpenM...
Número de Threads     •   A função OMP_GET_NUM_THREADS() retorna o número de         threads do time atualmente em execuçã...
Exemplo em C     #include <omp.h>     #include <stdio.h>     void main(){     #pragma omp parallel         {         if (o...
Exemplo com 8 threads          Sou thread 0 diferente          Sou thread 2 igual          Sou thread 3 igual          Sou...
Implementação Típica     •   O corpo da região paralela é transformado em um         procedimento     •   O início da regi...
Exemplo 1     • O que é impresso, supondo 8 threads?                 PROGRAM nbr1                 USE omp_lib             ...
Três Execuções     thread 5; m=18     thread 7; m=14     thread 6; m=16     thread 1; m=18     thread 2; m=14     thread 2...
Condição de corrida     • A variável m é armazenada em uma única posição de       memória para todas as threads        – m...
Condição de corrida     • Duas pessoas retiram, simultaneamente, R$ 100 da       mesma conta em dois terminais bancários (...
Condição de corrida     • Condição de corrida (“race condition”) é um problema de       programação concorrente que ocorre...
Condição de corrida – um clássico     •   Suponha que a variável m armazene o saldo (m=1000)         na memória do computa...
Exclusão Mútua e Região Crítica     •   A solução na programação é impedir que as tarefas cooperantes         executem sim...
Semântica da Região Crítica     •   A operação                           <entra na região crítica>         permite uma úni...
CRITICAL     •   Restringe o acesso ao <bloco> a uma única thread a         cada instante, implementando região crítica   ...
CRITICAL     •   Restrições:         – <nome> é entidade global do programa         – pode haver múltiplas diretivas CRITI...
Exemplo 1     • O que é impresso, supondo 8 threads?                 PROGRAM nbr1                 USE omp_lib             ...
Três Execuções     thread 0; m=11     thread 0; m=11     thread 7; m=11     thread 1; m=12     thread 2; m=12     thread 4...
PRIVATIZAÇÃO DE VARIÁVEIS     •   É comum ocorrer condição de corrida em variáveis         auxiliares dentro de laços para...
Exemplo 2                    PROGRAM nbr2                    USE omp_lib                    INTEGER :: i                  ...
Elementos de OpenMP     1.       Diretivas          •     Sintaxe          •     Região Paralela          •     Cooperação...
Cooperação de Trabalho     •   A região paralela apenas cria o time de threads; não         divide o trabalho entre as thr...
SINGLE     •   Uma única thread executa o <bloco-de-comandos>;         toadas as threads esperam ao final do comando      ...
Exemplo                 #pragma omp single                      work1();     • Qual é a utilidade deste comando?       – E...
LOOP     •   Fortran: As iterações do <laço-do> são divididas entre         as threads               !$OMP DO <lista-inici...
LOOP: RESTRIÇÕES     1. O <laço-do> ou o <laço-for> obrigatoriamente tem        contador explícito de iterações        –  ...
Exemplo     !$OMP PARALLEL     !$OMP DO      DO i = 1, vSize       vec(i) = REAL(i - vSize/2) ** 2      END DO     !$OMP E...
Lista de Clausulas do Loop     • Um laço é definido (Fortran) por             !$OMP DO <lista-de-clausulas>             <l...
Clausula de Divisão de Tarefas     •   SCHEDULE (type, [chunk])         •   divide o espaço de iterações do laço em trecho...
Clausula SCHEDULE     • SCHEDULE (STATIC, [chunk])       – Divide o espaço de iterações do laço em trechos de         “chu...
Ex: Chunk Ausente                          12 iterações, três threads           P1                   P2                   ...
Ex: Chunk Unitário                          12 iterações, três threads     P1 P2 P3 P1 P2 P3 P1 P2 P3 P1 P2 P3     c1   c2...
Ex: Chunk Não Unitário                          12 iterações, três threads      P1        P2         P3         P1       P...
SCHEDULE (DYNAMIC)     •   SCHEDULE (DYNAMIC, [chunk])         – Atribui blocos de “chunk” iterações consecutivas a thread...
Semântica     •   O número de iterações do laço é computado antes de entrar na         construção     •   As iterações do ...
Escopo das Diretivas     •   Os comandos lexicamente interiores a uma construção         OpenMP definem a extensão léxica ...
Cooperação de Trabalho     •   Comandos de cooperação de trabalho podem estar na         extensão dinâmica de uma região p...
Elementos de OpenMP     1.       Diretivas          •     Sintaxe          •     Região Paralela          •     Cooperação...
Combinação de Região Paralela e            Cooperação de Trabalho     • Combina região paralela e cooperação de trabalho n...
Exemplo     !$OMP PARALLEL DO      DO i = 1, vSize       vec(i) = REAL(i - vSize/2) ** 2      END DO     !$OMP END PARALLE...
Elementos de OpenMP     1.       Diretivas          •     Sintaxe          •     Região Paralela          •     Cooperação...
Diretivas de Sincronização     •   Finalidade: sincronizar a execução das threads     •   Obrigatoriamente no escopo dinâm...
BARRIER     •   Sincroniza todas as threads                 !$OMP BARRIER, ou                 #pragma omp barrier     •   ...
Exemplo     • Paralelize OpenMP o laço                    for (i=1; i<10; i++) {                      b[i] = func(i);     ...
Exemplo     • Tentativa 2:                     #pragma omp parallel for private(i), schedule(static,1)                    ...
Sumário OpenMP     • OpenMP implementa modelo fork-join de paralelismo       por meio de threads        • Mesmo espaço de ...
Próximos SlideShares
Carregando em…5
×

Introdução ao Processamento Paralelo (2)

803 visualizações

Publicada em

Minicurso ofericido durante a III Semana de Inverno de Geofisica, IMECC/UNICAMP, 2012, por Jairo Panetta (ITA/ICE).

Publicada em: Educação
0 comentários
0 gostaram
Estatísticas
Notas
  • Seja o primeiro a comentar

  • Seja a primeira pessoa a gostar disto

Sem downloads
Visualizações
Visualizações totais
803
No SlideShare
0
A partir de incorporações
0
Número de incorporações
41
Ações
Compartilhamentos
0
Downloads
0
Comentários
0
Gostaram
0
Incorporações 0
Nenhuma incorporação

Nenhuma nota no slide

Introdução ao Processamento Paralelo (2)

  1. 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 √ X1 III Semana Inverno Geofísica
  2. 2. Excursionando por OpenMPFontes:• Padrão OpenMP em www.openmp.org• Chandra, Menon, Dagum, Kohr: “Parallel Programming in OpenMP”, Academic Press, 2001• Chapman, Jost, Van der Pas, “Using OpenMP”, MIT Press, 20082 III Semana Inverno Geofísica
  3. 3. Padrão OpenMP • Padrão de facto (www.openmp.org) com interfaces para C, C++ e Fortran • O padrão é emitido pelo Open MP Architecture Review Board (ARB) – Entidade sem fins lucrativos – Membros da indústria (IBM, HP, NEC, Intel, ...), dos usuários (EPCC, NASA Ames, ...) e da academia (...)3 III Semana Inverno Geofísica
  4. 4. Padrão OpenMP • Implementa o modelo fork-join de paralelismo por meio de diretivas (comentários identificados), variáveis de ambiente e funções – Diretivas em Fortran: !$OMP – Diretivas em C: #pragma omp • Compiladores geram PTHREADS a partir das diretivas – Implementado por todos os principais compiladores C e Fortran • Como diretivas são comentários, programas OpenMP cuidadosamente programados podem ser executados sequencialmente – Executam em paralelo quando compilados com chave para OpenMP – Executam sequencialmente caso contrário4 III Semana Inverno Geofísica
  5. 5. Padrão OpenMP • Use a chave de compilação que “liga” OpenMP • chave não padronizada, varia de compilador para compilador: ifort –openmp pgf90 –mp gfortran -fopenmp • Vide “man page” do compilador • Por default, o número de threads criado em uma região paralela é definido pelo valor da variável de ambiente OMP_NUM_THREADS. Em bash: export OMP_NUM_THREADS=45 III Semana Inverno Geofísica
  6. 6. OpenMP • Ao paralelizar um programa, busque independências – Independências permitirem execuções simultâneas • OpenMP paraleliza laços (visão primitiva de OpenMP) – DO (Fortran), for (C) – Iterações independentes são executadas simultaneamente • Visão primitiva, pois abrir e fechar paralelismo a cada laço gera “overhead” indesejável • Idealmente, quanto maior o trecho paralelo, melhor.6 III Semana Inverno Geofísica
  7. 7. Programa Sequencial PROGRAM simple Constantes simbólicas e USE omp_lib interface de procedimentos IMPLICIT NONE INTEGER, PARAMETER :: vSize=1000000000 REAL :: vec(vSize) INTEGER :: i DO i = 1, vSize vec(i) = REAL(i - vSize/2) ** 2 END DO DO i = 1, vSize vec(i) = SQRT(vec(i)) END DO WRITE(*,(" maximum = ", f9.0,"; minimum =",f9.0))& MAXVAL(vec), MINVAL(vec) END PROGRAM simple7 III Semana Inverno Geofísica
  8. 8. OpenMP Versão 0 PROGRAM simple USE omp_lib IMPLICIT NONE INTEGER, PARAMETER :: vSize=1000000000 REAL :: vec(vSize) INTEGER :: i DO i = 1, vSize vec(i) = REAL(i - vSize/2) ** 2 END DO !$OMP PARALLEL DO DO i = 1, vSize vec(i) = SQRT(vec(i)) END DO WRITE(*,(" maximum = ", f9.0,"; minimum =",f9.0))& MAXVAL(vec), MINVAL(vec) END PROGRAM simple8 III Semana Inverno Geofísica
  9. 9. OpenMP Versão 0 Procs Tempo (s) Speed-up 1 167,87 1,00 2 128,20 1,31 3 109,62 1,54 4 102,36 1,65 5 97,99 1,72 6 95,08 1,779 III Semana Inverno Geofísica
  10. 10. OpenMP Versão 0 – O que falta? PROGRAM simple USE omp_lib IMPLICIT NONE INTEGER, PARAMETER :: vSize=1000000000 REAL :: vec(vSize) INTEGER :: i DO i = 1, vSize vec(i) = REAL(i - vSize/2) ** 2 END DO !$OMP PARALLEL DO DO i = 1, vSize vec(i) = SQRT(vec(i)) END DO WRITE(*,(" maximum = ", f9.0,"; minimum =",f9.0))& MAXVAL(vec), MINVAL(vec) END PROGRAM simple10 III Semana Inverno Geofísica
  11. 11. OpenMP Versão 1 PROGRAM simple USE omp_lib IMPLICIT NONE INTEGER, PARAMETER :: vSize=1000000000 REAL :: vec(vSize) INTEGER :: i !$OMP PARALLEL DO DO i = 1, vSize vec(i) = REAL(i - vSize/2) ** 2 END DO !$OMP PARALLEL DO DO i = 1, vSize vec(i) = SQRT(vec(i)) END DO WRITE(*,(" maximum = ", f9.0,"; minimum =",f9.0))& MAXVAL(vec), MINVAL(vec) END PROGRAM simple11 III Semana Inverno Geofísica
  12. 12. OpenMP Versão 1 Procs Speed-up 1 1,00 2 1,41 3 1,83 4 2,07 5 2,25 6 2,3712 III Semana Inverno Geofísica
  13. 13. OpenMP Versão 1 – O que falta? PROGRAM simple USE omp_lib IMPLICIT NONE INTEGER, PARAMETER :: vSize=1000000000 REAL :: vec(vSize) INTEGER :: i !$OMP PARALLEL DO DO i = 1, vSize vec(i) = REAL(i - vSize/2) ** 2 END DO !$OMP PARALLEL DO DO i = 1, vSize vec(i) = SQRT(vec(i)) END DO WRITE(*,(" maximum = ", f9.0,"; minimum =",f9.0))& MAXVAL(vec), MINVAL(vec) END PROGRAM simple13 III Semana Inverno Geofísica
  14. 14. Medindo Tempo de Execução Trecho % Tempo Exec Initialização 7,79 SQRT 55,52 Min, Max 36,69 Aplicando Amdhal Fração Speed-up Speed-up Versão sequencial (%) máximo medido V0 44,48 2,24 1,77 V1 36,69 2,72 2,3714 III Semana Inverno Geofísica
  15. 15. Como Paralelizar a Escrita? PROGRAM simple USE omp_lib IMPLICIT NONE INTEGER, PARAMETER :: vSize=1000000000 REAL :: vec(vSize) INTEGER :: i !$OMP PARALLEL DO DO i = 1, vSize vec(i) = REAL(i - vSize/2) ** 2 END DO !$OMP PARALLEL DO DO i = 1, vSize vec(i) = SQRT(vec(i)) END DO WRITE(*,(" maximum = ", f9.0,"; minimum =",f9.0))& MAXVAL(vec), MINVAL(vec) END PROGRAM simple15 III Semana Inverno Geofísica
  16. 16. OpenMP Versão 2 PROGRAM simple USE omp_lib IMPLICIT NONE INTEGER, PARAMETER :: vSize=1000000000 REAL :: vec(vSize), maxTot(0:7), minTot(0:7) INTEGER :: i, this, nThreads !$OMP PARALLEL DO DO i = 1, vSize vec(i) = REAL(i - vSize/2) ** 2 END DO !$OMP PARALLEL DO DO i = 1, vSize vec(i) = SQRT(vec(i)) END DO maxTot = -1.0; minTot = REAL(vSize) ** 2 !$OMP PARALLEL DO PRIVATE(this) DO i = 1, vSize this = OMP_GET_THREAD_NUM() ; nThreads = OMP_GET_NUM_THREADS() maxTot(this) = MAX(maxTot(this), vec(i)) minTot(this) = MIN(minTot(this), vec(i)) END DO WRITE(*,(" maximum = ", f12.0,"; minimum =",f12.0))& MAXVAL(maxTot(0:nThreads-1)), MINVAL(minTot(0:nThreads-1)) END PROGRAM simple16 III Semana Inverno Geofísica
  17. 17. OpenMP Versão 2 - Detalhe REAL :: ... maxTot(0:7), minTot(0:7) maxTot = -1.0; minTot = REAL(vSize) ** 2 !$OMP PARALLEL DO PRIVATE(this) DO i = 1, vSize this = OMP_GET_THREAD_NUM() Paralelo nThreads = OMP_GET_NUM_THREADS() maxTot(this) = MAX(maxTot(this), vec(i)) minTot(this) = MIN(minTot(this), vec(i)) END DO WRITE(*,(" maximum = ", f12.0,"; minimum =",f12.0))& Sequencial MAXVAL(maxTot(0:nThreads-1)), & MINVAL(minTot(0:nThreads-1))17 III Semana Inverno Geofísica
  18. 18. OpenMP – Versão 2 Procs Speed-up 1 1,00 2 2,00 3 2,99 4 3,98 5 4,99 6 5,9918 III Semana Inverno Geofísica
  19. 19. Conclusões da Excursão Inicial • Paralelismo OpenMP explora independências na codificação do programa – Parece fácil – Na maioria dos casos, é a forma mais fácil de gerar paralelismo • Paralelismo OpenMP pode mudar substancialmente o programa – Devido ao paralelismo desejado • Pelo que vimos, paralelismo OpenMP aplica-se a laços com iterações independentes – Visão parcial; – OpenMP é mais eficiente quando aplicado a grandes regiões independentes do programa19 III Semana Inverno Geofísica
  20. 20. Detalhando OpenMP20 III Semana Inverno Geofísica
  21. 21. Elementos de OpenMP 1. Diretivas • Sintaxe • Região Paralela • Cooperação de Trabalho • Combinação de Região Paralela e Cooperação de Trabalho • Sincronização • Ambiente 2. Funções • Ambiente • Sincronismo • Tempo 3. Variáveis de Ambiente • Ambiente21 III Semana Inverno Geofísica
  22. 22. Sintaxe das Diretivas em Fortran • Sintaxe: !$OMP nome-da-diretiva <lista-de-clausulas> onde – <lista-de-clausulas> contém 0 ou mais clausulas separadas por virgula – brancos separam o nome da diretiva da sentinela (!$OMP) e da lista de clausulas • Diretivas são “case insensitive” • Diretivas podem utilizar múltiplas linhas (continuação): !$OMP nome-da-diretiva, clausula, & !$OMP clausula, clausula, & !$OMP clausula, clausula • Compilação condicional: – Comandos Fortran iniciados por !$ são compilados sse a chave de compilação OpenMP for ativada – Necessário para que programas OpenMP funcionem corretamente em compiladores sem OpenMP22 III Semana Inverno Geofísica
  23. 23. Sintaxe das Diretivas em C e C++ • Sintaxe: #pragma omp nome-da-diretiva <lista-de-clausulas> new-line onde – <lista-de-clausulas> contém 0 ou mais clausulas separadas por virgula – brancos separam o nome da diretiva da sentinela (!$OMP) e da lista de clausulas • Diretivas são “case sensitive” (ao contrário de Fortran) – diretivas e clausulas em caixa baixa (minúsculas) • Compilação condicional: – O macro _OPENMP é definido sse a chave de compilação OpenMP for ativada #ifdef _OPENMP threadID = omp_get_thread_num(); #else threadID = 0 #endif23 III Semana Inverno Geofísica
  24. 24. Elementos de OpenMP 1. Diretivas • Sintaxe • Região Paralela • Cooperação de Trabalho • Combinação de Região Paralela e Cooperação de Trabalho • Sincronização • Ambiente 2. Funções • Ambiente • Sincronismo • Tempo 3. Variáveis de Ambiente • Ambiente24 III Semana Inverno Geofísica
  25. 25. Região Paralela • Fortran: !$OMP PARALLEL <lista-de-clausulas> <structured-block> !$OMP END PARALLEL • C, C++: #pragma omp parallel <lista-de-clausulas> <structured-block> • <lista-de-clausulas> pode ser vazia • <structured-block> em C tem escopo léxico bem definido – {...}, por exemplo – não é necessário indicar seu término para OpenMP • Não há equivalente em Fortran à {...} – é necessário indicar o término de <structured-block> por !$OMP END PARALLEL25 III Semana Inverno Geofísica
  26. 26. Modelo de Execução • OpenMP implementa o modelo fork-join de execução paralela: 1. Um programa OpenMP executa sequencialmente (um único processo denominado thread mestre, ”master thread”) até encontrar uma região paralela 2. Ao entrar na região paralela a thread mestre cria um time de threads e torna-se o mestre do time 3. Os comandos na região paralela são executados por todas as threads 4. Ao término da região paralela, todas as threads do time sincronizam e apenas a thread mestre continua a execução 5. Qualquer número de regiões paralelas pode ser criado26 III Semana Inverno Geofísica
  27. 27. Número de Threads • A função OMP_GET_NUM_THREADS() retorna o número de threads do time atualmente em execução – Retorna 1 na parte sequencial do programa • As threads são numeradas de 0 à OMP_NUM_THREADS-1 – Master Thread é a thread 0 • A função OMP_GET_THREAD_NUM() retorna o número da thread que a invoca – entre 0 e OMP_GET_NUM_THREADS-1 – 0 na região sequencial do programa27 III Semana Inverno Geofísica
  28. 28. Exemplo em C #include <omp.h> #include <stdio.h> void main(){ #pragma omp parallel { if (omp_get_thread_num() == 0) printf("Sou thread %d diferenten", omp_get_thread_num()); else printf("Sou thread %d igualn", omp_get_thread_num()); } }28 III Semana Inverno Geofísica
  29. 29. Exemplo com 8 threads Sou thread 0 diferente Sou thread 2 igual Sou thread 3 igual Sou thread 7 igual Sou thread 5 igual Sou thread 1 igual Sou thread 6 igual Sou thread 4 igual OpenMP não garante sincronismo de I/O29 III Semana Inverno Geofísica
  30. 30. Implementação Típica • O corpo da região paralela é transformado em um procedimento • O início da região paralela é transformada em um laço que percorre as threads, invocando pthread_create, passando o procedimento como argumento. • O término da região paralela é transformado em um laço que percorre as threads, invocando pthread_join, que aguarda o término das threads.30 III Semana Inverno Geofísica
  31. 31. Exemplo 1 • O que é impresso, supondo 8 threads? PROGRAM nbr1 USE omp_lib INTEGER :: m m = 10 !$OMP PARALLEL m=m+1 WRITE (*,"( thread ,i1,; m=,i2)") & OMP_GET_THREAD_NUM(), m !$OMP END PARALLEL WRITE (*,"( sequen ; m=,i2)") m END PROGRAM nbr131 III Semana Inverno Geofísica
  32. 32. Três Execuções thread 5; m=18 thread 7; m=14 thread 6; m=16 thread 1; m=18 thread 2; m=14 thread 2; m=16 thread 6; m=18 thread 5; m=14 thread 7; m=16 thread 4; m=18 thread 6; m=14 thread 1; m=16 thread 0; m=18 thread 3; m=14 thread 3; m=16 thread 3; m=18 thread 4; m=14 thread 4; m=16 thread 2; m=18 thread 1; m=14 thread 5; m=16 thread 7; m=18 thread 0; m=14 thread 0; m=16 sequen ; m=18 sequen ; m=14 sequen ; m=16 • Não determinismo por condição de corrida32 III Semana Inverno Geofísica
  33. 33. Condição de corrida • A variável m é armazenada em uma única posição de memória para todas as threads – m é armazenada em “data” (pois é variável alocada pelo compilador) • As threads competem por ler e escrever na posição de memória representada por m – conflito leitura-escrita • O resultado depende da ordem de acesso à variável compartilhada (velocidade relativa das threads) • Condição de corrida (“race condition”) é o fenômeno que ocorre quando o resultado de uma computação muda com a ordem (velocidade) de execução das tarefas componentes33 III Semana Inverno Geofísica
  34. 34. Condição de corrida • Duas pessoas retiram, simultaneamente, R$ 100 da mesma conta em dois terminais bancários (M1 e M2) conectadas ao mesmo computador central • O saldo da conta era R$ 1000 antes dos saques • Cada um obtém R$ 100 e o novo saldo é R$ 900!!! • Eis como: – M1 pede o saldo e obtém resposta 1000 – M1 subtrai, localmente, 100 do saldo que conhece – M2 pede o saldo e obtém resposta 1000 – M1 comunica ao computador central o novo saldo de 900 – M2 subtrai, localmente, 100 do saldo que conhece – M2 comunica ao computador central o novo saldo de 90034 III Semana Inverno Geofísica
  35. 35. Condição de corrida • Condição de corrida (“race condition”) é um problema de programação concorrente que ocorre quando o resultado de uma computação muda com a ordem (velocidade) de execução das tarefas componentes – No exemplo anterior, há ordens de execução que resultam em saldos corretos • Aparentemente, o saldo errado ocorre pois uma mesma informação (saldo) está armazenada em múltiplas memórias simultaneamente – saldo no computador central e nos dois terminais • É possível evitar a replicação da armazenagem? – Por exemplo, apenas o computador central calcula o saldo35 III Semana Inverno Geofísica
  36. 36. Condição de corrida – um clássico • Suponha que a variável m armazene o saldo (m=1000) na memória do computador central. – Suponha computador central com processadores P1 e P2, executando threads T1 e T2 originadas respectivamente pelas máquinas M1 e M2 • Eis ordem de execução que resulta em m=900: T1: R1 <- m T1: R1 <- R1 - 100 T2: R1 <- m T2: R1 <- R1 - 100 T1: m <- R1 T2: m <- R1 • A mesma ordem pode ocorrer se houver um único processador. – Em execuções intercaladas das threads36 III Semana Inverno Geofísica
  37. 37. Exclusão Mútua e Região Crítica • A solução na programação é impedir que as tarefas cooperantes executem simultaneamente as operações que geram o problema • Essa solução é denominada exclusão mútua (“mutual exclusion”) • No exemplo, implementar exclusão mútua obriga que o trecho m = m - 100 seja executado por uma thread de cada vez • A região do programa que requer execução exclusiva é denominada região crítica (“critical region”) • Região crítica é programada por duas operações primitivas: <entra na região crítica> m = m - 100 <sai da região crítica>37 III Semana Inverno Geofísica
  38. 38. Semântica da Região Crítica • A operação <entra na região crítica> permite uma única thread na região crítica a cada instante, enquanto as demais aguardam • A operação <sai da região crítica> remove a thread da região crítica, permitindo que outra thread adentre a região • Threads aguardam na entrada da região crítica em uma das formas: 1. Continuamente testando se podem entrar na região crítica (“busy waiting”); 2. Colocadas em estado de espera pelo O.S. (“sleeping”) dependendo como a região crítica é implementada38 III Semana Inverno Geofísica
  39. 39. CRITICAL • Restringe o acesso ao <bloco> a uma única thread a cada instante, implementando região crítica !$OMP CRITICAL (nome) <bloco> !$OMP END CRITICAL (nome) , ou #pragma omp critical (nome) <structured-block> • Semântica: – Threads aguardam no início da região até que nenhuma outra thread esteja executando qualquer região critica com o mesmo nome39 III Semana Inverno Geofísica
  40. 40. CRITICAL • Restrições: – <nome> é entidade global do programa – pode haver múltiplas diretivas CRITICAL com o mesmo nome – <nome> é opcional; todas as diretivas CRITICAL sem nome são mapeadas no mesmo nome (mesma região crítica) – mesmo <nome> em CRITICAL e END CRITICAL – são proibidos saltos de/para o <bloco> – CRITICAL e END CRITICAL no mesmo procedimento40 III Semana Inverno Geofísica
  41. 41. Exemplo 1 • O que é impresso, supondo 8 threads? PROGRAM nbr1 USE omp_lib INTEGER :: m m = 10 !$OMP PARALLEL !$OMP CRITICAL m=m+1 WRITE (*,"( thread ,i1,; m=,i2)") & OMP_GET_THREAD_NUM(), m !$OMP END CRITICAL !$OMP END PARALLEL WRITE (*,"( sequen ; m=,i2)") m END PROGRAM nbr141 III Semana Inverno Geofísica
  42. 42. Três Execuções thread 0; m=11 thread 0; m=11 thread 7; m=11 thread 1; m=12 thread 2; m=12 thread 4; m=12 thread 2; m=13 thread 5; m=13 thread 1; m=13 thread 7; m=14 thread 1; m=14 thread 2; m=14 thread 4; m=15 thread 7; m=15 thread 6; m=15 thread 3; m=16 thread 6; m=16 thread 0; m=16 thread 5; m=17 thread 4; m=17 thread 3; m=17 thread 6; m=18 thread 3; m=18 thread 5; m=18 sequen ; m=18 sequen ; m=18 sequen ; m=18 • Determinístico • Mas a seção crítica sequencializa o programa • Não há redução do tempo de execução42 III Semana Inverno Geofísica
  43. 43. PRIVATIZAÇÃO DE VARIÁVEIS • É comum ocorrer condição de corrida em variáveis auxiliares dentro de laços paralelizados • A solução é criar uma variável auxiliar para cada thread • Variável privatizada • !$OMP PARALLEL PRIVATE(<lista de variaveis>) • O valor inicial da variável privatizada é indefinido • A variável privatizada só existe no interior da região paralela43 III Semana Inverno Geofísica
  44. 44. Exemplo 2 PROGRAM nbr2 USE omp_lib INTEGER :: i REAL :: aux, vec(8) vec = 0.0 !$OMP PARALLEL PRIVATE(aux, i) DO i = 1, 8 aux = (i+1)*(i-1) vec(i) = aux END DO !$OMP END PARALLEL END PROGRAM nbr2 • Privatização de aux e de i evitam condição de corrida • Mas todas as threads executam todas as iterações do laço, pois não há divisão de trabalho entre as threads44 III Semana Inverno Geofísica
  45. 45. Elementos de OpenMP 1. Diretivas • Sintaxe • Região Paralela • Cooperação de Trabalho • Combinação de Região Paralela e Cooperação de Trabalho • Sincronização • Ambiente 2. Funções • Ambiente • Sincronismo • Tempo 3. Variáveis de Ambiente • Ambiente45 III Semana Inverno Geofísica
  46. 46. Cooperação de Trabalho • A região paralela apenas cria o time de threads; não divide o trabalho entre as threads – Cada thread executa todo código na região paralela – A divisão de trabalho pode ser implementada estabelecendo trabalhos distintos para threads distintas, utilizando thread ID • Trabalhoso, fácil de errar, dependente do número de threads • Comandos de cooperação de trabalho dividem a computação pelas threads – Quer na extensão léxica da região paralela quer como diretivas órfãs • Há diversos comandos de cooperação de trabalho; veremos dois deles: • SINGLE • LOOP III Semana Inverno Geofísica46
  47. 47. SINGLE • Uma única thread executa o <bloco-de-comandos>; toadas as threads esperam ao final do comando (barreira) • Fortran: !$OMP SINGLE <structured-block> !$OMP END SINGLE • C: #pragma omp single <lista-inicial-de-clausulas> <structured-block>47 III Semana Inverno Geofísica
  48. 48. Exemplo #pragma omp single work1(); • Qual é a utilidade deste comando? – Execução sequencial no interior de uma região paralela evita quebrar a região paralela em duas48 III Semana Inverno Geofísica
  49. 49. LOOP • Fortran: As iterações do <laço-do> são divididas entre as threads !$OMP DO <lista-inicial-de-clausulas> <laço-do> !$OMP END DO <lista-terminal-de-clausulas> • C: As iterações do <laço-for> são divididas entre as threads #pragma omp for <lista-inicial-de-clausulas> <laço-for>49 III Semana Inverno Geofísica
  50. 50. LOOP: RESTRIÇÕES 1. O <laço-do> ou o <laço-for> obrigatoriamente tem contador explícito de iterações – do i = 1, n – for (i=0, i<n, i++) 2. São proibidos saltos para dentro e para fora do <laço- do> – Exclui laços com EXIT 3. A diretiva !$OMP END DO é opcional 4. A variável que conta as iterações do laço é privatizada automaticamente50 III Semana Inverno Geofísica
  51. 51. Exemplo !$OMP PARALLEL !$OMP DO DO i = 1, vSize vec(i) = REAL(i - vSize/2) ** 2 END DO !$OMP END DO !$OMP DO DO i = 1, vSize vec(i) = SQRT(vec(i)) END DO !$OMP END DO !$OMP END PARALLEL51 III Semana Inverno Geofísica
  52. 52. Lista de Clausulas do Loop • Um laço é definido (Fortran) por !$OMP DO <lista-de-clausulas> <laço do> !$OMP END DO onde a lista de clausulas pode conter: – Cláusulas de Escopo (como private) – Cláusula de Divisão de Tarefas – Cláusula de Redução (não veremos)52 III Semana Inverno Geofísica
  53. 53. Clausula de Divisão de Tarefas • SCHEDULE (type, [chunk]) • divide o espaço de iterações do laço em trechos de tamanho chunk e atribui trechos a threads da forma determinada por type • Onde – chunk, se presente, é uma expressão escalar inteira que define o número de iterações atribuído a cada thread – type é um de: • STATIC • DYNAMIC • Há outros • A clausula SCHEDULE atribui iterações do laço a threads (mapeamento de tarefas) III Semana Inverno Geofísica53
  54. 54. Clausula SCHEDULE • SCHEDULE (STATIC, [chunk]) – Divide o espaço de iterações do laço em trechos de “chunk” iterações consecutivas – Atribui estaticamente trechos consecutivos à threads consecutivas, em “round-robin” • o primeiro trecho à thread 0, o segundo trecho à thread 1, e assim sucessivamente – Caso “chunk” não seja especificado, o espaço de índices do laço é dividido em trechos aproximadamente iguais e cada thread recebe um único trecho54 III Semana Inverno Geofísica
  55. 55. Ex: Chunk Ausente 12 iterações, três threads P1 P2 P3 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 Distribuição por blocos Block Distribution55 III Semana Inverno Geofísica
  56. 56. Ex: Chunk Unitário 12 iterações, três threads P1 P2 P3 P1 P2 P3 P1 P2 P3 P1 P2 P3 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 Distribuição Cíclica Cyclic Distribution56 III Semana Inverno Geofísica
  57. 57. Ex: Chunk Não Unitário 12 iterações, três threads P1 P2 P3 P1 P2 P3 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 Distribuição Cíclica por Blocos Block Cyclic Distribution57 III Semana Inverno Geofísica
  58. 58. SCHEDULE (DYNAMIC) • SCHEDULE (DYNAMIC, [chunk]) – Atribui blocos de “chunk” iterações consecutivas a threads dinamicamente – Isto é, assim que uma thread termina a execução de um “chunk” de iterações ela obtém o próximo “chunk” dinamicamente • A ausência de chunk é equivalente a chunk=1 • Qual é a utilidade dessa construção? • A clausula SCHEDULE(DYNAMIC) é particularmente útil se a quantidade de computação varia dinamicamente com a iteração do laço58 III Semana Inverno Geofísica
  59. 59. Semântica • O número de iterações do laço é computado antes de entrar na construção • As iterações do laço são divididas entre as threads conforme especificado pela cláusula SCHEDULE. • Diretivas LOOP em laços distintos com o mesmo número de iterações e SCHEDULE na mesma região paralela podem distribuir iterações a threads em ordem distinta, exceto em SCHEDULE(STATIC) • Programas que assumem qual thread executa qual iteração não são aderentes ao padrão, exceto no caso SCHEDULE(STATIC)59 III Semana Inverno Geofísica
  60. 60. Escopo das Diretivas • Os comandos lexicamente interiores a uma construção OpenMP definem a extensão léxica da construção • Bloco estruturado, em C • Os comandos executados em uma construção OpenMP definem a extensão dinâmica da construção – incluem a extensão léxica e invocações a métodos na árvore de chamadas do programa • Diretivas OpenMP externas à extensão léxica de uma construção mas na extensão dinâmica da construção são denominadas órfãs (“orphaned directives”) – programas podem abrir regiões paralelas nos níveis mais altos da árvore de chamadas e controlar a execução de rotinas por meio de diretivas órfãs60 III Semana Inverno Geofísica
  61. 61. Cooperação de Trabalho • Comandos de cooperação de trabalho podem estar na extensão dinâmica de uma região paralela ou não – Execução paralela quando na extensão dinâmica – Execução sequencial (uma única thread) quando não • Comandos de cooperação de trabalho são encontrados por todas as threads e na mesma ordem • É proibido aninhar comandos de cooperação de trabalho • Há uma barreira implícita no termino (END) de um comando de cooperação de trabalho – Todas as threads sincronizam no comando terminal – A barreira é eliminada pela inserção da clausula NOWAIT no comando terminal61 III Semana Inverno Geofísica
  62. 62. Elementos de OpenMP 1. Diretivas • Sintaxe • Região Paralela • Cooperação de Trabalho • Combinação de Região Paralela e Cooperação de Trabalho • Sincronização • Ambiente 2. Funções • Ambiente • Sincronismo • Tempo 3. Variáveis de Ambiente • Ambiente62 III Semana Inverno Geofísica
  63. 63. Combinação de Região Paralela e Cooperação de Trabalho • Combina região paralela e cooperação de trabalho na mesma diretiva • Cria uma única região paralela com uma única diretiva de cooperação de trabalho • Construções: • Fortran: PARALLEL DO - END PARALLEL DO • C: parallel for • Semântica: Idêntico a usar a diretiva PARALLEL seguida pela diretiva de cooperação de trabalho • Custo: Overhead de criar e destruir as threads • Benefício: O restante do código é serial – Não precisa lidar com paralelismo63 III Semana Inverno Geofísica
  64. 64. Exemplo !$OMP PARALLEL DO DO i = 1, vSize vec(i) = REAL(i - vSize/2) ** 2 END DO !$OMP END PARALLEL DO !$OMP PARALLEL DO DO i = 1, vSize vec(i) = SQRT(vec(i)) END DO !$OMP END PARALLEL DO64 III Semana Inverno Geofísica
  65. 65. Elementos de OpenMP 1. Diretivas • Sintaxe • Região Paralela • Cooperação de Trabalho • Combinação de Região Paralela e Cooperação de Trabalho • Sincronização • Ambiente 2. Funções • Ambiente • Sincronismo • Tempo 3. Variáveis de Ambiente • Ambiente65 III Semana Inverno Geofísica
  66. 66. Diretivas de Sincronização • Finalidade: sincronizar a execução das threads • Obrigatoriamente no escopo dinâmico de uma região paralela • Não podem romper limites de diretivas de divisão de trabalho • Construções: • BARRIER • CRITICAL (já vimos) • ...66 III Semana Inverno Geofísica
  67. 67. BARRIER • Sincroniza todas as threads !$OMP BARRIER, ou #pragma omp barrier • Semântica: – Cada thread que atinge a barreira aguarda até que todas as threads do time atinjam a barreira • Restrições: – Todas as threads de um time encontram a barreira • ou nenhuma thread a encontra – Comandos de cooperação de trabalho e barreiras devem ser encontrados na mesma ordem por todas as threads de um time • Uso incorreto causa deadlock!!!67 III Semana Inverno Geofísica
  68. 68. Exemplo • Paralelize OpenMP o laço for (i=1; i<10; i++) { b[i] = func(i); a[i] = b[i-1] + b[i]; } • Tentativa 1: #pragma omp parallel for private (i) for (i=1; i<10; i++) { b[i] = func(i); a[i] = b[i-1] + b[i]; } Errado pois iterações do laço não são independentes68 III Semana Inverno Geofísica
  69. 69. Exemplo • Tentativa 2: #pragma omp parallel for private(i), schedule(static,1) for (i=1; i<10; i++) { b[i] = func(i); #pragma omp barrier a[i] = b[i-1] + b[i]; } correto pela ordenação das tarefas e pela barreira explícita • Tentativa 3: #pragma omp parallel for private(i) for (i=1; i<10; i++) b[i] = func(i); #pragma omp parallel for private (i) for (i=1; i<10; i++) a[i] = b[i-1] + b[i]; correto pela barreira implícita ao fim do primeiro for69 III Semana Inverno Geofísica
  70. 70. Sumário OpenMP • OpenMP implementa modelo fork-join de paralelismo por meio de threads • Mesmo espaço de endereçamento • Paralelismo no mesmo espaço de endereçamento gera condição de corrida • Obriga privatização de variáveis • Região paralela por meio de !$OMP PARALLEL • Divide tarefas na região paralela por meio de !$OMP DO70 III Semana Inverno Geofísica

×