Segue o modelo SPMD – Single Program Multiple Data
- Um único código executado com dados diferentes
Norma OpenMP
- Implementações em memória compartilhada
- Paralelismo de laços
- Explícito, tipo fork-join
- Especificação alto-nível (sobre threads)
- Usa diretivas de compilação
#pragma omp ...
\pause Observações
- Fácil obter o código sequencial
- Suporte em C, C++, Fortran, …
- OpenMP: __Compilador compatível + runtime__
Consórcio de fabricantes HW/SW
- HP, IBM, Intel, SGI
Compiladores compatíveis
- gcc – https://gcc.gnu.org/wiki/openmp
- clang – https://clang-omp.github.io/
- Lista completa: \ http://openmp.org/wp/openmp-compilers/
\pause Testar com um olá mundo \tiny
#include <omp.h>
#include <stdio.h>
int main() {
#pragma omp parallel
printf("Hello from thread %d, nthreads %d\n",
omp_get_thread_num(), omp_get_num_threads());
}
\pause Em um Debian
gcc -fopenmp hello.c
Identifique os laços custosos
double res[MAX];
for (i = 0; i < MAX; i++)
calculo_pesado(&res[i]);
\pause Versão paralelizada com OpenMP
double res[MAX];
#pragma omp parallel for
for (i = 0; i < MAX; i++)
calculo_pesado(&res[i]);
Via memória compartilhada
- Possibilidade de definir quais variáveis são compartilhadas
Necessidade de sincronizar os acessos
- Implica em sobrecusto (escondido do programador)
- \pause Bom projeto do algoritmo
- Distribuição de dados
- Volume de acessos remoto
Regiões paralelas
omp parallel
\pause Compartilhamento dos dados
omp shared, private
\pause Distribuição de trabalho
omp for
\pause Sincronizações
omp atomic, critical, barrier
\pause Funções para tempo de execução, variáveis de ambiente
omp_set_num_threads()
omp_set_lock(), ...
OMP_SCHEDULE, OMP_NUM_THREADS, ...
Criação de fluxos de execução
double A[10000];
#pragma omp parallel
{
int th_id = omp_get_thread_num();
calculo_pesado(th_id, A);
}
\pause Observações
- Abertura de chaves sinaliza fork das threads
- Fechamento de chaves indica join
- Variável A é compartilhada
Variáveis compartilhadas
- Estáticas
- Globais
Variáveis privadas a cada fluxo
- Locais a um bloco
- Alocadas na pilha do fluxo paralelo
- Exemplo: função chamada por uma seção paralela
Existem cláusulas que dão liberdade ao programador
- Permite especificar o que compartilhar
\pause Completam as diretivas
omp parallel
omp sections
omp for
\pause São elas
- shared(var) – especifica que var é compartilhada
- private(var) – especifica que var é privada
- Cria-se uma cópia privada em cada fluxo
- default(private), default(shared)