A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

Prof. André Leon S. Gradvohl, Dr.

Apresentações semelhantes


Apresentação em tema: "Prof. André Leon S. Gradvohl, Dr."— Transcrição da apresentação:

1 Prof. André Leon S. Gradvohl, Dr. gradvohl@ft.unicamp.br
Introdução ao OpenMP Prof. André Leon S. Gradvohl, Dr.

2 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

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

4 Introdução ao OpenMP Estrutura de um programa OpenMP: Em Fortran:
PROGRAM HELLO INTEGER 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 END

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 }

6 Introdução ao OpenMP Observações B A RR Fork/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. B A RR

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: Utilização da função omp_set_num_threads() no código Fortran ou C/C++; Definindo a variável de ambiente OMP_NUM_THREADS, antes da execução; 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.

8 3/30/2017 9:16 PM Exemplo Faz o fork dos threads e mantém suas próprias cópias de variáveis. Região Paralela Obtém o número do Thread. #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); } Se tid == 0, então é o thread mestre. Obtém a quantidade de threads. © 2007 Microsoft Corporation. All rights reserved. Microsoft, Windows, Windows Vista and other product names are or may be registered trademarks and/or trademarks in the U.S. and/or other countries. The information herein is for informational purposes only and represents the current view of Microsoft Corporation as of the date of this presentation. Because Microsoft must respond to changing market conditions, it should not be interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information provided after the date of this presentation. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.

9 Obtém o número do thread.
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.

10 Criação de Threads – Exercícios
Matematicamente 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.

11 Criação de Threads – Exercícios
Solução Serial: static long num_steps = ; 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;

12 Criação de Threads – Exercícios
Solução Paralela static long num_steps = ; double step; int main () { int i,j; double pi, full_sum = 0.0; double sum[MAX_THREADS]; step = 1.0/(double) num_steps;

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

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)

15 Define uma região paralela
Diretiva DO/for Define uma região paralela A 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); } O comando for será dividido igualmente entre os threads. Detalhe:a variável I é privativa.

16 Diretiva DO/for Alternativamente, 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); }

17 Diretiva DO/for - Redução
Como 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;

18 Diretiva DO/for – Redução – mais detalhes
Dentro 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?

19 Diretiva DO/for – Redução – mais detalhes
Solução Paralela static long num_steps = ; double step; int main () { int i,j; double x, pi, sum = 0.0; double sum[MAX_THREADS]; step = 1.0/(double) num_steps;

20 Diretiva DO/for – Redução – mais detalhes
omp_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

21 Atributos de variáveis
As 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.

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

23 Atributos de variáveis exemplos
Cada thread possui sua própria cópia da variável tmp com o valor inicial zero. void useless() { int tmp = 0; #pragma omp parallel for firstprivate(tmp) for (int j = 0; j < 1000; ++j) tmp += j; printf(“%d\n”, tmp); }

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.

25 Seções A 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: A diretiva sections define a seção do código sequencial onde será definida as seções independentes, através da diretiva section; Cada section é executada por uma thread do grupo; Existe um ponto de sincronização implícita no final da diretiva section, a menos que se especifique o atributo nowait; 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.

26 Definição de uma área de seções.
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]; for (i=n/2; i < n; i++) } /* fim seções*/ } /* fim parallel */ } Definição de uma área de seções. Primeira seção Segunda seção

27 Unicidade A 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.

28 Apenas um thread vai executar esse trecho de código.
Unicidade- Exemplos 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. #pragma omp parallel { do_many_things(); #pragma omp single exchange_boundaries(); } do_many_other_things();

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.


Carregar ppt "Prof. André Leon S. Gradvohl, Dr."

Apresentações semelhantes


Anúncios Google