+ All Categories
Home > Documents > Introduction à la programmation par...

Introduction à la programmation par...

Date post: 29-Aug-2020
Category:
Upload: others
View: 7 times
Download: 0 times
Share this document with a friend
142
3 Introduction à la programmation par directives
Transcript
Page 1: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

3 Introduction

à la programmation par directives

Page 2: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Plan

Introduction Le modèle OpenMP Aspect de base

- Région parallèle - Distribution du travail

•  Les directives •  L’ordonnancement du travail

- Attributs de données - Les directives de synchronisation

Oct. 2011 Coulaud - PG 305 - V 0 - 2

Page 3: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Références

Site Web officiel : www.openmp.org Spécification OpenMP 3.1 Books:

Using OpenMP, Barbara Chapman, Gabriele Jost, Ruud Van Der Pas, Cambridge, MA : The MIT Press 2007, ISBN: 978- 0-262-53302-7

Parallel programming in OpenMP, Chandra, Rohit, San Francisco, Calif. : Morgan Kaufmann ; London : Harcourt, 2000, ISBN: 1558606718 . Communauté

La communauté des chercheurs et des développeurs d’OpenMP académique et industrielle - http://www.compunity.org/

Conférence : - WOMPAT, EWOMP, WOMPEI, IWOMP - http://www.nic.uoregon.edu/iwomp2005/index.html#program

Oct. 2011 Coulaud - PG 305 - V 0 - 3

2.5

Page 4: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Processus versus threads

Processus

Threads

Oct. 2011 Coulaud - PG 305 - V 0 - 4 P

rocessus

T0

Mémoire du processus

T1 T2 T3 T4

Pile pour les variables privées de la thread

Mémoire visible par toutes les threads

Processus 0

M0

Processus 1

M1

Deux unités indépendantes = deux pids

Page 5: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Les Threads POSIX

Une autre API de programmation mémoire partagée. Bas niveau d’abstraction par rapport à OpenMP

•  Seulement des fonctions, pas de directives ; •  Plus flexible, mais plus difficile à implémenter et à

maintenir ; •  OpenMP peut être implémenté au-dessus des threads

POSIX.

Disponibilité •  Pas d’interface en Fortran des threads POSIX

Oct. 2011 Coulaud - PG 305 - V 0 - 5

Page 6: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Le modèle OpenMP

Oct. 2011 Coulaud - PG 305 - V 0 - 6

Page 7: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Pourquoi OpenMP en 1997

Pas de portabilité pour les applications à mémoires partagées •  Chaque constructeur avait son API •  X3H5 et PCF n’ont pas abouti

Portabilité au travers de MPI Pas de langages parallèles dominants Les machines sont là

•  Origin2000, SUN, … •  Exemplar, PC, ...

et les applications arrivent ...

Oct. 2011 Coulaud - PG 305 - V 0 - 7

Page 8: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Ce qu’apporte OpenMP

Une portabilité *  Fortran 77 et 90 depuis novembre 97 *  C et C++ depuis décembre 98 *  Unix et NT

Haut niveau de programmation (Directives)

Modèles de programmation *  parallélisme à grains fins (boucle) *  parallélisme à gros grains (SPMD)

Une parallélisation incrémentale

Oct. 2011 Coulaud - PG 305 - V 0 - 8

Pour l’extensibilité

Page 9: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Principaux acteurs

Constructeurs

Compacq Computer Corp. Hewlett-Packard Compagny International Business Machines Intel Corp. Silicon Graphics / Cray Research Sun Microsystems

Compilateurs Absoft Corp. Edinburgh Portable Compilers Kuck & Associates, Inc. Myrias Computer Technologies Numerical Algorithms Group Ltd. The Portland Group, Inc.

Recherche Perdue University US Department of Energy ASCI

Program

Applications ADINA R&D, Inc. ANSYS, Inc. ILOG CPLEX Division Fluent, Inc. LSTC Corp. MECALOG SARL Oxford Molecular Group PLC

Oct. 2011 Coulaud - PG 305 - V 0 - 9

Page 10: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Comment utiliser OpenMP

Oct. 2011 Coulaud - PG 305 - V 0 - 10

Fortran/C/C++ compilateur

Annotation Source

Programme Séquentiel

Programme Parallèle compilateur

OpenMP

compilateur séquentiel

Page 11: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Évolution d’OpenMP

Oct. 2011 Coulaud - PG 305 - V 0 - 11

OpenMP Fortran 1.1

OpenMP C/C++ 1.0

OpenMP Fortran 2.0

OpenMP C/C++ 2.0

1998

2000 1999

2002

OpenMP Fortran 1.0

1997

OpenMP Fortran/C/C++

draft 2.5

2005

OpenMP Fortran/C/C++

draft 3.0

2008

OpenMP Fortran/C/C++

draft 3.1

OpenMP Fortran/C/C++

draft 4.0 RC1

2011

2012

Page 12: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Architecture OpenMP

Directives de Compilation

Variables d’environnement

Bibliothèque (Run Time)

système d’exploitation

Bibliothèque OpenMP

Application Utilisateurs finaux

Cou

che

utili

sate

ur

Cou

che

de

Prog

ram

mat

ion

API

Ope

nMP

Cou

che

Syst

ème

Page 13: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Modèle d’exécution

Modèle Fork and join : le maitre lance un ensemble de threads

Thread maître

FOR

K

JOIN

FOR

K

JOIN

Région parallèle 1 7 threads

Région parallèle 2 5 threads

Thread initial

Oct. 2011 Coulaud - PG 305 - V 0 - 13

Page 14: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Modèle d’exécution (suite)

Le modèle Fork/Join peut être emboité

•  Géré automatiquement à la

compilation

•  Indépendant du nombre de threads s'exécutant actuellement.

Coulaud - PG 305 - V 0

Fork

Join

Fork

Join

Oct. 2011 - 14

Page 15: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Modèle mémoire

Les threads communiquent en partageant des variables Le partage est défini par :

- Toute variable qui est vue par deux ou plusieurs threads est partagée ( mémoire)

- Toute variable qui est vue par un seul thread est privée. ( sa propre mémoire)

Les situations de concurrence (race condition) sont possibles -  Utiliser des synchronisations pour éviter des conflits sur les

données; -  Changer le statut de la variable pour minimiser le besoin de

synchroniser.

Oct. 2011 Coulaud - PG 305 - V 0 - 15

Page 16: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Modèle mémoire

Une variable partagée est visible par tous les threads. Une variable privée est dupliquée sur les threads. Une variable interne dans une région parallèle est une variable appartenant à la mémoire propre du thread (pile).

Oct. 2011 Coulaud - PG 305 - V 0 - 16

Page 17: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

void main()

{

double Res[1000];

#pragma omp parallel for

for(int i=0;i<1000;i++) {

do_huge_comp(Res[i]);

}

}

void main()

{

double Res[1000];

for(int i=0;i<1000;i++) {

do_huge_comp(Res[i]);

}

}

Comment est utilisé classiquement OpenMP ? OpenMP est classiquement utilisé pour paralléliser des boucles :

- trouver la boucle la plus consommatrice en temps CPU. - éclater sur plusieurs threads/processeurs.

Oct. 2011 Coulaud - PG 305 - V 0 - 17

Éclater la boucle entre plusieurs threads

Programme Parallèle Programme séquentiel

Page 18: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Exemple

Code source

#include “omp.h” ….; #pragma omp parallel {

… région parallèle } Compilation

GNU : gcc -fopenmp filename.cc –o filename INTEL : icc -openmp filename.cc –o filename

Exécution $ export OMP_NUM_THREADS=4

$ filename Coulaud - PG 305 - V 0 18 Oct. 2011

Page 19: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Un exemple de programme … common /setup/ iam,ipiece,npoints,nzone !$OMP THREADPRIVATE(/setup/) dimension field(N), spectrum(NZ) npoints = N nzone = NZ energy = 0.0 !$OMP PARALLEL DEFAULT(PRIVATE) SHARED(field,spectrum) & !$OMP& REDUCTION(+: energy) COPYIN(/setup/) np = omp_get_num_threads() iam = omp_get_thread_num() call initialise(field, spectrum) call calcul (energy, field, spectrum) !$OMP BARRIER !$OMP SINGLE call affiche(spectrum) !$OMP END SINGLE !$OMP END PARALLEL print*, energy

Oct. 2011 Coulaud - PG 305 - V 0 - 19

Master

Page 20: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Un exemple de programme #include <omp.h> main () { int var1, var2, var3; Serial code . . . // Début de la section parallèle. Lancement d’un ensemble de threads // Précisez la portée des variables #pragma omp parallel private(var1, var2) shared(var3) { // Section Parallèle exécutée par tous les threads . . . // Tous les threads rejoingnent le thread maitre et disparaissent } Reprise du code de séquentiel . . . }

Oct. 2011 Coulaud - PG 305 - V 0 - 20

Master

Page 21: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

#pragma omp parallel { int id = omp_get_thread_num(); more: res(id) = do_big_job(id); if(conv(res(id)) goto more; } printf(“ All done \n”);

OpenMP: Blocs structurés (C/C++) La plupart des constructeurs OpenMP s’appliquent à des blocs

structurés - Bloc structuré : un bloc avec un point d’entré au début et un point de sortie à la fin.

-  Les seuls branchements autorisés sont le STOP en Fortran et exit() en C/C+

if(go_now()) goto more; #pragma omp parallel { int id = omp_get_thread_num(); more: res(id) = do_big_job(id); if(conv(res(id)) goto done;

go to more; } done: if(!really_done()) goto more;

Un bloc structuré Un bloc non structuré Oct. 2011 Coulaud - PG 305 - V 0 - 21

Page 22: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

OpenMP: blocs structurés

C/C++: un bloc est une déclaration unique ou un groupe d'instructions entre les accolades {}

Fortran: un bloc est une déclaration unique ou un groupe d'instructions entre la paire de directives.

C$OMP PARALLEL 10 wrk(id) = garbage(id) res(id) = wrk(id)**2 if(conv(res(id)) goto 10 C$OMP END PARALLEL

C$OMP PARALLEL DO do I=1,N

res(I)=bigComp(I) end do C$OMP END PARALLEL DO

#pragma omp parallel { id = omp_thread_num(); res(id) = lots_of_work(id); }

#pragma omp for for(I=0;I<N;I++){ res[I] = big_calc(I); A[I] = B[I] + res[I]; }

Oct. 2011 Coulaud - PG 305 - V 0 - 22

Page 23: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Syntaxe d’OpenMP

La plupart des fonctionnalités en OpenMP sont des directives de compilations.

Les directives prennent la forme suivante :

Sentinelle directive [clause [clause]…]

Un programme OpenMP par directives peut-être compilé par un compilateur qui ne supporte pas openMP.

Oct. 2011 Coulaud - PG 305 - V 0 - 23

FORTRAN

Format fixe : C$OMP !$OMP *$OMP Format libre : !$OMP

Module Fortran 95 OMP_LIB

C/C++

#pragma omp

Fichier d’include : omp.h

Page 24: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Syntaxe d’OpenMP Fortran

Exemple •  Format fixe

- Début en colonne 1 - Blanc ou carte suite en colonne 6

•  Format libre

Oct. 2011 Coulaud - PG 305 - V 0 - 24

USE OMP_LIB … !$OMP PARALLEL !$OMP+ PRIVATE(I) …. !$OMP END PARALLEL

USE OMP_LIB … !$OMP PARALLEL & !$OMP& PRIVATE(I) …. !$OMP END PARALLEL

C6

Page 25: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Syntaxe d’OpenMP

Compilation conditionnelle, deux possibilités •  sentinelles

•  Format fixe : C$ !$ ou *$ •  Format libre : !$

•  Macro du préprocesseur _OPENMP

Exemple

Oct. 2011 Coulaud - PG 305 - V 0 - 25

!$ iam = omp_get_thread_num()

#ifdef _OPENMP iam = omp_get_thread_num() #endif

Fortran C/C++/Fortran

Page 26: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Directives OpenMP

Directives pour créer une zone parallèle : région parallèle

Directives pour partager du travail :

•  Do/for, workshare, sections, task

Directives pour le statut des données : •  shared, private, firstprivate, lastprivate threadprivate •  reduction, ...

Directives de synchronisation : •  barrier, critical, atomic, flush •  nowait

Oct. 2011 Coulaud - PG 305 - V 0 - 26

Page 27: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

OpenMP en 1 transparent

Oct. 2011 Coulaud - PG 305 - V 0 - 27

Page 28: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

RÉGION PARALLÈLE

Oct. 2011 Coulaud - PG 305 - V 0 - 28

Page 29: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

OpenMP : Région Parallèle (1)

Création uniquement par #pragma omp parallel [clause(,), clause, ….] bloc de code à exécuter par chaque thread

Duplication de l’exécution

•  chaque thread joue le même code – les données peuvent être différentes

•  autorise du travail en fonction du numéro du thread •  Seul le thread maître continue à la fin

Barrière implicite à la fin Nombre de threads

•  Fixé par une fonction, variable ou une clause •  Variable en fonction de l’état du système

Oct. 2011 Coulaud - PG 305 - V 0 - 29

Tn-1

TM

… T0

Page 30: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

OpenMP : Région Parallèle (2)

Clauses shared (list) private (list) firstprivate (list) default (shared | none) en C/C++, pas de restriction en fortran.

reduction (opérateur : list) copyin (list) if (expression logique scalaire) num_threads (expression entière scalaire)

Oct. 2011 Coulaud - PG 305 - V 0 - 30

Contrôler la granularité.

Page 31: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

OpenMP : Région Parallèle (3)

Restriction •  Pas de branchement d’entré ou de sortie (non conforme)

le code doit être un bloc structuré •  Le code ne doit pas dépendre de l’ordre l'exécution des instructions •  une seule condition if •  une seule num_threads avec une expression positive •  Fortran

-  PARALLEL / END PARALLEL dans la même unité -  Comportement des I/O asynchrones par différentes threads est

non spécifié •  C/C++

-  Un throw exécuté dans un thread est catché par le même thread et reste dans la même région parallèle.

Oct. 2011 Coulaud - PG 305 - V 0 - 31

Page 32: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

OpenMP : Région Parallèle (4)

Exemple Chaque thread appelle work(ID,A) pour ID = 0 to 3

double A[1000];

omp_set_num_threads(4);

#pragma omp parallel

{

int ID =omp_get_thread_num();

work(ID,A);

}

Chaque thread exécute le code redondant dans le bloc structuré

Oct. 2011 Coulaud - PG 305 - V 0 - 32

Page 33: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

OpenMP : Région Parallèle (5)

Chaque thread exécute le même code

Oct. 2011 Coulaud - PG 305 - V 0 - 33

double A[1000];

omp_set_num_threads(4);

work(0,A) work(1,A) work(2,A) work(3,A)

double A[1000];

omp_set_num_threads(4);

#pragma omp parallel

{

int ID =omp_get_thread_num();

work(ID,A);

}

Printf(“End of parallel region.\n”)

Printf(“End of parallel region.\n”) Les threads s’attendent i.e. barrière

Une seule copie de A est partagée entre

les threads

Page 34: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

OpenMP : Région Parallèle (6)

Un exemple

Oct. 2011 Coulaud - PG 305 - V 0 - 34

PROGRAM simple INTEGER :: NTHREADS, TID, OMP_GET_NUM_THREADS INTEGER :: OMP_GET_NUM_THREADS, OMP_GET_THREAD_NUM ! Fork a team of threads giving them their own copies of variables !$OMP PARALLEL PRIVATE(NTHREADS, TID) ! Obtain thread id TID = OMP_GET_THREAD_NUM() ….. ! IF (TID .EQ. 0) THEN ! Only master thread does this NTHREADS = OMP_GET_NUM_THREADS() PRINT *, 'Number of threads = ', NTHREADS END IF ! !$OMP END PARALLEL ! All threads join master thread and disband END PROGRAM simple OpenMP V 1.x

Nombre de threads fixé par une variable : setenv OMP_NUM_THREADS 64

USE OMP_LIB

OpenMP V 2.0

Page 35: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

OpenMP: Région Parallèle La clause IF

Peut être utilisé pour désactiver la parallélisation dans certains cas

Oct. 2011 Coulaud - PG 305 - V 0 - 35

integer id, N

!$OMP PARALLEL PRIVATE(id) IF(N.gt.1000)

id = omp_get_thread_num() res(id) = big_job(id)

!$OMP END PARALLEL

La région parallèle est exécutée sur N threads seulement si l’expression logique est .TRUE.

#pragma omp parallel if (expression)

Exemple : quand la taille d’un paramètre est trop petite

Page 36: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

OpenMP: Région Parallèle la clause num_threads

Contrôler le nombre de threads utilisés dans une région parallèle

Oct. 2011 Coulaud - PG 305 - V 0 - 36

#include <omp.h>

main() {

#pragma omp parallel num_threads(10) { ... parallel region ... } }

#pragma omp num_threads (expression)

Page 37: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

subroutine whoami external omp_get_thread_num integer iam, omp_get_thread_num iam = omp_get_thread_num() !$OMP CRITICAL print*,’Hello from ‘, iam !$OMP END CRITICAL end subroutine whoami

OpenMP: Portée des directives

Les directives OpenMP peuvent être sur plusieurs fichiers.

Oct. 2011 Coulaud - PG 305 - V 0 - 37

Étendue lexicale de la région parallèle

!$OMP PARALLEL call whoami !$OMP END PARALLEL

+

Étendue dynamique de la région parallèle

bar.f poo.f

Directives orphelines

Page 38: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Exercice 1 programme “Hello world”

Écrire un programme multithreadé ou chaque thread affiche “hello world” et son numéro de thread. Le thread 0 affiche en plus dans la région parallèle le nombre de threads

Oct. 2011 Coulaud - PG 305 - V 0 - 38

Page 39: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Exercice 1 programme “Hello world”

Oct. 2011 Coulaud - PG 305 - V 0 - 39

#include <omp.h> main () { int nthreads, tid; /* Fork a team of threads with each thread having a private tid variable */ #pragma omp parallel private(tid) { /* Obtain and print thread id */ tid = omp_get_thread_num(); printf("Hello World from thread = %d\n", tid); /* Only master thread does this */ if (tid == 0) { nthreads = omp_get_num_threads(); printf("Number of threads = %d\n", nthreads); } } /* All threads join master thread and terminate */ }

Page 40: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

icc –openmp hello.c export OMP_NUM_THREADS=3 ; ./a.out Hello World from thread = 0 Number of threads = 3 Hello World from thread = 1 Hello World from thread = 2

Oct. 2011 Coulaud - PG 305 - V 0 - 40

Page 41: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

CONSTRUCTION DE TRAVAIL PARTAGÉ

Oct. 2011 Coulaud - PG 305 - V 0 - 41

Page 42: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Construction de travail partagé

Partager le travail parmi les threads Pas de création de threads Pas de barrière implicite en entrée mais une en sortie

Les directives : •  la directive DO ou for •  la directive SECTIONS •  la directive SINGLE •  La directive WORKSHARE

Restrictions - Chaque région de partage doit être rencontrée par tous les threads ou par aucun

- La séquence de partage et de barrière doit être la même sur chaque thread

Oct. 2011 Coulaud - PG 305 - V 0 - 42

Page 43: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Construction de travail partagé La directive DO ou for (1)

Partager les itérations d’une boucle à travers l’équipe

Parallélisme de données

#pragma omp for [clause(,), clause, ….] for (i=1; i<n; i++) {

code de la boucle à exécuter par chaque thread

}

!$OMP DO [clause(,), clause, ….] DO I=1, N

code de la boucle à exécuter par chaque thread END DO

!$OMP END DO [NOWAIT]

Oct. 2011 Coulaud - PG 305 - V 0 - 43

Page 44: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Construction de travail partagé La directive DO ou for (2)

Clauses - private, firstprivate , lastprivate - reduction ( operator : list) - schedule ( type [,chunck]) - collapse(n) - ordered - nowait

Restrictions - boucle avec un indice entier, A(i), - contrôle de boucle (pas de do while)

C++ Il faut utiliser des itérateurs aléatoires pour accéder aux données en temps constant. Sinon il faut utiliser un parallélisme de tâche.

Oct. 2011 Coulaud - PG 305 - V 0 - 44

Page 45: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Construction de travail partagé La directive DO ou for (2)

Oct. 2011 Coulaud - PG 305 - V 0 - 45

!$OMP PARALLEL call init(a) !$OMP DO do i=1,N … … enddo !$OMP END DO call display(a) !$OMP END PARALLEL

Exécution dupliquée

Travail partagé : exécute différentes itérations

Exécution dupliquée

Page 46: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

La clause collapse

collapse(n) : indique le nombre de boucles dans un ensemble de boucles imbriquées qui doivent être regroupées en une seule itération.

Oct. 2011 Coulaud - PG 305 - V 0 - 46

void bar(float *a, int i, int j, int k); int kl, ku, ks, jl, ju, js, il, void sub(float *a) {

int i, j, k; #pragma omp for collapse(2) private(i, k, j) for (k=kl; k<=ku; k+=ks) for (j=jl; j<=ju; j+=js) for (i=il; i<=iu; i+=is) bar(a,i,j,k);

} C/C++

Fusionne les boucles k et j

Page 47: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Construction de travail partagé La directive DO ou for (un exemple)

Oct. 2011 Coulaud - PG 305 - V 0 - 47

!$OMP PARALLEL SHARED(A,B,C,N) PRIVATE(I) !$OMP DO SCHEDULE(STATIC,CHUNK) DO I = 1, N C(I) = A(I) + B(I) END DO !$OMP END DO NOWAIT !$OMP END PARALLEL

Plus de barrière

Page 48: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

OpenMP: différentes approches

Code séquentiel Parallélisation manuelle Parallélisation automatique

for (int i=0; i<N; i++) { a[i]=b[i]+c[i]; }

#pragma omp parallel { int id = omp_get_thread_num(); int Nthr = omp_get_num_threads(); int istart = id*N/Nthr, iend = (id+1)*N/Nthr; for (int i=istart; i<iend; i++) { a[i]=b[i]+c[i]; } }

#pragma omp parallel #pragma omp for schedule(static) { for (int i=0; i<N; i++) { a[i]=b[i]+c[i]; } }

Coulaud - PG 305 - V 0 Oct. 2011 - 48

Page 49: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Problème avec les boucles

Equilibrage de charge - Si toutes les itérations s’exécutent à la même vitesse, les processeurs sont

utilisés de manière optimale ; - Si certaines itérations sont plus rapides que d'autres, certains processeurs

seront plus lents pour traiter leurs itérations, réduisant ainsi l'accélération ; - Si nous ne connaissons pas à priori la répartition du travail, il peut être

nécessaire de redistribuer dynamiquement la charge.

Granularité - La création de threads et la synchronisation prend du temps ; - Affectation de travail pour les threads peut prendre plus de temps que

l'exécution elle-même! ; - Besoin de fusionner le travail (grain grossier) pour recouvrir le surcout des

threads.

Compromis entre l'équilibrage de charge et de la granularité!

Oct. 2011 Coulaud - PG 305 - V 0 - 49

Page 50: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

L’ordonnancement du travail La clause SCHEDULE

Un exemple : !$OMP PARALLEL DO SCHEDULE ( type ) #pragma omp schedule (type)

type est à choisir parmi - static ( chunk) - dynamic (chunk) - guided ( chunk) - auto c’est le compilateur ou le runtime qui décide - runtime

Décidé à l’exécution et spécifié par une variable OMP_SCHEDULE setenv OMP_SCHEDULE STATIC,100

Si pas de cause, l’ordonnancement dépend de l’implémentation !!!

Oct. 2011 Coulaud - PG 305 - V 0 - 50

Format : schedule (type [,chunk])

Page 51: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

L’ordonnancement du travail Le type STATIC

Oct. 2011 Coulaud - PG 305 - V 0 - 51

Exemple : 600 itérations SCHEDULE(STATIC,chunk)

Page 52: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

L’ordonnancement du travail Le type DYNAMIC

Oct. 2011 Coulaud - PG 305 - V 0 - 52

EXECUTION

Affectation dynamique des itérations de taille chunck.

Défaut chunck = 1

schedule(dynamic,chunk)

Page 53: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

L’ordonnancement du travail Le type GUIDED

Oct. 2011 Coulaud - PG 305 - V 0 - 53

Exemple : 10 230 itérations éclatées schedule(guided,256)

Les itérations sont coupées en morceaux de taille exponentiellement décroissante, chunk est le nombre d’itérations du plus petit morceau. Défaut : chunk = 1 Affectation dynamique entre les threads.

Page 54: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Ordonnancement Quand l’utiliser

static Travail par itération est prédictible et similaire

dynamic Travail par itération est imprévisible et très variable

guided Cas spécial du cas dynamique pour réduire le surcoût.

auto Aucune idée

Comment choisir le type de l’ordonnanceur ?

Oct. 2011 Coulaud - PG 305 - V 0 - 54

Page 55: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Construction de travail partagé La directive sections

Zone non itérative, chaque section est exécutée par un thread

!$OMP SECTIONS clause[[,] clause…] !$OMP SECTION < code bloc 1> !$OMP SECTION < code bloc 2> !$OMP SECTION

. . . !$OMP END SECTIONS [NOWAIT]

#pragma omp sections clause[[,] clause…] { #pragma omp section < code bloc 1> #pragma omp section < code bloc 2> #pragma omp section

. . . }

Clauses : private firstprivate lastprivate reduction nowait

Clauses : private firstprivate Lastprivate reduction

Parallélisme procédurale

Page 56: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Construction de travail partagé La directive sections (un exemple)

Oct. 2011 Coulaud - PG 305 - V 0 - 56

!$OMP PARALLEL !$OMP SECTIONS !$OMP SECTION CALL XAXIS() !$OMP SECTION CALL YAXIS() !$OMP SECTION CALL ZAXIS() !$OMP END SECTIONS NOWAIT !$OMP END PARALLEL

#pragma omp parallel default(none)\ shared(n,a,b,c,d) private(i)

{ #pragma omp sections nowait { #pragma omp section

for (i=0; i<n-1; i++) b[i] = (a[i] + a[i+1])/2;

#pragma omp section for (i=0; i<n; i++) d[i] = 1.0/c[i];

} /*-- End of sections --*/ } /*-- End of parallel region --*/

Page 57: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

La directive MASTER

Détermine un section où uniquement la thread maître exécute le code •  Le reste de l’équipe saute la section et continue l’exécution après

la fin de la section maître

•  Pas de barrière implicite à l’entrée et à la sortie de la section

!$omp master bloc structuré

!$omp end master

#pragma omp master { bloc structuré }

Coulaud - PG 305 - V 0

#pragma omp parallel { …. ; #pragma omp master

{ printf(’’ Hello \n’’); } …..

} Oct. 2011 Coulaud - PG 305 - V 0 - 57

Page 58: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

La directive SINGLE

un seul thread du groupe va exécuter le code

!$OMP SINGLE clause[[,] clause…] bloc structuré !$OMP END SINGLE [end_clause]

#pragma omp single clause[[,] clause…] { bloc structuré }

Clauses : Début : private, firstprivate Fin : copyprivate, nowait

Clauses : private, firstprivate copyprivate, nowait

Coulaud - PG 305 - V 0

Région parallèle

single

JOIN

wait

maître

Page 59: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Construction de travail partagé La directive SINGLE (un exemple)

Restrictions - La clause copyprivate ne peut pas être utilisée avec nowait ; - Une seule clause nowait.

Oct. 2011 Coulaud - PG 305 - V 0 - 59

!$OMP PARALLEL SHARED(A,B,C,N) PRIVATE(I) !$OMP SINGLE call output(…) !$OMP SINGLE !$OMP END PARALLEL

Page 60: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Construction de travail partagé La directive WORKSHARE

Uniquement en fortran. Permet de partager les itérations d’une boucle à travers l’équipe

!$OMP WORKSHARE [NOWAIT] code à exécuter par chaque thread !$OMP END WORKSHARE [NOWAIT]

Code Fortran95 Tableau ForALL, where Fonction elemental

•  Pas de clause •  Barrière implicite en entré et en sortie

Attention le surcoût peut-être élevé

Page 61: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Construction de travail partagé La directive WORKSHARE (une exemple)

Oct. 2011 Coulaud - PG 305 - V 0 - 61

!$OMP PARALLEL SHARED(A,B,C,N) PRIVATE(I) !$OMP WORKSHARE A(:,:) = 1.0 C(:,:) = A(:,:) + B(:,:) where ( D(:,: ) > 0;) E(:,:) = sqrt((D(:,:)) !$OMP END WORKSHARE NO WAIT !$OMP END PARALLEL

pas de barrière

Page 62: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Construction de travail partagé Restriction

Les directives doivent se trouver dans une région parallèle

Ces directives doivent être rencontrées •  par tous les threads du groupe •  dans le même ordre

Oct. 2011 Coulaud - PG 305 - V 0 - 62

Page 63: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Combiner région parallèle et travail partagé

On peut combiner les directives région parallèle et travail partagé : •  Directive do parallèle

•  Directive worshare parallèle

!$OMP PARALLEL DO [ … ] boucle do

!$OMP END PARALLEL DO

Oct. 2011 Coulaud - PG 305 - V 0 - 63

•  Directive sections parallèle

!$OMP PARALLEL SECTIONS […] !$OMP SECTION

Bloc 1 !$OMP SECTION

Bloc 2 ...

!$OMP END PARALLEL SECTIONS

!$OMP PARALLEL WORKSHARE […] boucle do

!$OMP END PARALLEL WORKSHARE […]

Page 64: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Combiner région parallèle et travail partagé

On peut combiner les directives région parallèle et travail partagé : •  Directive do parallèle

•  Directive sections parallèle

#pragma omp parallel for [ … ] boucle do

Oct. 2011 Coulaud - PG 305 - V 0 - 64

#pragma omp parallel sections […] { #pragma omp section Bloc 1 #pragma omp section Bloc 2 ... }

Page 65: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

ATTRIBUTS DE DONNÉES

Oct. 2011 Coulaud - PG 305 - V 0 - 65

Page 66: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Les différents statuts

PRIVATE (list) SHARED (list) DEFAULT(PRIVATE | SHARED | NONE)

FIRSTPRIVATE (list) initialise chaque copie locale par la valeur originale

LASTPRIVATE (list) le dernier thread met à jour la variable

THREADPRIVATE (list)

Oct. 2011 Coulaud - PG 305 - V 0 - 66

Page 67: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Oct. 2011 Coulaud - PG 305 - V 0 - 67

Subroutine saxpy(z, a, x, y, n) integer i, n real z(n), a, x(n), y !$omp parallel do do i = 1, n z(i) = a * x(i) + y end do return end

Un exemple (1)

Page 68: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

z a x y n i Mémoire partagée Globale

Exécution séquentielle.

Toutes les données pointent sur la mémoire globale

z a x y n Mémoire partagée Globale

Exécution parallèle Les accès à z, a, x, y, n pointent vers la mémoire globale.

i i i i

Chaque thread possède une copie privée de i Les accès à i vont vers la copie privée

Un exemple (2)

Oct. 2011 Coulaud - PG 305 - V 0 - 68

Page 69: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Division du travail entre les threads

Oct. 2011 Coulaud - PG 305 - V 0 - 69

Subroutine saxpy(z, a, x, y, n) integer i, n real z(n), a, x(n), y !$omp parallel do do i = 1, n z(i) = a * x(i) + y end do end

i = 11, 20

n = 40, 4 threads

i = 21, 30 i = 31, 40 i = 1, 10

Z(10)

n

Z(11) Z(20) Z(21) Z(1) Z(30) a

y

Z(31) Z(40)

X(10) X(11) X(20) X(21) X(1) X(30) X(31) X(40)

Mémoire partagée globale.

Mémoire locale

Un exemple (3)

Page 70: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

La clause shared

shared (var) Tous les threads accèdent à la même zone mémoire de la variable var

•  Attention au conflit d’écriture, mise à jour, …

Uniquement possible avec la directive de région parallèle ou des tâches

Oct. 2011 Coulaud - PG 305 - V 0 - 70

Subroutine saxpy(z, a, x, y, n) integer i, n real z(n), a, x(n), y !$omp parallel do shared (z,a,x,y) private(i) do i = 1, n z(i) = a * x(i) + y end do end

Page 71: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

La clause private

private (VAR) Création d’une copie locale de VAR dans chaque thread :

•  La valeur n’est pas initialisée •  Pas de lien entre le stockage de la copie privée et de la variable originale •  En sortie dépend de la version.

Oct. 2011 Coulaud - PG 305 - V 0 - 71

IS = 0 !$omp parallel do private(is) DO J=1,1000

IS = IS + J END DO !$omp end parallel do print *, IS

IS n’est pas initialisé

IS est indéfini en 2.5

IS = 0 en 3.0

Page 72: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

La clause firstprivate

firstprivate (VAR) Firstprivate est un cas spécial du statut PRIVATE

•  Création d’une copie locale dans chaque thread •  Initialisation de chaque copie par la valeur de la variable provenant

de la thread maître.

Oct. 2011 Coulaud - PG 305 - V 0 - 72

void useless() { int tmp = 0;

#pragma omp for firstprivate(tmp) for (int j = 0; j < 1000; ++j) tmp += j; printf(“%d\n”, tmp);

}

Chaque thread a une copie de tmp et est initialisée à 0

tmp = 0 en 3.0 et est indéfini en 2.5

Page 73: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

La clause lastprivate

lastprivate (VAR) LASTPRIVATE est un cas spécial du statut PRIVATE

•  En sortie, affecte la valeur de la dernière itération ou section (séquentielle)

•  Si NOWAIT; la variable est indéfinie tant qu’une barrière de synchronisation n’a pas été réalisée.

Oct. 2011 Coulaud - PG 305 - V 0 - 73

void useless() { int tmp = 0;

#pragma omp for lastprivate(tmp) for (int j = 0; j < 1000; ++j) tmp += j; printf(“%d\n”, tmp);

}

Chaque thread a une copie de tmp et est initialisée à 0

tmp = valeur pour j = 999

Page 74: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

La clause default

Précise le statut des variables dans la portée. none

- Pas de statut par défaut - Il faut préciser le statut de toutes les variables.

shared

-  Toutes les variables sont partagées. -  C’est le statut par défaut en l’absence de la clause none.

private -  Toutes les variables de la portée sont privées -  y compris les variables dans les commons (sauf ceux spécifiés dans la

clause threadprivate).

Oct. 2011 Coulaud - PG 305 - V 0 - 74

default (private | shared | none)

default (shared | none)

Fortran

C/C++

Page 75: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Une clause supplémentaire

firstprivate -  Toutes les variables de la portée sont privées -  Les variables sont initialisées.

Oct. 2011 Coulaud - PG 305 - V 0 - 75

default (firstprivate) Fortran

V 3.0

Page 76: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Un test

Considérons l’exemple suivant Variables : A,B et C =1 #pragma omp for private(B) firstprivate(C)

Q1 A,B et C sont-elles locales à chaque thread ou partagées dans une région parallèle ? Q2 Préciser les valeurs initiales et finales (après la zone parallèle)

Oct. 2011 Coulaud - PG 305 - V 0 - 76

Dans la région parallèle •  A est partagée A = 1 •  B et C sont privées

•  La Valeur initiale de B n’est pas définie •  La Valeur initiale de C est 1

En dehors de la région parallèle La valeur de B et de C n’est pas définie dans OpenMP 2.5 Les valeurs de B et de C sont définies dans la région mais pas en dehors de la région parallèle

Page 77: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

La clause threadprivate

#pragma omp threadprivate(list) !$omp threadprivate (list) Rendre des variables globales privées dans un thread

•  Fortran : COMMON blocks, variables des modules •  C/C++ : variable globales, statiques, membre statique d’une classe

Différent de les considérer comme PRIVATE

•  Avec PRIVATE les variables globales sont masquées. •  THREADPRIVATE préserve la portée globale à l’intérieur de chaque thread

Les variables threadprivate peuvent être initialisées en utilisant la clause COPYIN ou en utilisant l’instruction DATA.

Restrictions

-  Le nombre de threads ne doit pas varier (omp_dynamic = false) -  La directive doit suivre al déclaration

Oct. 2011 Coulaud - PG 305 - V 0 - 77

Page 78: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

La clause Threadprivate (exemple)

Créer un compteur privé dans chaque thread. int counter = 0; #pragma omp threadprivate(counter) int increment_counter() {

counter++; return (counter);

}

Oct. 2011 Coulaud - PG 305 - V 0 - 78

Page 79: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

#include <omp.h> int a, b, i, tid; float x; #pragma omp threadprivate(a, x)

main () { printf("1st Parallel Region:\n");

#pragma omp parallel private(b, tid) { tid = omp_get_thread_num(); a = tid ; b = tid; x = 1.1 * tid +1.0; printf("Thread %d: a,b,x= %d %d %f\n",tid,a,b,x); } /* end of parallel section */ printf("************************************\n"); printf("Master thread doing serial work here\n"); printf("************************************\n"); printf("2nd Parallel Region:\n"); #pragma omp parallel private(tid) { tid = omp_get_thread_num(); printf("Thread %d: a,b,x= %d %d %f\n",tid,a,b,x); } /* end of parallel section */ }

Oct. 2011 Coulaud - PG 305 - V 0 - 79

Page 80: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

% export OMP_NUM_THREADS=4 % ./a.out 1st Parallel Region: Thread 0: a,b,x= 0 0 1.000000 Thread 1: a,b,x= 1 1 2.100000 Thread 2: a,b,x= 2 2 3.200000 Thread 3: a,b,x= 3 3 4.300000 ************************************ Master thread doing serial work here ************************************ 2nd Parallel Region: Thread 0: a,b,x= 0 0 1.000000 Thread 3: a,b,x= 3 0 4.300000 Thread 1: a,b,x= 1 0 2.100000 Thread 2: a,b,x= 2 0 3.200000 Oct. 2011 Coulaud - PG 305 - V 0 - 80

Page 81: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

La clause threadprivate (exemple)

Oct. 2011 Coulaud - PG 305 - V 0 - 81

subroutine poo parameter (N=1000) common/buf/A(N),B(N) C$OMP THREADPRIVATE(/buf/) do i=1, N B(i)= const* A(i) end do return end

subroutine bar parameter (N=1000) common/buf/A(N),B(N) C$OMP THREADPRIVATE(/buf/) do i=1, N A(i) = sqrt(B(i)) end do return end

Considérons des procédures appelées chacune dans un thread dans une région parallèle.

À cause de la directive threadprivate, chaque thread exécutant ces procédures ont leur propre copie du bloc common /buf/.

Page 82: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

integer, save :: a !$OMP THREADPRIVATE(a) !$OMP PARALLEL a = OMP_get_thread_num() !$OMP END PARALLEL …. !$OMP PARALLEL ... !$OMP END PARALLEL

La clause Threadprivate (exemple 2)

Oct. 2011 Coulaud - PG 305 - V 0 - 82

Page 83: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

C++: Threadprivate

•  création •  Autorise dans les classes C++ un membre static à être privé class T {

public: static int i; #pragma omp threadprivate(i) ...

};

Oct. 2011 Coulaud - PG 305 - V 0 - 83

V 3.0

Page 84: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

copyin (list) donne un moyen d’assigner la même valeur aux variables threadprivate pour tous les threads.

La clause copyin

Oct. 2011 Coulaud - PG 305 - V 0 - 84

Les commons privés (thread) sont initialisés par la valeur de la thread maître.

La variable du thread master est utilisée comme valeur à copier

Fortran : la liste contient le nom des variables et des commons

Page 85: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

La clause copyprivate

copyprivate(list) Pour diffuser une variable privée dans une variable globale ou un pointer

-  list ne doit pas avoir le statut de PRIVATE, FIRSTPRIVATE - uniquement après la directive SINGLE

Oct. 2011 Coulaud - PG 305 - V 0 - 85

float x, y; #pragma omp threadprivate(x, y) void init(float a, float b) { #pragma omp single copyprivate(a,b,x,y) { get_values(a,b,x,y); } }

Page 86: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Exercice 2 : programme pi

Oct. 2011 Coulaud - PG 305 - V 0 - 86

F(x)

= 4

.0/(1

+x2 )

4.0

2.0

1.0 X 0.0

∫ 4.0

(1+x2) dx = π 0

1

∑ F(xi)Δx ≈ π i = 0

N

On approche l’intégrale par la somme des aires des rectangles :

où chaque rectangle a une largeur Δx et une hauteur F(xi) évaluée au milieu de d’intervalle i.

Indication : chaque thread évalue un bout de la somme en parallèle REAL(8) :: SUM(NUM_THREAD_MAX)

On somme en séquentiel les contributions.

Page 87: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

La clause reduction

Une autre clause qui affecte comment une variable est partagée reduction (op : list)

Les variables dans “list” doivent être partagées dans le région parallèle. Les opérateurs possibles sont :

FORTRAN : +, *, -, .AND., .EQV., .NEQV., MAX, MIN, IAND, IOR, IEOR C/C++ : +, *, -, &, |, ^, &&, max, min

Dans une région parallèle :

•  Une copie locale des variables de la liste est faite et initialisée en fonction de l’opérateur op de la réduction. (ex.. 0 for “+”).

•  Les copies locales sont réduites en une seule valeur et combinée avec la valeur de la variable globale (originale).

Oct. 2011 Coulaud - PG 305 - V 0 - 87

Page 88: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

La clause reduction

Restriction : •  List ne doit pas contenir des tableaux dans la version 1.0 (accepté en 2.0)

•  Les copies locales sont réduites en une seule valeur et combinée avec la valeur de la variable globale (originale).

Oct. 2011 Coulaud - PG 305 - V 0 - 88

Exemple: !$OMP DO REDUCTION(+: A, Y) REDUCTION(.OR.: AM)

Page 89: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Statut des données La clause reduction (exemple)

Oct. 2011 Coulaud - PG 305 - V 0 - 89

PROGRAM DOT_PRODUCT INTEGER N, CHUNK, I PARAMETER (N=100) PARAMETER (CHUNK=10) REAL A(N), B(N), RESULT ! Some initializations !$OMP PARALLEL DO DEFAULT(SHARED) & !$OMP& PRIVATE(I) & !$OMP& SCHEDULE(STATIC,CHUNK) DO I = 1, N A(I) = I * 1.0 B(I) = I * 2.0 ENDDO !$OMP END DO RESULT= 0.0

!$OMP PARALLEL DO & !$OMP& DEFAULT(SHARED) PRIVATE(I)& !$OMP& SCHEDULE(STATIC,CHUNK) & !$OMP& REDUCTION(+:RESULT) DO I = 1, N RESULT = RESULT + (A(I) * B(I)) ENDDO !$OMP END DO PRINT *, 'Final Result= ', RESULT END PROGRAM DOT_PRODUCT

Page 90: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

#include <omp.h> main () { int i, n, chunk; float a[100], b[100], result; /* Some initializations */

n = 100; chunk = 10; result = 0.0; for (i=0; i < n; i++) a[i] = i * 1.0; b[i] = i * 2.0; }

#pragma omp parallel for default(shared) private(i) schedule(static,chunk) \ reduction(+:result) for (i=0; i < n; i++)

result = result + (a[i] * b[i]); printf("Final result= %f\n",result); }

Oct. 2011 Coulaud - PG 305 - V 0 - 90

Page 91: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Résumé des clauses

Oct. 2011 Coulaud - PG 305 - V 0 - 91

Page 92: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

L’API OPENMP

Oct. 2011 Coulaud - PG 305 - V 0 - 92

Page 93: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Les variables d’environnement

Fixe le nombre de threads à utiliser OMP_NUM_THREADS int_literal

Autorise d’utiliser un nombre de thread différents dans chaque région ? OMP_DYNAMIC TRUE || FALSE

Précise si l’on souhaite faire du parallélisme emboîté avec une nouvelle équipe de thread ou non

OMP_NESTED TRUE || FALSE

Contrôle comment OpenMP ordonnance pour la clause schedule (RUNTIME) le travail partagé.

OMP_SCHEDULE “schedule[, chunk_size]” setenv OMP_SCHEDULE "guided,4"

Oct. 2011 Coulaud - PG 305 - V 0 - 93

Page 94: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Les variables d’environnement

OMP_PROC_BIND : permet de fixer un thread sur le processeur. OMP_PROC_BIND true/false

OMP_STACKSIZE : contrôle la taille de la pile pour les threads créés (sauf le master) OMP_STACKSIZE n [B,K,M,G]

OMP_WAIT_POLICY : permet de préciser la politique d’attente des threads

OMP_WAIT_POLICY active/passive

OMP_MAX_ACTIVE_LEVELS : contrôle le nombre maximal de parallélisme emboitée dans une région parallèle. La valeur est un entier positif.

OMP_THREAD_LIMIT : Fixe le nombre de threads utilisé dans le programme

94

V 3.0

Oct. 2011 Coulaud - PG 305 - V 0

Page 95: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

L’API OpenMP Les fonctions de la bibliothèque

Oct. 2011 Coulaud - PG 305 - V 0 95

1. OMP_SET_NUM_THREADS 2. OMP_GET_NUM_THREADS 3. OMP_GET_MAX_THREADS 4. OMP_GET_THREAD_NUM 5. OMP_GET_THREAD_LIMIT 6. OMP_GET_NUM_PROCS 7. OMP_IN_PARALLEL 8. OMP_SET_DYNAMIC 9. OMP_GET_DYNAMIC 10. OMP_SET_NESTED 11. OMP_GET_NESTED 12. OMP_SET_SCHEDULE 13. OMP_GET_SCHEDULE 14. OMP_SET_MAX_ACTIVE_LEVELS 15. OMP_GET_MAX_ACTIVE_LEVELS 16. OMP_GET_LEVEL

17. OMP_GET_ANCESTOR_THREAD_NUM 18. OMP_GET_TEAM_SIZE 19. OMP_GET_ACTIVE_LEVEL 20. OMP_INIT_LOCK 21. OMP_DESTROY_LOCK 22. OMP_SET_LOCK 23. OMP_UNSET_LOCK 24. OMP_TEST_LOCK 25. OMP_INIT_NEST_LOCK 26. OMP_DESTROY_NEST_LOCK 27. OMP_SET_NEST_LOCK 28. OMP_UNSET_NEST_LOCK 29. OMP_TEST_NEST_LOCK 30. OMP_GET_WTIME 31. OMP_GET_WTICK

Page 96: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

L’API OpenMP Les fonctions de la bibliothèque

Fonctions de l’API •  Tester/ modifier le nombre de threads

omp_set_num_threads(), omp_get_num_threads(), omp_get_thread_num(), omp_get_max_threads()

•  Modifie le mode dynamique i.e le nombre de threads peut varier entre deux constructions parallèles

omp_set_dynamic(), omp_get_dynamic()

•  Modifie le parallélisme emboité omp_set_nested(), omp_get_nested(),

•  Sommes nous dans une région parallèle ? omp_in_parallel()

•  Combien de processeurs dans le système ? omp_num_procs()

Oct. 2011 Coulaud - PG 305 - V 0 - 96

Page 97: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

L’API OpenMP Les fonctions de la bibliothèque

Fonctions sur les verrous

omp_init_lock(), omp_init_nest_lock(), omp_destroy_lock(), omp_destroy_nest_lock(), omp_set_lock(), omp_set_nest_lock(), omp_unset_lock(), omp_unset_nest_lock(), omp_test_lock(), omp_test_nest_lock()

Fonction pour mesurer le temps omp_get_wtime(), omp_get_wtick()

Oct. 2011 Coulaud - PG 305 - V 0 - 97

double start; double end; start = omp_get_wtime(); ... work to be timed ... end = omp_get_wtime(); printf_s("Work took %f sec. time.\n", end-start);

Page 98: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

SYNCHRONISATION

Oct. 2011 Coulaud - PG 305 - V 0 - 98

Page 99: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

OpenMP: Synchronization

Différentes directives permettent de synchroniser les Haut niveau

- Barrier - critical - atomic - ordered

Bas niveau - flush - lock

Oct. 2011 Coulaud - PG 305 - V 0 - 99

Page 100: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Le thread attend jusqu’à ce que toute l’équipe arrive sur la directive

!$omp barrier #pragma omp barrier

La directive barrier

#pragma omp parallel shared (A, B, C) private(id) {

id=omp_get_thread_num(); A[id] = big_calc1(id);

#pragma omp barrier #pragma omp for

for(i=0;i<N;i++){C[i]=big_calc3(I,A);} #pragma omp for nowait

for(i=0;i<N;i++){ B[i]=big_calc2(C, i); }

A[id] = big_calc3(id); }

Barrière implicite à la fin de bloc de la directive for

Barrière implicite à la fin de la région parallèle

Pas de barrière implicite à cause de nowait

Oct. 2011 Coulaud - PG 305 - V 0 - 100

Page 101: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

La directive critical

Empêcher l’accès simultané pas les threads à un bloc d’instruction Un thread à la fois dans le bloc d’instructions parmi toutes les threads du programme (pas de l’équipe!)

La section critique

•  On peut la nommer - Le nom est une entité globale - Ne doit pas entrer en conflit avec le nom d’une procédure, common, …

•  Un thread à la fois dans la section

Oct. 2011 Coulaud - PG 305 - V 0 - 101

!$omp critical [(nom)] bloc d’instructions !$omp end critical [(nom)]

#pragma omp critical [(name)] {bloc structuré}

Page 102: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

La directive critical (exemple)

Accumulation dans une boucle

Oct. 2011 Coulaud - PG 305 - V 0 - 102

!$omp parallel do shared(A) private(ALOCAL) …… !$OMP CRITICAL (left) A(index(i)) = A(index(i)) + Alocal !$OMP END CRITICAL (left) …… !$omp end parallel

#pragma omp for shared(A) private(Alocal) for (…) { …… #pragma omp critical (left) A[index[i]] = A[index[i]] + Alocal …… }

Page 103: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

La directive atomic

La directive assure qu’une variable partagée est lue et modifiée en mémoire par une seule tâche à la fois

Ne s’applique qu’à l’instruction suivant la directive

Oct. 2011 Coulaud - PG 305 - V 0 - 103

#pragma omp atomic [read | write | update Í capture] {bloc structuré}

Clauses : read v = x

write x = v

update (défaut) x = x binop operation (++x, x--, …)

capture fait un atomic update de x + capture la valeur d’origine ou finale

Page 104: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

La directive atomic (exemple)

Oct. 2011 Coulaud - PG 305 - V 0 - 104

#pragma omp parallel {

double tmp, B; B = DOIT(); tmp = other_work(B);

#pragma omp atomic update x += tmp ;

}

fournit l’exclusion mutuelle mais s'applique uniquement à la mise à jour d'un emplacement mémoire

Page 105: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

La directive ordered

Les itérations d’une boucle seront exécutées dans le même ordre qu’en séquentiel.

Oct. 2011 Coulaud - PG 305 - V 0 - 105

!$omp parallel do shared(A) ordered do i = 1, 1000 !$omp ordered A(i) = 2 * A(i-1) !$omp end ordered enddo !$omp end parallel do

Restriction •  Uniquement dans un bloc DO/for •  La directive DO/for doit aussi avoir la clause ordered

!$omp ordered bloc !$omp end ordered

#pragma omp ordered { bloc }

#pragma omp parallel private (tmp) #pragma omp for ordered

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

#pragma ordered res += consum(tmp); }

Page 106: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

La directive flush

Permet à un thread de construire une vue cohérente de la mémoire Après cet appel

- Toutes les opérations mémoires sont terminées - Variables dans les registres, buffers d’écriture doivent être mis à jour en mémoire ;

Autorise une mécanisme de synchronisation point à point La dernière valeur de la variable est visible pour tous les threads

Oct. 2011 Coulaud - PG 305 - V 0 - 106

!$omp flush (list) #pragma omp flush (list)

Page 107: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

La directive flush (exemple)

Permet de synchroniser deux threads, la variable ISYNC doit être partagée.

Oct. 2011 Coulaud - PG 305 - V 0 - 107

!$OMP PARALLEL DEFAULT(PRIVATE) SHARED(ISYNC) IAM = OMP_GET_THREAD_NUM() ; ISYNC(IAM) = 0 NEIGH = GET_NEIGHBOR (IAM) !$OMP BARRIER CALL WORK() C I am done with my work, synchronize with my neighbor ISYNC(IAM) = 1 !$OMP FLUSH(ISYNC) C Wait until neighbor is done DO WHILE ( ISYNC(NEIGH) .EQ. 0) !$OMP FLUSH(ISYNC) END DO !$OMP END PARALLEL

Page 108: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Exercice avancé

Faire circuler un jeton sur un anneau.

Oct. 2011 Coulaud - PG 305 - V 0 - 108

Page 109: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

LE PARALLÉLISME EMBOÎTÉ

Oct. 2011 Coulaud - PG 305 - V 0 - 109

Page 110: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Parallélisme emboîté Le principe

Chaque thread rencontre une région parallèle •  Autoriser le parallélisme emboîté setenv OMP_NESTED TRUE

Utiliser omp_set_nested() •  Sinon la partie est sérialisée (1 thread)

Création des nouveaux threads

•  thread Ti devient master •  master + slaves = team •  à la fin les salves sont en mode sleep ou spin

-  Dépend de OMP_WAIT_POLICY

Oct. 2011 Coulaud - PG 305 - V 0 - 110

Ti 2 1 0

#pragma omp parallel

#pragma omp parallel

fork

fork

join

join

Page 111: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Parallélisme emboîté Les restrictions

Attention il faut imbriquer des régions parallèles et pas du partage de travail.

Oct. 2011 Coulaud - PG 305 - V 0 - 111

#pragma omp parallel { #pragma omp parallel { bloc 2} }

#pragma omp parallel #pragma omp for { #pragma omp for { bloc 2} }

Directives interdites :

- barrier, master, single, ordered -  critical avec le même nom

Page 112: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Parallélisme emboîté Un exemple

Activé que si OMP_NESTED = TRUE

Oct. 2011 Coulaud - PG 305 - V 0 - 112

program parallel implicit none integer :: rang, OMP_GET_THREAD_NUM ! $OMP PARALLEL NUM_THREADS(3) PRIVATE(rang) rang= OMP_GET_THREAD_NUM () print *,"Mon rang dans region 1 :",rang ! $OMP PARALLEL NUM_THREADS(2) PRIVATE(rang) rang= OMP_GET_THREAD_NUM () print *," Mon rang dans region 2 :",rang !$OMP END PARALLEL !$OMP END PARALLEL end program parallel

Page 113: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Exemple

#include <omp.h>

int main() { int rang = -1, rang2 = -1 ; omp_set_nested(1); #pragma omp parallel default(none) num_threads(2) private(rang,rang2) { rang = omp_get_thread_num() ; #pragma omp parallel default(none) num_threads(3) private(rang2) ,shared(rang) { rang2 = omp_get_thread_num() ; printf("Mon rang dans region 1 est : %d dans la region 2 est %d \n",rang, rang2) ; } } return 0 ; }

Oct. 2011 Coulaud - PG 305 - V 0 - 113

Page 114: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

$ ./nested Mon rang dans la region 1 est : 0 et dans la region 2 est 0 Mon rang dans la region 1 est : 0 et dans la region 2 est 1 Mon rang dans la region 1 est : 0 et dans la region 2 est 2 Mon rang dans la region 1 est : 1 et dans la region 2 est 0 Mon rang dans la region 1 est : 1 et dans la region 2 est 1 Mon rang dans la region 1 est : 1 et dans la region 2 est 2

Oct. 2011 Coulaud - PG 305 - V 0 - 114

Page 115: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

#pragma omp parallel default(shared) { #pragma omp for

for (i=0; i<n; i++) { #pragma omp parallel shared(i, n)

{ #pragma omp for

for (j=0; j<n; j++) work(i, j); }

} }

Oct. 2011 Coulaud - PG 305 - V 0 - 115

Page 116: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

#pragma omp parallel default(none) num_threads(2) private(rang) { rang = omp_get_thread_num() ; printf("Mon rang dans region 1 est : %d \n",rang) ; #pragma omp parallel default(none) num_threads(3) private(rang) { rang = omp_get_thread_num() ; printf("Mon rang dans la region 2 est %d \n",rang) ; } }

Oct. 2011 Coulaud - PG 305 - V 0 - 116

Page 117: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

$ ./nested_1 Mon rang dans region 1 est : 0 Mon rang dans la region 2 est 0 Mon rang dans region 1 est : 1 Mon rang dans la region 2 est 1 Mon rang dans la region 2 est 2 Mon rang dans la region 2 est 0 Mon rang dans la region 2 est 1 Mon rang dans la region 2 est 2

Oct. 2011 Coulaud - PG 305 - V 0 - 117

Page 118: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Fixer le nombre de threads par niveau

- Variable d’environnement : OMP_NUM_THREADS -  fonction: omp_set_num_threads() dans une région parallèle - Clause : num_threads(10)

Fixer/obtenir le nombre de threads dans le programme

- Variable d’environnement : OMP_THREAD_LIMIT -  fonction: omp_get_thread_imit() pour connaître le nombre de threads

disponible

Oct. 2011 Coulaud - PG 305 - V 0 - 118

Page 119: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Set/ get le nombre maximal de niveau de régions parallèles emboitées Variable d’environnement : OMP_MAX_ACTIVE_LEVELS

Fonctions omp_set_max_active_levels(), omp_get_max_active_levels()

Fonctions de la bibliothèques pour déterminer

La profondeur : omp_get_active_level() (1, 2, …, levelmax) Id du père : omp_get_ancestor_thread_num(level) La taille de l’équipe d’un niveau level: omp_get_team_size(level)

Oct. 2011 Coulaud - PG 305 - V 0 - 119

Page 120: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

CONSTRUCTION DE TÂCHES

Oct. 2011 Coulaud - PG 305 - V 0 - 120

Page 121: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Les tâches OpenMP

Principale nouveauté avec OpenMP 3.0

Offre un modèle flexible pour les problèmes irréguliers - Boucles non bornées (boucle while) ; - Algorithmes récursifs ; - Schémas producteurs/consommateurs

Oct. 2011 Coulaud - PG 305 - V 0 - 121

Page 122: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Les tâches OpenMP

Les tâches OpenMP sont des unités de travail indépendantes • Les threads sont affectés pour effectuer le travail des tâches ;

• L’exécution des tâches peut être différée ; • L’exécution des tâches peut être immédiate ;

le système d'exécution décide si l’exécution est différée ou immédiate. Une tâche est constituée

-  D’un code à exécuter ; -  D’un environnement de données initialisées à la

création ; -  De variables de contrôle interne (ICV).

Oct. 2011 Coulaud - PG 305 - V 0 - 122

Parallèle

Page 123: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Construction de tâches

C/C++: #pragma omp task [clause [[,]clause] ...]

structured-block

Oct. 2011 Coulaud - PG 305 - V 0 - 123

Permet de construire une tâche qui sera exécutée par un thread du pool de threads. On peut imbriquer le constructeur (parallélisme emboité)

Fortran: !$omp task [clause [[,]clause] ...]

structured-block !$omp end task

Page 124: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Construction de tâches

C/C++: #pragma omp task [clause [[,]clause] ...]

structured-block

Oct. 2011 Coulaud - PG 305 - V 0 - 124

Clauses : if (expression scalaire) final (expression scalaire) untied default (shared | none ) mergeable firstprivate (list) private (list) shared (list)

Fortran: !$omp task [clause [[,]clause] ...]

structured-block !$omp end task

Clauses : if (expression scalaire) final (expression scalaire) untied default (shared | private | firstprivate | none) mergeable firstprivate (list) private (list) shared (list)

Page 125: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Exemple : Hello world (1)

int main() { #pragma omp parallel {

#pragma omp single {

{ printf("Hello "); } { printf("World "); } printf("\nThank You "); } // End of single region } // End of parallel region printf("\n"); return(0); }

$ export OMP_NUM_THREADS=2 $ ./task_hello Hello World Thank You

Oct. 2011 Coulaud - PG 305 - V 0 - 125

Région parallèle

single

JOIN

wait

maître

Page 126: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Exemple : Hello world (2)

int main() { #pragma omp parallel {

#pragma omp single {

{ printf("Hello "); } { printf("World "); } printf("\nThank You "); } // End of single region } // End of parallel region printf("\n"); return(0); }

int main() { #pragma omp parallel {

#pragma omp single {

#pragma omp task { printf("Hello "); } #pragma omp task { printf("World "); } printf("\nThank You "); } // End of single region } // End of parallel region printf("\n"); return(0); }

Oct. 2011 Coulaud - PG 305 - V 0 - 126

$./task_hello_1 Thank You World Hello $./task_hello_1 Thank You World Hello $ ./task_hello_1 Thank You Hello World

Page 127: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Exemple : Hello world (3)

int main() { #pragma omp parallel {

#pragma omp single {

#pragma omp task { printf("Hello "); } #pragma omp task { printf("World "); } #pragma omp taskwait printf("\nThank You "); } // End of single region } // End of parallel region printf("\n"); return(0); }

$./task_hello_2 World Hello Thank You

Oct. 2011 Coulaud - PG 305 - V 0 - 127

Page 128: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Exemple : liste chainée

node *p = listhead ; while (p) {

do_independent_work(p) ; p = p->next() ;

}

Oct. 2011 Coulaud - PG 305 - V 0 - 128

Difficile de le faire avant OpenMP 3.0 Compte le nombre d’itérations transforme en une boucle finie for

Page 129: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Exemple : liste chainée

node *p = listhead ; #pragma omp parallel {

#pragma omp single {

while (p) { #pragma omp task firstprivate (p)

{

do_independent_work(p) ; } p = p->next()

} } // END SINGLE

} // END PARALLEL

Oct. 2011 Coulaud - PG 305 - V 0 - 129

Quand la tache se termine, le thread associé attend sur la barrière implicite de la construction single

Création des threads

Un thread exécute la boucle while

Création des tâches et exécution en parallèle

Chaque tâche s’exécute dans un thread

Page 130: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

La clause IF

Oct. 2011 Coulaud - PG 305 - V 0 - 130

•  Quand l’argument est faux • La tâche est exécutée immédiatement par

•  C’est une directive utilisateur pour optimiser • Quand le cout de création > cout de calcul • Pour contrôler l’affinité du cache et de la mémoire

Page 131: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Terminaison

Où et quand les tâches sont elles terminées ?

•  sur les barrières implicites (fin de région parallèle, …)

•  sur les barrières explicites #pragma omp barrier

S’applique à toutes les tâches générées dans la région parallèle

•  Sur les barrières des tâches #pragma omp taskwait

Attend jusqu’à ce que toutes les tâches définies par le constructeur aient terminées. Ne s’applique pas aux descendants

Oct. 2011 Coulaud - PG 305 - V 0 - 131

Page 132: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Exercice : le tri rapide récursif

Paralléliser l’algorithme du Quicksort écrit de manière récursive. Code séquentiel disponible dans la section OpenMP http://people.bordeaux.inria.fr/coulaud/Enseignement/PG305

Oct. 2011 Coulaud - PG 305 - V 0 - 132

Exo

Page 133: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Exercice : le tri rapide récursif

void init_data() { int i, x, y, t; for (i = 0; i < N; i++) A[i] = i; for (i = 0; i < N; i++) { x = rand()%N; y = rand()%N; t = A[y]; A[y] = A[x]; A[x] = t; } }

Oct. 2011 Coulaud - PG 305 - V 0 - 133

#define N 100 ; int A[N] ; int main(int argc, char* argv[]) { init_data(); for (int i = 0; i < N; i++) printf("%3d ",A[i]);

printf("\n\n"); Quicksort(0, N-1); for (int j = 0; j < N; j++) printf("%3d ",A[j]); printf("\n\n"); return 0; }

Page 134: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Exercice : le tri rapide récursif

void Quicksort(int p, int r) { if (p < r) { int q = Partition(p, r); // indice du pivot Quicksort(p, q-1); Quicksort(q+1, r); } } int Partition (int p, int r) { int x = A[p]; // pivot int k = p; // index int l = r+1; // index int t;

Oct. 2011 Coulaud - PG 305 - V 0 - 134

while (1) { do k++; while ((A[k] <= x) && (k < r)); do ; l--; while (A[l] > x); while (k < l) { t = A[k]; A[k] = A[l]; A[l] = t; do k++; while (A[k] <= x); do l--; while (A[l] > x); } t = A[p]; A[p] = A[l]; A[l] = t; return l; // retourne l'indice du pivot } }

Page 135: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Bilan

Simple et facile à mettre en œuvre Pour avoir de la performance

Ne pas créer trop de threads Temps de calcul grand > temps de création Equilibrer le travail dans les threads à Implique de revoir l’algorithme.

Oct. 2011 Coulaud - PG 305 - V 0 - 135

Page 136: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Exercice : Les nombres de Fibonacci

Les nombres de Fibonacci sont définis comme suit Suite : 1, 1, 2, 3, 5, 8, 13, 21, 34

Oct. 2011 Coulaud - PG 305 - V 0 - 136

F(0) = 1 F(1) = 1 F(n) = F(n-1) + F(n-2) (n=2,3, …)

Page 137: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

OpenMP en 1 slide

Oct. 2011 Coulaud - PG 305 - V 0 - 137

Page 138: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Conclusion (1)

II est facile d’insérer des directives OpenMP Toutefois, pour avoir de bonnes performances

•  Le coût des synchronisations doit être réduit •  La localité des données doit être optimisée à tous les niveaux

Le style SPMD style conduit à de bonnes performances •  Mais demande beaucoup d’effort à programmer

OpenMP a la flexibilité pour permettre les deux sortes de programmation

Oct. 2011 Coulaud - PG 305 - V 0 - 138

Page 139: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Conclusion (2)

•  Les plus •  Facilité de programmation •  Parallélisation incrémentale •  Haut niveau d’abstraction •  Bonne performance (modèle SPMD)

•  Les moins •  Des manques (aspect NUMA thread ou data affinity) *  Manque de performances sur les tâches *  Pas d’information sur ce que fait le runtime

•  Pour plus de détails : http://www.openmp.org

Oct. 2011 Coulaud - PG 305 - V 0 - 139

Page 140: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

TP openMP

Ecrire la version parallèle OpenMP du produit matrice – vecteur dont la version séquentielle est

For (i=0 ;i<n ;i++) {

C[i]=0 ; For (j=0 ;j<n ;j++)

C[i]+=A[i][j]*B[j] ; } 1.  Ecrire le produit par ligne 2.  Ecrire le produit par bloc 3.  La directive collapse peut-elle fonctionner ? Expliquer pourquoi.

Oct. 2011 Coulaud - PG 305 - V 0 - 140

Page 141: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Remerciements

Documents utilisés pour ces transparents Cours de l’IDRIS Rudolf Eigenmann, Tim Mattson : tutorial OpenMP à SC’2001 Miguel Hermanns : Parallel Programming in Fortran 95 using OpenMP Tim Mattson et Larry Meadows :A “Hands-on” Introduction to OpenMP

SC’2008 ….

Page 142: Introduction à la programmation par directivespeople.bordeaux.inria.fr/coulaud/Enseignement/PG305/pg...Introduction à la programmation par directives Plan Introduction Le modèle

Exercice 1 Solution

Oct. 2011 Coulaud - PG 305 - V 0 - 142

PROGRAM HELLO INTEGER :: TID INTEGER :: OMP_GET_THREAD_NUM !$OMP PARALLEL PRIVATE(TID) TID = OMP_GET_THREAD_NUM() PRINT *, 'Hello World from thread = ', TID !$OMP END PARALLEL END PROGRAM HELLO


Recommended