29
INTRODUÇÃO AO OPENMP PROF. ANDRÉ LEON S. GRADVOHL, DR. [email protected]

Introdução ao OpenMP

  • Upload
    idana

  • View
    40

  • Download
    0

Embed Size (px)

DESCRIPTION

Introdução ao OpenMP. Prof. André Leon S. Gradvohl , Dr . [email protected]. Arquiteturas paralelas. Arquiteturas paralelas: Single Instruction Multiple Data Máquinas Vetoriais Multiple Instruction Multiple Data Memória distribuída Memória compartilhada. - PowerPoint PPT Presentation

Citation preview

Page 1: Introdução ao  OpenMP

INTRODUÇÃO AO OPENMP

PROF. ANDRÉ LEON S. GRADVOHL, [email protected]

Page 2: Introdução ao  OpenMP

2

ARQUITETURAS PARALELAS

Arquiteturas paralelas:• Single Instruction Multiple Data

• Máquinas Vetoriais• Multiple Instruction Multiple Data

• Memória distribuída• Memória compartilhada

Onde o OpenMP se encaixa

Page 3: Introdução ao  OpenMP

3

MODELOS DE PROGRAMAÇÃO PARALELA

Modelos de Programação Paralela

• Multiprocessamento• Fork/Join

• Passagem de Mensagens• Exemplo: PVM, MPI

• Multithread• Exemplo: OpenMP, POSIX-Threads

OpenMP (Open MultiProcessing):

• Interface de programação que suporta multiprocessamento em ambientes de memória compartilhada.

Page 4: Introdução ao  OpenMP

4

INTRODUÇÃO AO OPENMP

Estrutura de um programa OpenMP:

• Em Fortran:

PROGRAM HELLOINTEGER VAR1, VAR2, VAR3*** Código serial*** Início da seção paralela. “Fork” um grupo de “threads”.!$OMP PARALLEL PRIVATE(VAR1, VAR2) SHARED(VAR3)*** Seção paralela executada por todas as “threads”*** Todas as “threads” efetuam um “join” a thread mestre e finalizam!$OMP END PARALLEL*** Código serialEND

Page 5: Introdução ao  OpenMP

5

INTRODUÇÃO AO OPENMP

Estrutura de um programa OpenMP:

• Em C:

#include <omp.h>int main () {int var1, var2, var3;*** Código serial*** Início da seção paralela. “Fork” um grupo de “threads”.#pragma omp parallel private(var1, var2) shared(var3){*** Seção paralela executada por todas as “threads”*** Todas as “threads” efetuam um “join” a thread mestre e finalizam}*** Código serial}

Page 6: Introdução ao  OpenMP

6

INTRODUÇÃO AO OPENMP

ObservaçõesFork/Join:

• Quando uma thread chega a uma definição de região paralela, ela cria um conjunto de threads e passa a ser a thread mestre. A thread mestre faz parte do conjunto de threads e possui o número de identificação “0”.

• A partir do início da região paralela, o código é duplicado e todas as threads executarão esse código.

• Existe um ponto de sincronização (“barreira”) no final da região paralela, sincronizando o fim de execução de cada thread. Somente a thread mestre continua desse ponto.

BARR

Page 7: Introdução ao  OpenMP

7

INTRODUÇÃO AO OPENMP

Observações• O número de threads

• Em uma execução com o OpenMP, o número de “threads” é determinado pelos seguintes fatores, em ordem de precedência:1. Utilização da função omp_set_num_threads() no código

Fortran ou C/C++;2. Definindo a variável de ambiente OMP_NUM_THREADS,

antes da execução;3. Implementação padrão do ambiente: número de processadores

em um nó.• Restrições

• Não é permitido caminhar para dentro ou fora (”branch”) de uma estrutura de blocos definida por uma diretiva OpenMP e somente um IF é permitido.

Page 8: Introdução ao  OpenMP

EXEMPLO#include <stdio.h>

#include <omp.h>

int main ()

{ int nthreads, tid;

#pragma omp parallel private(nthreads, tid)

{

tid = omp_get_thread_num();

printf(“Ola Mundo do thread = %d\n”, tid);

if (tid == 0)

{

nthreads = omp_get_num_threads();

printf(“Numero de threads = %d\n”, nthreads);

}

}

}

Faz o fork dos threads e mantém suas próprias

cópias de variáveis.Obtém o número do Thread.

Se tid == 0, então é o thread mestre.

Obtém a quantidade de threads.

Região Paralela

Page 9: Introdução ao  OpenMP

9

CRIAÇÃO DE THREADS#include <stdio.h>

#include <omp.h>

int main()

{

double A[1000];

#pragma omp parallel num_threads(4)

{

int ID = omp_get_thread_num();

pooh(ID,A);

}

return 0;

}

Criação de 4 threads.

Obtém o número do

thread.

Page 10: Introdução ao  OpenMP

10

CRIAÇÃO DE THREADS – EXERCÍCIOSMatematicamente sabe-se que:

Portanto, é possível aproximar esta integral como um somatório:

Onde cada retângulo tem largura x e altura F(xi) no meio do intervalo i.

1

02 )1(

4 x

n

ii xxF

0

)(

Page 11: Introdução ao  OpenMP

11

CRIAÇÃO DE THREADS – EXERCÍCIOSSolução Serial:

static long num_steps = 100000;

double step;

int main ()

{

int i; double x, pi, sum = 0.0;

step = 1.0/(double) num_steps;

for (i=0;i< num_steps; i++){

x = (i+0.5)*step;

sum = sum + 4.0/(1.0+x*x);

}

pi = step * sum;

}

Page 12: Introdução ao  OpenMP

12

CRIAÇÃO DE THREADS – EXERCÍCIOSSolução Paralela

static long num_steps = 100000000;

double step;

int main ()

{

int i,j;

double pi, full_sum = 0.0;

double sum[MAX_THREADS];

step = 1.0/(double) num_steps;

Page 13: Introdução ao  OpenMP

13

CRIAÇÃO DE THREADS – EXERCÍCIOS omp_set_num_threads(MAX_THREADS);

full_sum=0.0;

#pragma omp parallel

{

int i;

int id = omp_get_thread_num();

int numthreads = omp_get_num_threads();

double x;

sum[id] = 0.0;

if (id == 0) printf(" num_threads = %d",numthreads);

for (i=id;i< num_steps; i+=numthreads){

x = (i+0.5)*step;

sum[id] = sum[id] + 4.0/(1.0+x*x);

}

}

Região Paralela

Page 14: Introdução ao  OpenMP

14

CRIAÇÃO DE THREADS – EXERCÍCIOS for(full_sum = 0.0, i=0;i< MAX_THREADS;i++)

full_sum += sum[i];

pi = step * full_sum;

}Agrupamento dos

resultados.(Redução)

Page 15: Introdução ao  OpenMP

15

DIRETIVA DO/FORA diretiva DO/for especifica que as iterações de um laço sejam distribuídas e executadas em paralelo pelo grupo de threads. A região paralela tem que ter sido identificada antes.

Com isso, o programador não precisa de preocupar com a divisão da carga de trabalho entre os threads

Exemplo:

#pragma omp parallel

{

#pragma omp for

for (I=0;I<N;I++)

Faca_algo(I);

}

Define uma região paralela

O comando for será dividido igualmente entre os threads.

Detalhe:a variável I é privativa.

Page 16: Introdução ao  OpenMP

16

DIRETIVA DO/FORAlternativamente, pode-se utilizar a seguinte sintaxe:

Exemplo:

#pragma omp parallel for

for (I=0;I<N;I++) Faca_algo(I);

Cuidado com o uso de outras variáveis dento de um “laço paralelo”!!

As variáveis do laço são privativas de cada thread.

Exemplo:int i, j, A[MAX];j = 5;for (i=0;i< MAX; i++) {

j = j+ 2*i;A[i] = big(j);

}

Page 17: Introdução ao  OpenMP

17

DIRETIVA DO/FOR - REDUÇÃOComo resolver o caso ao lado?

double ave=0.0, A[MAX]; int i;

for (i=0;i< MAX; i++) {

ave + = A[i];

}

ave = ave/MAX;

Resposta: usando uma redução !double ave=0.0, A[MAX]; int i;#pragma omp parallel for reduction (+:ave)for (i=0;i< MAX; i++) {

ave + = A[i];}ave = ave/MAX;

Page 18: Introdução ao  OpenMP

18

DIRETIVA DO/FOR – REDUÇÃO – MAIS DETALHESDentro de uma região paralela:

• É feita uma cópia local de cada variável e inicializada com um valor que depende do tipo de operação, e. g., na operação de + o valor inicial é zero.

• As cópias locais são reduzidas (somadas, multiplicadas etc) em um único valor que, posteriormente, são combinados em uma única variável comum.

Como fica o programa para calcular o com a diretiva for e a redução?

Page 19: Introdução ao  OpenMP

19

DIRETIVA DO/FOR – REDUÇÃO – MAIS DETALHESSolução Paralela

static long num_steps = 100000000;

double step;

int main ()

{

int i,j;

double x, pi, sum = 0.0;

double sum[MAX_THREADS];

step = 1.0/(double) num_steps;

Page 20: Introdução ao  OpenMP

20

DIRETIVA DO/FOR – REDUÇÃO – MAIS DETALHESomp_set_num_threads(MAX_THREADS); sum=0.0;

#pragma omp parallel for reduction (+:sum)

for (i=1;i< num_steps; i++){

x = (i-0.5)*step;

sum= sum + 4.0/(1.0+x*x);

}

pi = step * sum;

}

Região Paralela com redução

Page 21: Introdução ao  OpenMP

21

ATRIBUTOS DE VARIÁVEISAs variáveis no OpenMP podem ser compartilhadas ou não entre os threads. Esse controle é feito através de alguns atributos. São eles:

private: Declara que as variáveis listadas serão de uso específico de cada “thread”. Essas variáveis não são iniciadas.

shared (default) Declara que as variáveis listadas compartilharão o seu conteúdo com todas as threads de um grupo. As variáveis existem em apenas um endereço de memória, que pode ser lido e escrito por todas as threads do grupo.

Page 22: Introdução ao  OpenMP

22

ATRIBUTOS DE VARIÁVEIS

firstprivate: Define uma lista de variáveis com o atributo PRIVATE, mas sendo inicializadas automaticamente, de acordo com o valor que possuíam no thread antes de uma região paralela.

lastprivate: Define uma lista de variáveis com o atributo PRIVATE e copia o valor da última iteração de um laço da última thread que finalizou.

default: Permite que o programador defina o atributo “default” para as variáveis em uma região paralela (PRIVATE, SHARED ou NONE).

Page 23: Introdução ao  OpenMP

23

ATRIBUTOS DE VARIÁVEIS EXEMPLOS

void useless() {

int tmp = 0;

#pragma omp parallel for firstprivate(tmp)

for (int j = 0; j < 1000; ++j)

tmp += j;

printf(“%d\n”, tmp);

}

Cada thread possui sua própria cópia da variável tmp com o valor inicial zero.

Page 24: Introdução ao  OpenMP

24

ATRIBUTOS DE VARIÁVEIS EXEMPLOS

void useless() {

int tmp = 0;

#pragma omp parallel for firstprivate(tmp) lastprivate(tmp)

for (int j = 0; j < 1000; ++j)

tmp += j;

printf(“%d\n”, tmp);

}

A variável tmp termina com o valor do calculado pelo último thread a terminar.

Page 25: Introdução ao  OpenMP

25

SEÇÕESA diretiva sections divide o trabalho de forma não iterativa em seções separadas, aonde cada seção será executada por uma “thread” do grupo. Representa a implementação de paralelismo funcional, ou seja, por código.

Algumas observações:

1. A diretiva sections define a seção do código sequencial onde será definida as seções independentes, através da diretiva section;

2. Cada section é executada por uma thread do grupo;

3. Existe um ponto de sincronização implícita no final da diretiva section, a menos que se especifique o atributo nowait;

4. Se existirem mais threads do que seções, o OpenMP decidirá, quais threads executarão os blocos de section, e quais, não executarão.

Page 26: Introdução ao  OpenMP

26

SEÇÕES- EXEMPLO

#include <omp.h>

#define N 1000

int main () {

int i, n=N;

float a[N], b[N], c[N];

for (i=0; i < N; i++) a[i] = b[i] = i * 1.0;

#pragma omp parallel shared(a,b,c,n) private(i) {

#pragma omp sections nowait {

#pragma omp section

for (i=0; i < n/2; i++)

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

#pragma omp section

for (i=n/2; i < n; i++)

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

} /* fim seções*/

} /* fim parallel */

}

Definição de uma área de seções.

Primeira seção

Segunda seção

Page 27: Introdução ao  OpenMP

27

UNICIDADEA diretiva single determina que o código identificado seja executado por somente uma thread do grupo.

Os threads do grupo que não executam a diretiva single, esperam o fim do processamento da thread que executa a diretiva, a menos que se especifique o atributo nowait.

A diretiva ordered determina que as iterações do laço na região paralela, sejam executados na ordem sequêncial.

Page 28: Introdução ao  OpenMP

28

UNICIDADE- EXEMPLOS#pragma omp parallel

{

do_many_things();

#pragma omp single

{

exchange_boundaries();

}

do_many_other_things();

}

Apenas um thread vai executar esse trecho de código.

Detalhe: nesse caso todos os threads aguardarão até que o bloco single seja

executado.

Page 29: Introdução ao  OpenMP

29

UNICIDADE- EXEMPLOS#pragma omp parallel private (tmp)

#pragma omp for ordered reduction(+:res)

for (I=0;I<N;I++){

tmp = NEAT_STUFF(I);

#pragma ordered

res += consum(tmp);

}

Os threads executarão os trechos de código um de cada vez, de forma

sequencial.