OpenMP

39
OpenMP Valter Ferlete - [email protected] Programação Multi-Core - T01 11/09/2014

description

Introdução ao OpenMP

Transcript of OpenMP

Page 1: OpenMP

OpenMPValter Ferlete - [email protected]

Programação Multi-Core - T0111/09/2014

Page 2: OpenMP

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.

Page 3: OpenMP

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.

Page 4: OpenMP

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.

Page 5: OpenMP

Linha do tempo

Page 6: OpenMP

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.

Page 7: OpenMP

OpenMP

Page 8: 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++.

Page 9: OpenMP

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.

Page 10: OpenMP

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.

Page 11: OpenMP

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

Page 12: OpenMP

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

Page 13: OpenMP

Thread Overview

Page 14: OpenMP

Modelo de Execução Fork - Join

OpenMP usa o modelo fork-join para paralelizar a execuçãoFORK: 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.

Page 15: OpenMP

Organização do OpenMP

Page 16: 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()

Page 17: OpenMP

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).

Page 18: OpenMP

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.

Page 19: OpenMP

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

Page 20: OpenMP

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 %d\n", omp_get_thread_num()); if ( omp_get_thread_num() == 0 ) { nthreads = omp_get_num_threads(); printf("Existem %d threads\n",nthreads); } }// Final da Região Paralela return 0;}

Page 21: OpenMP

Compilar e executarCompilar: $ gcc -o hello -fopenmp hello.c

Executar: $ export OMP_NUM_THREADS=2 (Opcional)$ .\helloc

Page 22: OpenMP

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áusulasDefinem o comportamento das regiões e das variáveis aos quais estão associadas

sharedprivatefirstprivatelastprivatenum_threadsscheduledefault

orderedcopyncopyprivateifnowaitreduction

Page 23: OpenMP

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 = %d\n”, i);}

Page 24: OpenMP

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

Page 25: OpenMP

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;

}

Page 26: OpenMP

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 forfor( int i = 0; i < n; i++ ){

#pragma omp parallel forfor( int i = 0; i < n; i++ )

c[i] = a[i]+b[i];}

}

Page 27: OpenMP

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 singleprintf(“ler a entrada”);//somente uma thread lê entrada

printf(“calcular resultado”);//Várias threads calculam o resultado

#pragma omp singleprintf(“escreve na saida”); // somente uma thread escreve na saída

}

Page 28: OpenMP

Diretiva / Construtor de trabalho● single [nowait]

○ com nowait a barreira pode ser relaxada.

#pragma omp parallel{

#pragma omp singleprintf(“Serão %d threads \n”, omp_get_num_threads())taskA();#pragma omp single nowaitprintf(“A thread %d terminou \n”, omp_get_thread_num());

}

Page 29: OpenMP

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); }

}}

Page 30: OpenMP

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);

}

Page 31: OpenMP

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 masterprintf(“Serão %d threads \n”, omp_get_num_threads());foo();#pragma omp master nowaitprintf(“A thread master terminou \n”);

}

Page 32: OpenMP

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

● barrierQuando esta directiva é alcançada por uma thread, este espera até que os

restantes chegem ao mesmo ponto.#pragma omp barrier

● flushIdentifica um ponto de sincronização no qual é necessário providenciar uma

visão consistente memória.#pragma omp flush

Page 33: OpenMP

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”

Page 34: OpenMP

Cláusula - Schedule

Page 35: OpenMP

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”

Page 36: OpenMP

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 singleprintf("val = %d, paralelizado com %d threads\n", val,

omp_get_num_threads());}else { printf("val = %d, serializado\n", val);}

}

Saída:

val = 0, serializadoval = 1, serializadoval = 2, paralelizado com 2 threads

Chamando:

test(0);test(1);test(2);

Page 37: OpenMP

Cláusula - Private

int i=10;#pragma omp parallel private(i){

printf("thread %d: i = %d\n", omp_get_thread_num(), i);i = 100 + omp_get_thread_num();

}printf("i = %d\n", i);

● 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.

thread 0: i = 0thread 3: i = 0thread 1: i = 32696thread 2: i = 0i = 10

Page 38: OpenMP

Mais sobre OpenMP● Site oficialhttp://openmp.org/● OpenMP Forumhttp://openmp.org/forum/● The Community of OpenMP Users, Researchers, Tool Developers and Providershttp://www.compunity.org/● C++ and OpenMPhttp://www.compunity.org/events/pastevents/parco07/parco_cpp_openmp.pdf● OpenMP C and C++ Application Program Interfacehttp://www.openmp.org/mp-documents/cspec20.pdf