OpenMP 
Valter Ferlete - valter.ferlete@ufms.br 
Programação Multi-Core - T01 
11/09/2014
OpenMP 
● Origem; 
● Visão Geral; 
● Objetivos; 
● Prós e Contras; 
● Modelo de Memória e Execução; 
● Serviços OpenMP; 
● Variáveis de ambiente; 
● Diretivas e Cláusulas.
Origem 
● No início dos anos 90, fabricantes de máquinas com memória 
compartilhada forneciam extensões para programação 
paralela em Fortran; 
● As implementações permitiam ao usuário inserir diretivas para 
indicar onde loops deveriam ser paralelizados e os 
compiladores eram responsáveis pela paralelização; 
● Implementações funcionalmente parecidas, mas não portáveis 
e começaram a divergir; 
● ANSI X3H5 em 1994 foi a primeira tentativa de padronização.
Origem 
● A especificação padrão OpenMP começou em 1997 partindo 
do padrão X3H5 graças ao aparecimento de novas 
arquiteturas de máquinas de memória compartilhada; 
● Alguns parceiros na especificação: 
○ Compaq, HP, Intel, IBM, Silicon, Sun 
○ Absoft, GENIAS, Myrias, The Portland Group 
○ ANSYS, Dash, ILOG CPLEX, Livermore, NAG 
● A API para Fortran foi liberada em Outubro de 1997 e para 
C/C++ no final de 1998.
Linha do tempo
Visão Geral 
● Biblioteca de mais alto nível para programação paralela; 
● Prevê memória compartilhada; 
● Requer suporte do compilador; 
● Exige biblioteca específica com implementações thread safe.
OpenMP
Objetivos OpenMP 
● Prover um padrão para uma variedade de plataformas e 
arquiteturas baseadas em memória compartilhada; 
● Estabelecer um conjunto limitado e simples de diretivas para 
programação utilizando memória compartilhada; 
● Prover capacidade para paralelizar um programa de forma 
incremental; 
● Implementar paralelismo com granulosidade fina e grossa 
● Suportar Fortran, C e C++.
Por que usar OpenMP? 
● Facilidade de conversão de programas sequênciais em 
paralelos; 
● Maneira simples de explorar paralelismo; 
● Fácil compreensão e uso das diretivas; 
● Minimiza a interferência na estrutura do algoritmo; 
● Compila e executa em ambientes paralelos e sequencial.
Por que não usar OpenMP? 
● Requer um compilador que suporta OpenMP; 
● A escalabilidade é limitada pela arquitetura de memória; 
● Manipulação segura do erro está em falta; 
● Carece de mecanismo refinado para controlar o 
mapeamento thread-processor.
Modelo de Memória 
➔ Memória distribuída 
● Sistema computacional constituído de vários 
processadores dotados de recursos 
individuais; 
● Este sistema se caracteriza pela troca de 
mensagem entre os processadores; 
● A troca de mensagem é feita por uma 
biblioteca de comunicação (MPI). 
Modelo de programação baseado em MPI
Modelo de Memória 
➔ Memória compartilhada 
● Sistema computacional constituído de vários 
processadores que compartilham o mesmo 
recurso de memória; 
● É necessário a sincronização do acesso aos 
dados na memória compartilhada pelos 
processadores. 
OpenMP, Threads, Posix Threads
Thread Overview
Modelo de Execução Fork - Join 
OpenMP usa o modelo fork-join para paralelizar a execução 
FORK: A thread principal cria um grupo de threads paralelas; 
JOIN: Quando grupo threads completa a região paralela, ele 
sincroniza e finaliza, mantendo apenas a thread principal.
Organização do OpenMP
Serviços do OpenMP 
● Biblioteca de serviços 
○ Permite controlar e interagir com o ambiente de execução. 
● Exemplos: 
○ omp_get_thread_num() 
○ omp_set_num_threads(nthreads) 
○ omp_get _num_threads() 
○ omp_set_num_threads() 
○ omp_get_max_threads() 
○ omp_set_nested()
Variáveis de ambiente 
➢ OMP_NUM_THREADS 
○ Identifica o número de atividades que serão executadas em paralelo; 
○ (default: número de processadores). 
➢ OMP_DYNAMIC 
○ Indica se o número de atividades a serem executadas em paralelo 
deve ou não ser ajustado dinamicamente; 
○ (default:FALSE). 
➢ OMP_NESTED 
○ Indica se deve ser contemplado ativação de paralelismo aninhado; 
○ (default: FALSE). 
➢ OMP_SCHEDULE 
○ Define esquema de escalonamento das atividades paralelas. 
○ (default: estático).
Diretivas de compilação 
➢ A maioria dos construtores em OpenMP são diretivas do compilador ou pragmas; 
➢ Diretivas consiste em uma linha de código com significado “especial” para o 
compilador; 
➢ Para C e C++, a diretiva possui a seguinte forma: 
○ #pragma omp construct [clause [clause] …] 
○ Ex. #pragma omp parallel 
➢ Para Fortran: 
○ !$OMP PARALLEL 
➢ Pragma Parallel 
○ Define uma região paralelizável sobre um bloco estruturado de código; 
○ As threads bloqueiam no fim da região; 
○ Os dados são compartilhados (shared) entre as threads ao menos que seja 
especificados de outra forma.
Um exemplo genérico 
#include <omp.h> 
main ( ){ 
//Código seqüencial (master) 
#pragma omp parallel 
{ 
// Código paralelo …. 
} 
// Código seqüencial (master) 
} 
Região Paralela
Hello World 
#include <omp.h> 
#include <stdio.h> 
int main() { 
int nthreads; 
omp_set_num_threads(4); // Configura o número de treads 
#pragma omp parallel{ 
printf("Hello World da thread %dn", omp_get_thread_num()); 
if ( omp_get_thread_num() == 0 ) { 
nthreads = omp_get_num_threads(); 
printf("Existem %d threadsn",nthreads); 
} 
}// Final da Região Paralela 
return 0; 
}
Compilar e executar 
Compilar: 
$ gcc -o hello -fopenmp hello.c 
Executar: 
$ export OMP_NUM_THREADS=2 (Opcional) 
$ .helloc
Diretivas e Cláusulas 
● Diretivas 
○ Construtor Paralelo 
#pragma omp parallel 
○ Construtores de trabalho 
#pragma omp for 
#pragma omp single 
#pragma omp sections 
○ Construtores de sincronização 
#pragma omp critical 
#pragma omp master 
#pragma omp atomic 
#pragma omp barrier 
#pragma omp flush 
#pragma omp ordered 
#pragma omp threadprivate 
● Cláusulas 
Definem o comportamento das 
regiões e das variáveis aos quais 
estão associadas 
shared 
private 
firstprivate 
lastprivate 
num_threads 
schedule 
default 
ordered 
copyn 
copyprivate 
if 
nowait 
reduction
Diretiva / Construtor paralelo 
● parallel 
○ Informa ao compilador a existência de uma região que deve ser executada em 
paralelo. 
omp_set_num_threads(4); 
#pragma omp parallel 
{ 
int i; 
printf(“n”); 
for( i = 0; i< 2; i++) 
printf(“Iteração = %dn”, i); 
}
Diretiva / Construtor paralelo 
● parallel Cláusula reduction 
○ reduction(operador:variável), permite operar sobre o valor de uma variável; 
○ Cada execução pode manipular sua cópia, como em private; 
○ O valor local inicial é definido pela operação de redução; 
○ No final uma operação de redução atualiza o dados na thread master. 
int soma=100; 
omp_set_num_threads(4); 
#pragma omp parallel reduction(+:soma) 
{ 
soma +=1; 
} 
//No retorno ao master a soma=104
Diretiva / Construtor de trabalho 
● for / parallel for 
○ Permite que os grupos de instruções definidas em um loop sejam 
paralelizadas. 
float dot_prod(float* a, float* b, int N){ 
float sum =0.0; 
#pragma omp parallel for shared(sum) 
for(int i=0;i<N;i++){ 
sum+=a[i]*b[i]; 
} 
return sum; 
}
Paralelismo aninhado 
● Dentro de uma região paralela, quando as threads encontram outro construtor 
paralelo, elas criam novos grupos de threads e tornam-se as threads mestre 
desses novos grupos; 
● Essas regiões são denominadas regiões paralelas aninhadas e por padrão são 
executadas de forma sequêncial, ou seja, o novo grupo criado contém apenas uma 
thread, que é a própria thread mestre do grupo. 
#pragma omp parallel { 
#pragma omp parallel for 
for( int i = 0; i < n; i++ ){ 
#pragma omp parallel for 
for( int i = 0; i < n; i++ ) 
c[i] = a[i]+b[i]; 
} 
}
Diretiva / Construtor de trabalho 
● single 
○ Indica que em uma região paralela ou um trecho de código deve ser executado 
apenas por uma única thread. 
#pragma omp parallel num_threads(6) 
{ 
#pragma omp single 
printf(“ler a entrada”);//somente uma thread lê entrada 
printf(“calcular resultado”);//Várias threads calculam o resultado 
#pragma omp single 
printf(“escreve na saida”); // somente uma thread escreve na saída 
}
Diretiva / Construtor de trabalho 
● single [nowait] 
○ com nowait a barreira pode ser relaxada. 
#pragma omp parallel 
{ 
#pragma omp single 
printf(“Serão %d threads n”, omp_get_num_threads()) 
taskA(); 
#pragma omp single nowait 
printf(“A thread %d terminou n”, omp_get_thread_num()); 
}
Diretiva / Construtor de trabalho 
● sections 
○ Cria seções paralelas; 
○ Cada seção será executada em uma thread diferente. 
main (){ 
int x=2; 
#pragma omp sections{ 
#pragma omp section 
{ taskA(x); } 
#pragma omp section 
{ taskB(x); } 
} 
}
Diretiva / Construtor de sincronização 
● critical[(nome)] 
○ Permite que trechos de código sejam executados em regime de exclusão 
mútua. 
int prox_x, prox_y; 
#pragma omp parallel shared(x,y) private (prox_x, prox_y) 
{ 
#pragma omp critical(eixox) 
prox_x = dequeue(x); 
taskA(prox_x,x); 
#pragma omp critical(eixoy) 
prox_y = dequeue(y); 
taskA(prox_y,y); 
}
Diretiva / Construtor de sincronização 
● master [nowait] 
○ Indica que em uma região paralela ou um trecho de código deve ser executado 
apenas pela thread master; 
○ Representa uma barreira; 
○ com nowait a barreira pode ser relaxada. 
#pragma omp parallel 
{ 
#pragma omp master 
printf(“Serão %d threads n”, omp_get_num_threads()); 
foo(); 
#pragma omp master nowait 
printf(“A thread master terminou n”); 
}
Diretiva / Construtor de sincronização 
● atomic [read, write, update e capture] 
Especifica que uma posição de memória deve ser atualizada atomicamente. 
#pragma omp atomic 
● barrier 
Quando esta directiva é alcançada por uma thread, este espera até que os 
restantes chegem ao mesmo ponto. 
#pragma omp barrier 
● flush 
Identifica um ponto de sincronização no qual é necessário providenciar uma 
visão consistente memória. 
#pragma omp flush
Cláusula - Schedule 
● Cláusula: schedule 
○ Afeta como as iterações do laço são mapeadas entre as threads 
○ schedule(static [,chunk]) 
■ Blocos de iterações de tamanho “chunk” 
■ Distribuição Round robin 
○ schedule(dynamic [,chunk]) 
■ Iteração de tamanho “chunk” 
■ Ao terminar as iterações, a thread requisita o próximo passo 
○ schedule(guided [,chunk]) 
■ Agendamento dinâmico iniciado com um tamanho grande 
■ O tamanho dos blocos diminui, não menor do que “chunk”
Cláusula - Schedule
Cláusula - Schedule 
● Cláusula: schedule (Exemplo) 
#pragma omp parallel for schedule (static, 4) shared(qtdePrimos) 
for(i = 0; i < 500; i++){ 
if (testaPrimo(i) == 1){ 
#pragma omp atomic 
qtdePrimos++; 
} 
} 
$ export OMP_SCHEDULE=“static,4”
Cláusula - IF 
● Cláusula: if(expressão lógica) 
○ Se a expressão lógica for verdadeira a região paralela será executada por mais 
de uma thread. 
void test(int val){ 
#pragma omp parallel if (val==2) 
if (omp_in_parallel()){ 
#pragma omp single 
printf("val = %d, paralelizado com %d threadsn", val, 
omp_get_num_threads()); 
}else { 
printf("val = %d, serializadon", val); 
} 
} 
Chamando: 
test(0); 
test(1); 
test(2); 
Saída: 
val = 0, serializado 
val = 1, serializado 
val = 2, paralelizado com 2 threads
Cláusula - Private 
● Cláusula: private 
○ Especifica que cada thread deve ter sua própria instância de uma variável; 
○ A variável não é inicializada; 
○ Alterações de valor dentro da região paralela não são visíveis fora; 
○ Utilizando firstprivate ou lastprivate o valor de i é inicializado com o valor 
antes do início da região paralela. 
int i=10; 
#pragma omp parallel private(i) 
{ 
printf("thread %d: i = %dn", omp_get_thread_num(), i); 
i = 100 + omp_get_thread_num(); 
} 
printf("i = %dn", i); 
thread 0: i = 0 
thread 3: i = 0 
thread 1: i = 32696 
thread 2: i = 0 
i = 10
Mais sobre OpenMP 
● Site oficial 
http://openmp.org/ 
● OpenMP Forum 
http://openmp.org/forum/ 
● The Community of OpenMP Users, Researchers, Tool Developers and Providers 
http://www.compunity.org/ 
● C++ and OpenMP 
http://www.compunity.org/events/pastevents/parco07/parco_cpp_openmp.pdf 
● OpenMP C and C++ Application Program Interface 
http://www.openmp.org/mp-documents/cspec20.pdf
Referências 
https://computing.llnl.gov/tutorials/openMP 
http://openmp.org/mp-documents/OpenMP4.0.0.Examples.pdf 
http://www.cenapad.unicamp.br/servicos/treinamentos/apostilas/apostila_openmp.pdf

OpenMP

  • 1.
    OpenMP Valter Ferlete- valter.ferlete@ufms.br Programação Multi-Core - T01 11/09/2014
  • 2.
    OpenMP ● Origem; ● Visão Geral; ● Objetivos; ● Prós e Contras; ● Modelo de Memória e Execução; ● Serviços OpenMP; ● Variáveis de ambiente; ● Diretivas e Cláusulas.
  • 3.
    Origem ● Noinício dos anos 90, fabricantes de máquinas com memória compartilhada forneciam extensões para programação paralela em Fortran; ● As implementações permitiam ao usuário inserir diretivas para indicar onde loops deveriam ser paralelizados e os compiladores eram responsáveis pela paralelização; ● Implementações funcionalmente parecidas, mas não portáveis e começaram a divergir; ● ANSI X3H5 em 1994 foi a primeira tentativa de padronização.
  • 4.
    Origem ● Aespecificação padrão OpenMP começou em 1997 partindo do padrão X3H5 graças ao aparecimento de novas arquiteturas de máquinas de memória compartilhada; ● Alguns parceiros na especificação: ○ Compaq, HP, Intel, IBM, Silicon, Sun ○ Absoft, GENIAS, Myrias, The Portland Group ○ ANSYS, Dash, ILOG CPLEX, Livermore, NAG ● A API para Fortran foi liberada em Outubro de 1997 e para C/C++ no final de 1998.
  • 5.
  • 6.
    Visão Geral ●Biblioteca de mais alto nível para programação paralela; ● Prevê memória compartilhada; ● Requer suporte do compilador; ● Exige biblioteca específica com implementações thread safe.
  • 7.
  • 8.
    Objetivos OpenMP ●Prover um padrão para uma variedade de plataformas e arquiteturas baseadas em memória compartilhada; ● Estabelecer um conjunto limitado e simples de diretivas para programação utilizando memória compartilhada; ● Prover capacidade para paralelizar um programa de forma incremental; ● Implementar paralelismo com granulosidade fina e grossa ● Suportar Fortran, C e C++.
  • 9.
    Por que usarOpenMP? ● Facilidade de conversão de programas sequênciais em paralelos; ● Maneira simples de explorar paralelismo; ● Fácil compreensão e uso das diretivas; ● Minimiza a interferência na estrutura do algoritmo; ● Compila e executa em ambientes paralelos e sequencial.
  • 10.
    Por que nãousar OpenMP? ● Requer um compilador que suporta OpenMP; ● A escalabilidade é limitada pela arquitetura de memória; ● Manipulação segura do erro está em falta; ● Carece de mecanismo refinado para controlar o mapeamento thread-processor.
  • 11.
    Modelo de Memória ➔ Memória distribuída ● Sistema computacional constituído de vários processadores dotados de recursos individuais; ● Este sistema se caracteriza pela troca de mensagem entre os processadores; ● A troca de mensagem é feita por uma biblioteca de comunicação (MPI). Modelo de programação baseado em MPI
  • 12.
    Modelo de Memória ➔ Memória compartilhada ● Sistema computacional constituído de vários processadores que compartilham o mesmo recurso de memória; ● É necessário a sincronização do acesso aos dados na memória compartilhada pelos processadores. OpenMP, Threads, Posix Threads
  • 13.
  • 14.
    Modelo de ExecuçãoFork - Join OpenMP usa o modelo fork-join para paralelizar a execução FORK: A thread principal cria um grupo de threads paralelas; JOIN: Quando grupo threads completa a região paralela, ele sincroniza e finaliza, mantendo apenas a thread principal.
  • 15.
  • 16.
    Serviços do OpenMP ● Biblioteca de serviços ○ Permite controlar e interagir com o ambiente de execução. ● Exemplos: ○ omp_get_thread_num() ○ omp_set_num_threads(nthreads) ○ omp_get _num_threads() ○ omp_set_num_threads() ○ omp_get_max_threads() ○ omp_set_nested()
  • 17.
    Variáveis de ambiente ➢ OMP_NUM_THREADS ○ Identifica o número de atividades que serão executadas em paralelo; ○ (default: número de processadores). ➢ OMP_DYNAMIC ○ Indica se o número de atividades a serem executadas em paralelo deve ou não ser ajustado dinamicamente; ○ (default:FALSE). ➢ OMP_NESTED ○ Indica se deve ser contemplado ativação de paralelismo aninhado; ○ (default: FALSE). ➢ OMP_SCHEDULE ○ Define esquema de escalonamento das atividades paralelas. ○ (default: estático).
  • 18.
    Diretivas de compilação ➢ A maioria dos construtores em OpenMP são diretivas do compilador ou pragmas; ➢ Diretivas consiste em uma linha de código com significado “especial” para o compilador; ➢ Para C e C++, a diretiva possui a seguinte forma: ○ #pragma omp construct [clause [clause] …] ○ Ex. #pragma omp parallel ➢ Para Fortran: ○ !$OMP PARALLEL ➢ Pragma Parallel ○ Define uma região paralelizável sobre um bloco estruturado de código; ○ As threads bloqueiam no fim da região; ○ Os dados são compartilhados (shared) entre as threads ao menos que seja especificados de outra forma.
  • 19.
    Um exemplo genérico #include <omp.h> main ( ){ //Código seqüencial (master) #pragma omp parallel { // Código paralelo …. } // Código seqüencial (master) } Região Paralela
  • 20.
    Hello World #include<omp.h> #include <stdio.h> int main() { int nthreads; omp_set_num_threads(4); // Configura o número de treads #pragma omp parallel{ printf("Hello World da thread %dn", omp_get_thread_num()); if ( omp_get_thread_num() == 0 ) { nthreads = omp_get_num_threads(); printf("Existem %d threadsn",nthreads); } }// Final da Região Paralela return 0; }
  • 21.
    Compilar e executar Compilar: $ gcc -o hello -fopenmp hello.c Executar: $ export OMP_NUM_THREADS=2 (Opcional) $ .helloc
  • 22.
    Diretivas e Cláusulas ● Diretivas ○ Construtor Paralelo #pragma omp parallel ○ Construtores de trabalho #pragma omp for #pragma omp single #pragma omp sections ○ Construtores de sincronização #pragma omp critical #pragma omp master #pragma omp atomic #pragma omp barrier #pragma omp flush #pragma omp ordered #pragma omp threadprivate ● Cláusulas Definem o comportamento das regiões e das variáveis aos quais estão associadas shared private firstprivate lastprivate num_threads schedule default ordered copyn copyprivate if nowait reduction
  • 23.
    Diretiva / Construtorparalelo ● parallel ○ Informa ao compilador a existência de uma região que deve ser executada em paralelo. omp_set_num_threads(4); #pragma omp parallel { int i; printf(“n”); for( i = 0; i< 2; i++) printf(“Iteração = %dn”, i); }
  • 24.
    Diretiva / Construtorparalelo ● parallel Cláusula reduction ○ reduction(operador:variável), permite operar sobre o valor de uma variável; ○ Cada execução pode manipular sua cópia, como em private; ○ O valor local inicial é definido pela operação de redução; ○ No final uma operação de redução atualiza o dados na thread master. int soma=100; omp_set_num_threads(4); #pragma omp parallel reduction(+:soma) { soma +=1; } //No retorno ao master a soma=104
  • 25.
    Diretiva / Construtorde trabalho ● for / parallel for ○ Permite que os grupos de instruções definidas em um loop sejam paralelizadas. float dot_prod(float* a, float* b, int N){ float sum =0.0; #pragma omp parallel for shared(sum) for(int i=0;i<N;i++){ sum+=a[i]*b[i]; } return sum; }
  • 26.
    Paralelismo aninhado ●Dentro de uma região paralela, quando as threads encontram outro construtor paralelo, elas criam novos grupos de threads e tornam-se as threads mestre desses novos grupos; ● Essas regiões são denominadas regiões paralelas aninhadas e por padrão são executadas de forma sequêncial, ou seja, o novo grupo criado contém apenas uma thread, que é a própria thread mestre do grupo. #pragma omp parallel { #pragma omp parallel for for( int i = 0; i < n; i++ ){ #pragma omp parallel for for( int i = 0; i < n; i++ ) c[i] = a[i]+b[i]; } }
  • 27.
    Diretiva / Construtorde trabalho ● single ○ Indica que em uma região paralela ou um trecho de código deve ser executado apenas por uma única thread. #pragma omp parallel num_threads(6) { #pragma omp single printf(“ler a entrada”);//somente uma thread lê entrada printf(“calcular resultado”);//Várias threads calculam o resultado #pragma omp single printf(“escreve na saida”); // somente uma thread escreve na saída }
  • 28.
    Diretiva / Construtorde trabalho ● single [nowait] ○ com nowait a barreira pode ser relaxada. #pragma omp parallel { #pragma omp single printf(“Serão %d threads n”, omp_get_num_threads()) taskA(); #pragma omp single nowait printf(“A thread %d terminou n”, omp_get_thread_num()); }
  • 29.
    Diretiva / Construtorde trabalho ● sections ○ Cria seções paralelas; ○ Cada seção será executada em uma thread diferente. main (){ int x=2; #pragma omp sections{ #pragma omp section { taskA(x); } #pragma omp section { taskB(x); } } }
  • 30.
    Diretiva / Construtorde sincronização ● critical[(nome)] ○ Permite que trechos de código sejam executados em regime de exclusão mútua. int prox_x, prox_y; #pragma omp parallel shared(x,y) private (prox_x, prox_y) { #pragma omp critical(eixox) prox_x = dequeue(x); taskA(prox_x,x); #pragma omp critical(eixoy) prox_y = dequeue(y); taskA(prox_y,y); }
  • 31.
    Diretiva / Construtorde sincronização ● master [nowait] ○ Indica que em uma região paralela ou um trecho de código deve ser executado apenas pela thread master; ○ Representa uma barreira; ○ com nowait a barreira pode ser relaxada. #pragma omp parallel { #pragma omp master printf(“Serão %d threads n”, omp_get_num_threads()); foo(); #pragma omp master nowait printf(“A thread master terminou n”); }
  • 32.
    Diretiva / Construtorde sincronização ● atomic [read, write, update e capture] Especifica que uma posição de memória deve ser atualizada atomicamente. #pragma omp atomic ● barrier Quando esta directiva é alcançada por uma thread, este espera até que os restantes chegem ao mesmo ponto. #pragma omp barrier ● flush Identifica um ponto de sincronização no qual é necessário providenciar uma visão consistente memória. #pragma omp flush
  • 33.
    Cláusula - Schedule ● Cláusula: schedule ○ Afeta como as iterações do laço são mapeadas entre as threads ○ schedule(static [,chunk]) ■ Blocos de iterações de tamanho “chunk” ■ Distribuição Round robin ○ schedule(dynamic [,chunk]) ■ Iteração de tamanho “chunk” ■ Ao terminar as iterações, a thread requisita o próximo passo ○ schedule(guided [,chunk]) ■ Agendamento dinâmico iniciado com um tamanho grande ■ O tamanho dos blocos diminui, não menor do que “chunk”
  • 34.
  • 35.
    Cláusula - Schedule ● Cláusula: schedule (Exemplo) #pragma omp parallel for schedule (static, 4) shared(qtdePrimos) for(i = 0; i < 500; i++){ if (testaPrimo(i) == 1){ #pragma omp atomic qtdePrimos++; } } $ export OMP_SCHEDULE=“static,4”
  • 36.
    Cláusula - IF ● Cláusula: if(expressão lógica) ○ Se a expressão lógica for verdadeira a região paralela será executada por mais de uma thread. void test(int val){ #pragma omp parallel if (val==2) if (omp_in_parallel()){ #pragma omp single printf("val = %d, paralelizado com %d threadsn", val, omp_get_num_threads()); }else { printf("val = %d, serializadon", val); } } Chamando: test(0); test(1); test(2); Saída: val = 0, serializado val = 1, serializado val = 2, paralelizado com 2 threads
  • 37.
    Cláusula - Private ● Cláusula: private ○ Especifica que cada thread deve ter sua própria instância de uma variável; ○ A variável não é inicializada; ○ Alterações de valor dentro da região paralela não são visíveis fora; ○ Utilizando firstprivate ou lastprivate o valor de i é inicializado com o valor antes do início da região paralela. int i=10; #pragma omp parallel private(i) { printf("thread %d: i = %dn", omp_get_thread_num(), i); i = 100 + omp_get_thread_num(); } printf("i = %dn", i); thread 0: i = 0 thread 3: i = 0 thread 1: i = 32696 thread 2: i = 0 i = 10
  • 38.
    Mais sobre OpenMP ● Site oficial http://openmp.org/ ● OpenMP Forum http://openmp.org/forum/ ● The Community of OpenMP Users, Researchers, Tool Developers and Providers http://www.compunity.org/ ● C++ and OpenMP http://www.compunity.org/events/pastevents/parco07/parco_cpp_openmp.pdf ● OpenMP C and C++ Application Program Interface http://www.openmp.org/mp-documents/cspec20.pdf
  • 39.
    Referências https://computing.llnl.gov/tutorials/openMP http://openmp.org/mp-documents/OpenMP4.0.0.Examples.pdf http://www.cenapad.unicamp.br/servicos/treinamentos/apostilas/apostila_openmp.pdf