47
OpenMP Aleardo Manacero Jr.

OpenMP - dcce.ibilce.unesp.braleardo/cursos/hpc/openMP2020.… · Programa OpenMP começa com um thread sequencial Para criar novos threads o usuário define uma região paralela

  • Upload
    others

  • View
    2

  • Download
    0

Embed Size (px)

Citation preview

Page 1: OpenMP - dcce.ibilce.unesp.braleardo/cursos/hpc/openMP2020.… · Programa OpenMP começa com um thread sequencial Para criar novos threads o usuário define uma região paralela

OpenMP

Aleardo Manacero Jr.

Page 2: OpenMP - dcce.ibilce.unesp.braleardo/cursos/hpc/openMP2020.… · Programa OpenMP começa com um thread sequencial Para criar novos threads o usuário define uma região paralela

Copyright Notice

Material parcialmente retirado de“Introduction to OpenMP”, por Rudi Eigenmann -- [email protected], Bob Kuhn -- [email protected], Tim Mattson -- [email protected], e Ramesh Menon -- [email protected]

Copyright © 1997-99 OpenMP Architecture Review Board.

E também de “OpenMP”, por Blaise Barney – Lawrence Livermore Laboratory, https://computing.llnl.gov/tutorials/openMP/

Page 3: OpenMP - dcce.ibilce.unesp.braleardo/cursos/hpc/openMP2020.… · Programa OpenMP começa com um thread sequencial Para criar novos threads o usuário define uma região paralela

Introdução

API portável para sistemas multiprocessadores de memória compartilhada

Fortran 77, Fortran 90, C, C++ Suporte para UNIX e NT

Padroniza paralelismo em grão fino (laços)

Suporta algoritmos de grão grosso

É baseada em diretivas de compilação

Page 4: OpenMP - dcce.ibilce.unesp.braleardo/cursos/hpc/openMP2020.… · Programa OpenMP começa com um thread sequencial Para criar novos threads o usuário define uma região paralela

Introdução

Não é uma nova linguagem

São diretivas, bibliotecas e variáveis de ambientes extendendo uma linguagem básica: f77, f90, C, C++

Não faz paralelização automática

Usuário explicitamente especifica as regiões de execução paralela

Compilador faz a paralelização dessas regiões

Page 5: OpenMP - dcce.ibilce.unesp.braleardo/cursos/hpc/openMP2020.… · Programa OpenMP começa com um thread sequencial Para criar novos threads o usuário define uma região paralela

ArquiteturaCódigo fonte (C, p.ex.), com diretivas openMP

Page 6: OpenMP - dcce.ibilce.unesp.braleardo/cursos/hpc/openMP2020.… · Programa OpenMP começa com um thread sequencial Para criar novos threads o usuário define uma região paralela

Modelo de uso em C

Threads com índices locais e vetor compartilhado entre threads

main() {

#pragma omp parallel for \

shared(A)private(i)

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

. . .

}

}

Page 7: OpenMP - dcce.ibilce.unesp.braleardo/cursos/hpc/openMP2020.… · Programa OpenMP começa com um thread sequencial Para criar novos threads o usuário define uma região paralela

Modelo de paralelização

Programa OpenMP começa com um thread sequencial

Para criar novos threads o usuário define uma região paralela

Threads trabalhadores são disparados

Mestre é parte dos threads trabalhadores

Threads saem ao final da região paralela (dormem)

Modelo Fork-Join

Page 8: OpenMP - dcce.ibilce.unesp.braleardo/cursos/hpc/openMP2020.… · Programa OpenMP começa com um thread sequencial Para criar novos threads o usuário define uma região paralela

Visão geral de construções OpenMP

Binding Nesting

Conditional Compilation

If()

Parallel Region

Schedule()

Ordered

Do

Sections

Single

Work Sharing

Control Constructs

ThreadPrivate

Shared()

FirstPrivate()

LastPrivate()

Private()

Reduction(:)

CopyIn()

Default()

Data Scope

Data Constructs

Master

Critical

Barrier

Atomic

Ordered

Synchronization Constructs

Directives

Environment Functions

Lock Functions

Runtime Library

Static

Dynamic,chunk

Guided,chunk

OMP_SCHEDULE

OMP_NUM_THREADS

OMP_DYNAMIC

OMP_NESTED

Environment Variables

OpenMP

Page 9: OpenMP - dcce.ibilce.unesp.braleardo/cursos/hpc/openMP2020.… · Programa OpenMP começa com um thread sequencial Para criar novos threads o usuário define uma região paralela

Criando threads em OpenMP

Apenas uma forma de criar threads em OpenMP

FortranC$OMP PARALLEL Code to be executed by each threadC$OMP END PARALLEL

C#pragma omp parallel { Code to be executed by each thread}

Page 10: OpenMP - dcce.ibilce.unesp.braleardo/cursos/hpc/openMP2020.… · Programa OpenMP começa com um thread sequencial Para criar novos threads o usuário define uma região paralela

Criando threads em OpenMP

A diretiva parallel pode receber cláusulas de execução

Essas cláusulas podem definir número de threads ou que variáveis serão compartilhadas entre threads

#pragma omp parallel num_threads ( that_many ){ Code to be executed by each thread}

#pragma omp parallel shared(A) private(i){ Code to be executed by each thread}

Page 11: OpenMP - dcce.ibilce.unesp.braleardo/cursos/hpc/openMP2020.… · Programa OpenMP começa com um thread sequencial Para criar novos threads o usuário define uma região paralela

Variáveis nos threads

Variáveis podem ser passadas aos threads de vários modos

Como openMP funciona em memória compartilhada, o modo padrão é que sejam compartilhadas entre threads

Fora isso podem ser privativas (private) a cada thread

Ou terem valor inicial comum (firstprivate) ou valor final “comum” (lastprivate)

Page 12: OpenMP - dcce.ibilce.unesp.braleardo/cursos/hpc/openMP2020.… · Programa OpenMP começa com um thread sequencial Para criar novos threads o usuário define uma região paralela

Exclusão Mútua

Pode ser implementada de duas formas:

Região crítica

Execução atômica

Page 13: OpenMP - dcce.ibilce.unesp.braleardo/cursos/hpc/openMP2020.… · Programa OpenMP começa com um thread sequencial Para criar novos threads o usuário define uma região paralela

Região críticaPodem ser nomeadas e nomes são globais

Não podem conflitar com nomes de funções e outras entidades globais

#pragma omp parallel { …… #pragma omp critical(left) A[i] += Alocal ……}

Exclusão Mútua

Page 14: OpenMP - dcce.ibilce.unesp.braleardo/cursos/hpc/openMP2020.… · Programa OpenMP começa com um thread sequencial Para criar novos threads o usuário define uma região paralela

Execução atômicaNão são estruturáveis

É aplicada apenas ao comando seguinte

Otimizam a exclusão mútua se o hardware permitir

#pragma omp parallel { …… #pragma omp atomic A[i] += Alocal ……}

Exclusão Mútua

Page 15: OpenMP - dcce.ibilce.unesp.braleardo/cursos/hpc/openMP2020.… · Programa OpenMP começa com um thread sequencial Para criar novos threads o usuário define uma região paralela

Execução sequencialÉ utilizada para o controle de laços de repetição

Além de garantir a exclusão mútua obriga também a execução sequencial do laço

#pragma omp parallel { …… #pragma omp ordered printf(“%d\n”, i); ……}

Exclusão Mútua

Page 16: OpenMP - dcce.ibilce.unesp.braleardo/cursos/hpc/openMP2020.… · Programa OpenMP começa com um thread sequencial Para criar novos threads o usuário define uma região paralela

Barreira de sincronismo

Diretiva BARRIER

Threads esperam chegada de todos

Barreira implícita ao final de cada região paralela

#pragma omp parallel { ……

#pragma omp barrier ……}

Page 17: OpenMP - dcce.ibilce.unesp.braleardo/cursos/hpc/openMP2020.… · Programa OpenMP começa com um thread sequencial Para criar novos threads o usuário define uma região paralela

Laços de repetição

Diretiva DO/for

Deve estar dentro de um trecho paralelo

Divide as iterações entre os threads

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

#pragma omp for schedule(dynamic,chunk) nowait

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

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

} /* end of parallel region */

Page 18: OpenMP - dcce.ibilce.unesp.braleardo/cursos/hpc/openMP2020.… · Programa OpenMP começa com um thread sequencial Para criar novos threads o usuário define uma região paralela

Atribuindo trabalho aos threads

Atributo schedule

Pode ser estático, dinâmico, guiado ou runtime

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

#pragma omp for schedule(static, chunk) nowait

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

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

} /* end of parallel region */

Page 19: OpenMP - dcce.ibilce.unesp.braleardo/cursos/hpc/openMP2020.… · Programa OpenMP começa com um thread sequencial Para criar novos threads o usuário define uma região paralela

Atribuindo trabalho aos threads

Escalonamento estático

Page 20: OpenMP - dcce.ibilce.unesp.braleardo/cursos/hpc/openMP2020.… · Programa OpenMP começa com um thread sequencial Para criar novos threads o usuário define uma região paralela

Atribuindo trabalho aos threads

Escalonamento dinâmico e guiado

Page 21: OpenMP - dcce.ibilce.unesp.braleardo/cursos/hpc/openMP2020.… · Programa OpenMP começa com um thread sequencial Para criar novos threads o usuário define uma região paralela

Seções

Diretiva SECTION

Atribui tarefas distintas aos threads

#pragma omp sections nowait {

#pragma omp section

do_a_section

#pragma omp section

do_another_section

} /* end of sections region */

Page 22: OpenMP - dcce.ibilce.unesp.braleardo/cursos/hpc/openMP2020.… · Programa OpenMP começa com um thread sequencial Para criar novos threads o usuário define uma região paralela

Seção do thread mestre

Diretiva MASTER

Trecho executado apenas pelo thread principal

Demais threads continuam a execução depois da seção master

#pragma omp parallel { ……

#pragma omp master printf(“Hello World”);

……}

Page 23: OpenMP - dcce.ibilce.unesp.braleardo/cursos/hpc/openMP2020.… · Programa OpenMP começa com um thread sequencial Para criar novos threads o usuário define uma região paralela

Seção de thread único

Diretiva SINGLE

Trecho executado apenas por um dos threads Demais threads continuam a execução depois da seção single

#pragma omp parallel { ……

#pragma omp single printf(“Hello World”);

……}

Page 24: OpenMP - dcce.ibilce.unesp.braleardo/cursos/hpc/openMP2020.… · Programa OpenMP começa com um thread sequencial Para criar novos threads o usuário define uma região paralela

Um exemplo

Hello World paralelo

Dispara um conjunto de threads, sendo que cada um imprime o seu ID

O thread principal imprime o total de threads disparados

Page 25: OpenMP - dcce.ibilce.unesp.braleardo/cursos/hpc/openMP2020.… · Programa OpenMP começa com um thread sequencial Para criar novos threads o usuário define uma região paralela

Um exemplo

#include <omp.h>#include <stdio.h>#include <stdlib.h>

int main (int argc, char *argv[]) {int nthreads, tid;

/* Dispara threads com suas cópias das variáveis */#pragma omp parallel private (nthreads, tid) { /* Descobre seu ID */ tid = omp_get_thread_num(); printf("Hello World from thread = %d\n", tid);

Page 26: OpenMP - dcce.ibilce.unesp.braleardo/cursos/hpc/openMP2020.… · Programa OpenMP começa com um thread sequencial Para criar novos threads o usuário define uma região paralela

Um exemplo

/* Só o thread principal (mestre) faz isso */ if (tid == 0) { nthreads = omp_get_num_threads(); printf("Number of threads = %d\n", nthreads); }

} /* Todos os threads se juntam ao thread principal e “somem” */

}

Page 27: OpenMP - dcce.ibilce.unesp.braleardo/cursos/hpc/openMP2020.… · Programa OpenMP começa com um thread sequencial Para criar novos threads o usuário define uma região paralela

Um exemplo

Para compilar esse código o comando é

gcc -o hello arquivo.c -fopenmp

Antes de executar é preciso definir o número de threads, 8 nesse exemplo, com

export OMP_NUM_THREADS=8

Page 28: OpenMP - dcce.ibilce.unesp.braleardo/cursos/hpc/openMP2020.… · Programa OpenMP começa com um thread sequencial Para criar novos threads o usuário define uma região paralela

Um exemplo

Exemplo tirado de “An introduction to Parallel Programming”, P. Pacheco

Faz a integração de uma função através do método do trapézio

Usa “omp critical” para garantir a exclusão mútua no processo de acumulação na variável “global_result_p”

Page 29: OpenMP - dcce.ibilce.unesp.braleardo/cursos/hpc/openMP2020.… · Programa OpenMP começa com um thread sequencial Para criar novos threads o usuário define uma região paralela

Um exemplo

#include <stdio.h>

#include <stdlib.h>

#include <omp.h>

void Trap(double a, double b, int n, double* global_result_p);

int main(int argc, char* argv[ ]) {

double global_result = 0.0;

double a, b;

int n;

int thread_count;

Page 30: OpenMP - dcce.ibilce.unesp.braleardo/cursos/hpc/openMP2020.… · Programa OpenMP começa com um thread sequencial Para criar novos threads o usuário define uma região paralela

Um exemplo

thread_count = strtol(argv[1], NULL, 10);

printf("Enter a, b, and n \n");

scanf("%lf %lf %d", &a, &b, &n);

# pragma omp parallel num_threads(thread_count)

Trap(a, b, n, &global_result);

printf("With n = %d trapezoids, our estimate \n", n);

printf("of the integral from %f to %f = %.14e \n", a, b, global_result);

return 0;

} /* main */

Page 31: OpenMP - dcce.ibilce.unesp.braleardo/cursos/hpc/openMP2020.… · Programa OpenMP começa com um thread sequencial Para criar novos threads o usuário define uma região paralela

Um exemplo

void Trap(double a, double b, int n, double* global_result_p) {

double h, x, my_result;

double local_a, local_b;

int i, local_n;

int my_rank = omp_get_thread_num();

int thread_count = omp_get_num_threads();

h = (b-a)/n; local_n = n/thread_count;

local_a = a + my_rank*local_n*h; local_b = local_a + local_n*h;

my_result = (f(local_a) + f(local_b))/2.0;

Page 32: OpenMP - dcce.ibilce.unesp.braleardo/cursos/hpc/openMP2020.… · Programa OpenMP começa com um thread sequencial Para criar novos threads o usuário define uma região paralela

Um exemplo

for (i = 1; i <= local n-1; i++) {

x = local_a + i * h;

my_result += f(x);

}

my_result = my_result * h;

# pragma omp critical

*global_result_p += my_result;

} /* Trap */

// função f( ) deve ser definida pelo usuário

Page 33: OpenMP - dcce.ibilce.unesp.braleardo/cursos/hpc/openMP2020.… · Programa OpenMP começa com um thread sequencial Para criar novos threads o usuário define uma região paralela

Mais um exemplo

Um exemplo que será explorado outras vezes é o problema de transferência de calor, enunciado da seguinte forma:

Suponha uma chapa em que as bordas são mantidas em temperatura constante, assim como pontos isolados da chapa. Como determinar a temperatura em um ponto qualquer da chapa?

Page 34: OpenMP - dcce.ibilce.unesp.braleardo/cursos/hpc/openMP2020.… · Programa OpenMP começa com um thread sequencial Para criar novos threads o usuário define uma região paralela

Transferência de calor

Pode-se usar algoritmos de aproximações sucessivas, como o chamado algoritmo red & black

Nesse caso, cada ponto da chapa tem sua temperatura, numa iteração, como sendo a média das temperaturas de seus vizinhos e de sua própria na iteração anterior

Page 35: OpenMP - dcce.ibilce.unesp.braleardo/cursos/hpc/openMP2020.… · Programa OpenMP começa com um thread sequencial Para criar novos threads o usuário define uma região paralela

Transferência de calor

Os pontos a serem considerados como vizinhos em cada iteração são os vizinhos na vertical e na horizontal, como em:

Page 36: OpenMP - dcce.ibilce.unesp.braleardo/cursos/hpc/openMP2020.… · Programa OpenMP começa com um thread sequencial Para criar novos threads o usuário define uma região paralela

Transferência de calor

Assim, a chapa pode ser vista como uma enorme matriz, em que cada elemento é o valor da temperatura da chapa num ponto

Os valores de contorno e constantes são também considerados elementos da matriz

Page 37: OpenMP - dcce.ibilce.unesp.braleardo/cursos/hpc/openMP2020.… · Programa OpenMP começa com um thread sequencial Para criar novos threads o usuário define uma região paralela

Transferência de calor

O algoritmo Red & Black faz o cálculo das temperaturas numa iteração considerando valores da matriz red, armazenando os novos resultados na matriz black

Na iteração seguinte a matriz red passa a ser o destino dos resultados calculados a partir da matriz black (daí o nome do algoritmo!)

Page 38: OpenMP - dcce.ibilce.unesp.braleardo/cursos/hpc/openMP2020.… · Programa OpenMP começa com um thread sequencial Para criar novos threads o usuário define uma região paralela

Transferência de calor

A programação desse algoritmo em paralelo usando openMP é feita disparando uma certa quantidade de threads, que devem ser sincronizados a cada iteração

O procedimento é simples, demandando

Page 39: OpenMP - dcce.ibilce.unesp.braleardo/cursos/hpc/openMP2020.… · Programa OpenMP começa com um thread sequencial Para criar novos threads o usuário define uma região paralela

Exemplo de chapa

Page 40: OpenMP - dcce.ibilce.unesp.braleardo/cursos/hpc/openMP2020.… · Programa OpenMP começa com um thread sequencial Para criar novos threads o usuário define uma região paralela

Mais um exemplo

#include <stdio.h>

#include <stdlib.h>

#include <math.h>

#include <omp.h>

#define cols 200

#define totrows 200

#define maxtime 180000

Page 41: OpenMP - dcce.ibilce.unesp.braleardo/cursos/hpc/openMP2020.… · Programa OpenMP começa com um thread sequencial Para criar novos threads o usuário define uma região paralela

Mais um exemplo

int main(int argc, char* argv[ ])

{double red[totrows+2][cols+2], black[totrows+2][cols+2];

int r, c, tick;

int thread_count;

thread_count = strtol(argv[1], NULL, 10);

Page 42: OpenMP - dcce.ibilce.unesp.braleardo/cursos/hpc/openMP2020.… · Programa OpenMP começa com um thread sequencial Para criar novos threads o usuário define uma região paralela

Mais um exemplo

for (tick = 1; tick <= maxtime; tick++) {

// Inicia valores das fontes constantes de calor

black[totrows/3][cols/3] = 10.0;

black[2*totrows/3][cols/3] = 20.0;

black[totrows/3][2*cols/3] = -20.0;

black[2*totrows/3][2*cols/3] = 20.0;

Page 43: OpenMP - dcce.ibilce.unesp.braleardo/cursos/hpc/openMP2020.… · Programa OpenMP começa com um thread sequencial Para criar novos threads o usuário define uma região paralela

Mais um exemplo

/* Calcula-se as temperaturas nessa iteração */ #pragma omp parallel shared (black,red,thread_count) \ private(r,c) { #pragma omp for schedule (dynamic, totrows/thread_count) for (r=1; r <= totrows; r++) for (c=1; c <= cols; c++) red[r][c] = ( black[r][c] + black[r][c-1] + black[r-1][c] + black[r+1][c] + black[r][c+1] ) / 5.0; }

Page 44: OpenMP - dcce.ibilce.unesp.braleardo/cursos/hpc/openMP2020.… · Programa OpenMP começa com um thread sequencial Para criar novos threads o usuário define uma região paralela

Mais um exemplo

// Red part of the algorithm

red[totrows/3][cols/3] = 10.0;

red[2*totrows/3][cols/3] = 20.0;

red[totrows/3][2*cols/3] = -20.0;

red[2*totrows/3][2*cols/3] = 20.0;

Page 45: OpenMP - dcce.ibilce.unesp.braleardo/cursos/hpc/openMP2020.… · Programa OpenMP começa com um thread sequencial Para criar novos threads o usuário define uma região paralela

Mais um exemplo

/* Calcula-se as temperaturas nessa iteração */ #pragma omp parallel shared (black,red,thread_count) \ private(r,c) { #pragma omp for schedule (dynamic, totrows/thread_count) for (r=1; r < totrows; r++) for (c=1; c < cols; c++) black[r][c] = ( red[r][c] + red[r][c-1] + red[r-1][c] + red[r+1][c] + red[r][c+1] ) / 5.0; } } /* Fim do laço “for (tick = 1; tick <= maxtime; tick++)” */

Page 46: OpenMP - dcce.ibilce.unesp.braleardo/cursos/hpc/openMP2020.… · Programa OpenMP começa com um thread sequencial Para criar novos threads o usuário define uma região paralela

Mais um exemplo

// Reatribuindo valores constantes black[totrows/3][cols/3] = 10.0; black[2*totrows/3][cols/3] = 20.0; black[totrows/3][2*cols/3] = -20.0; black[2*totrows/3][2*cols/3] = 20.0;

for (r=62; r <= 72; r++) { for (c=62; c <= 70; c++) printf("%lf ",black[r][c]); puts(" "); } return 0;} /* main */

Page 47: OpenMP - dcce.ibilce.unesp.braleardo/cursos/hpc/openMP2020.… · Programa OpenMP começa com um thread sequencial Para criar novos threads o usuário define uma região paralela

openMP