35
1 1 Présentation rapide d’

Présentation rapide d’

  • Upload
    argyle

  • View
    41

  • Download
    0

Embed Size (px)

DESCRIPTION

Présentation rapide d’. 1. Plan. OpenMP et la programmation multithread en mémoire partagée La programmation multithread OpenMP OpenMP en pratique Les directives de partage du travail Les directives de synchronisation La bibliothèque d’OpenMP OpenMP plus précisément… - PowerPoint PPT Presentation

Citation preview

Page 1: Présentation rapide d’

11

Présentation rapide d’

Page 2: Présentation rapide d’

2

• OpenMP et la programmation multithread en mémoire partagée– La programmation multithread– OpenMP

• OpenMP en pratique– Les directives de partage du travail– Les directives de synchronisation– La bibliothèque d’OpenMP

• OpenMP plus précisément…– Implémentation pratique– Le parallélisme imbriqué– OpenMP2

Plan

Page 3: Présentation rapide d’

3

• OpenMP est un standard de programmation multithread en mémoire partagée

• OpenMP est portable sur l’ensemble des calculateurs à mémoire partagée (développé et soutenue par des fabricants de machines et de compilateurs)

• OpenMP permet une parallelisation progressive des codes

• OpenMP est utilisable avec les langages Fortran (77,90,…), C et C++

• Les compilateurs enrichissent les langages de programmation existants– principalement par directives ( de partage de travail, de

synchronisation )– plus quelques fonctions de la bibliothèque OpenMP

Contexte et intérêt d’OpenMP

Page 4: Présentation rapide d’

4

Contexte et intérêt d’OpenMP

Page 5: Présentation rapide d’

5

• OpenMP est une approche très simple de la programmation multi-treaded

• Les nouveaux processeurs permettent d’utiliser plusieurs tread– Intel Pentium IV Hypertreaming

– AMD Opteron 2XX 4XX 8XX sont des calculateurs parallèle à mémoire partagée

– Apparition de CPU multi-core • IBM Power• SUN UltraSPARc IV• HP PA8800• Bientôt Opteron, pentium

Contexte et intérêt d’OpenMP

Page 6: Présentation rapide d’

6

• La plus part des instructions OpemMP sont des directives

• Une des cibles d’OpenMP est la parallelisation des boucles

• OpenMP permet une approche incrémentale du parallélisme (peu de changement du code source)

Programme séquentiel Programme parallèle

void main()

{

double Res[1000];

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

{

gros_calcul(Res[i]);

}

}

void main()

{

double Res[1000];

#pragma omp parallel for

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

{

gros_calcul(Res[i]);

}

}

Un programme simple en OpenMP

Page 7: Présentation rapide d’

7

• Introduction au modèle multithread en mémoire partagée

• OpenMP

• Structure d’un programme OpenMP

• Directives d’ouverture/fermeture de région parallèle

• HelloWorld_OpenMP.c

Partie 1 : OpenMp ?

Page 8: Présentation rapide d’

8

• Le problème :– On dispose de n processeurs– Ces machines sont connectées par un mécanisme de mémoire

partagée entre eux

Comment utiliser cette machine à n processeurs reliés par de la mémoire partagée ?

RAM (partagée)

CPU CPU CPU CPU CPU CPUCPU

Multithreading en mémoire partagée

Page 9: Présentation rapide d’

9

• Une réponse : le multithreading en mémoire partagée– Faire exécuter un processus qui va « spawner » des threads (flots

d’exécution) sur chaque processeur– Effectuer des échanges de données de façon transparente via la

mémoire partagée– Synchroniser explicitement au besoin, par exemple avec des

verrous (locks)

• Le modèle le plus simple pour l’utilisateur paraît être d’ouvrir/fermer les sections parallèles en fonction des besoins et de la possibilité de paralléliser

Multithreading en mémoire partagée

Page 10: Présentation rapide d’

10

• ‘Quasi’-standard développé et soutenu par les fabricants de machines, et de compilateurs

• But : spécifier une interface simple pour permettre la programmation parallèle en mémoire partagée à l’aide de threads

• Le modèle choisi repose sur des directives de compilation qui génèrent un code multithread

• En fait ces directives proviennent des directives constructeurs déjà présentes chez Cray, SGI, … et tous les autres fabricants de multiprocesseurs de grande taille

• Le but est de promouvoir la simplicité d’utilisation de telles machines (très coûteuses) via une interface simple d’utilisation

OpenMP

Page 11: Présentation rapide d’

11

• Utiliser un langage à directives revient à insérer des lignes de commandes dans le code du programme, et qui seront traitées par le pré-compilateur. Ces directives sont utilisées sur des régions structurées! (un point d’entrée, un point de sortie, uniques)

• Dans le cas d’OpenMP, un code C ou Fortran multithread est alors généré, puis compilé

• Les directives OpenMP sont des commentaires (permet de compiler avec/sans le support OpenMP), prenant la forme :

– C :#pragma omp <directive> [clause [clause ] … ]

– Fortran : !$OMP, C$OMP, *$OMP <directive> [clause [ clause ] … ]

Les directives de compilation

Page 12: Présentation rapide d’

12

• Multithreading et parallélisme fork/join– Un processus est lancé, qui « spawne » ensuite les threads

lorsqu’une région parallèle est rencontrée– La parallelisation peut être réalisée de façon incrémentale

Région séquentielle

Région parallèle multithread

Structure d’un programme OpenMP

Page 13: Présentation rapide d’

13

• La déclaration :– Fortran :

!$OMP PARALLEL [CLAUSE [[,] CLAUSE] …]

!$OMP END PARALLEL– C/C++ :

#pragma omp parallel

{

}

• Remarque : leurs portées ne ce limite pas au bloc mais également à toutes les procédures appelées dans le bloc parallèle

double A[1000]

#pragma omp parallel

{

int id = omp_get_thread_num();

fonc(id,A);

}

Les régions parallèles

Page 14: Présentation rapide d’

14

double A[1000]

fonc(0,A) fonc(1,A) fonc(3,A)

printf("fin\n ");

fonc(4,A)

Tous les threads s’attendent ici (synchronisation de type barrière)

La variable A est partagée par tout les threads

Les régions parallèles

Page 15: Présentation rapide d’

15

• Notions élémentaires : variables partagées ou privées

• Directives de partage de travail

• Directives de synchronisation

• Fonctions de la bibliothèque

• Exemple concret : calcul de la trace d’une matrice carrée

Partie 2 : OpenMP concrètement

Page 16: Présentation rapide d’

16

• Une variable partagée pourra être écrite et lue par tous les threads

• Une variable est dite privée pour un thread si seulement lui peut la lire et l’écrire

• Les clauses SHARED ou PRIVATE permettent de préciser lors de l’ouverture de la région quelles variables sont partagées ou privées. Il est aussi possible de préciser la valeur par défaut (exemple : !$OMP PARALLEL DEFAULT(SHARED) )

• Certaines variables sont privées par défaut. Exemple : les indices des boucles parallélisées avec les directives for/DO

• Les variables utilisées dans les fonctions appelées par les zones parallèles sont systématiquement privées!

Des variables partagées et privées

Page 17: Présentation rapide d’

17

• PRIVATE– La variable est privée pour chacun des threads

• SHARED– La variable est partagée entre tous les threads

• FIRSTPRIVATE– La variable est privée et prend la valeur qu’avait la variable du

même nom sur le thread maître

• LASTPRIVATE– La valeur en sortie de région parallèle est la copie de celle de la

dernière itération en séquentiel

• THREADPRIVATE– Utilisée pour préciser qu’une variable est privée (utile pour les

variables globales)

Des variables partagées et privées

Page 18: Présentation rapide d’

18

• Une des cibles d’OpenMP : permettre de distribuer les itérations des boucles entre les différents threads

• Syntaxe :– C : #pragma omp for– Fortran : !$OMP DO / !$OMP END DO

• En pratique :

#pragma omp parallel

{

#pragma omp for

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

{

}

}

La cible : distribution des boucles

Page 19: Présentation rapide d’

19

• Par défaut, tous les threads s’arrêtent et attendent lorsque la fin de la boucle est atteinte (barrière de synchronisation explicite)– Ce comportement peut être changé en utilisant la clause NOWAIT

• La façon dont les itérations sont distribuées entre les différents threads peut être modifiée via la clause schedule, ou via la variable d’environnement OMP_SCHEDULE

– static, taille : consiste a diviser les itérations en paquets d'une taille donnée (sauf peut-être pour le dernier)

– dynamic, taille : les itérations sont divisées en paquets de taille donnée. Sitôt qu'une tâche épuise ses itérations, un autre paquet lui est attribue

– guided, taille : les itérations sont divisées en paquets dont la taille décroît exponentiellement jusqu’à taille.

– runtime : le choix ce fait lors de l’exécution

– ordered : l’ordre de la boucle est respecté ( mode debug principalement )

La cible : distribution des boucles

Page 20: Présentation rapide d’

20

• La directive SECTION permet d’attribuer à chaque thread un bloc structuré différent (programmation MPMD : Multiple Program, Multiple Data)

#pragma omp parallel

#pragma omp sections {

#pragma omp section

section1…

#pragma omp section

section2…

#pragma omp section

section3…

}

Distribution du calcul

Page 21: Présentation rapide d’

21

• Afin de permettre d’effectuer une opération globale sur les valeurs locales obtenues en sortie d’une région parallèle, on peut utiliser une clause de réduction

• Utilisation (dans PARALLEL, DO/for, …)– REDUCTION (opération: liste de variables)

• Opérations disponibles:– min, max– +, -, *– …

int i;

double z,res=0.0;

double v[1000];

#pragma omp parallel for reduction(+:ps) private (z)

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

{

z = f(i) ;

res = res + z ;

}

La clause de réduction

Page 22: Présentation rapide d’

22

• Ces directives permettent d’assurer que le code n’est exécute que par un seul thread

• Dans le cas de SINGLE, un seul thread (généralement le premier) procède à l’exécution de la zone considérée, les autres attendent ce thread a la fin du bloc SINGLE. La clause COPYPRIVATE permet de diffuser la valeur d’une liste de variables privées avant de sortir de cette région

• Dans le cas de MASTER, c’est toujours le thread maître (de rang 0) qui exécute cette tache. Il n’y a aucune synchronisation des threads avec cette directive.

Single / Master

Page 23: Présentation rapide d’

23

• OpenMP possède des directives permettant de synchroniser les threads entre eux, ou du moins de contrôler plus finement le déroulement de l’exécution.

• Ce sont les directives:– ATOMIC– CRITICAL– BARRIER– FLUSH– ORDERED

Les synchronisations

Page 24: Présentation rapide d’

24

• Les directives ATOMIC et CRITICAL permettent de spécifier qu’un seul thread entrera à la fois dans la région suivant immédiatement la directive (l’ordre restant indéterminé)

• La différence réside dans le fait que ATOMIC se base principalement sur les instructions atomiques des processeurs, et correspond à une mise à jour de variable alors que CRITICAL englobe toute une partie de code (implémentation moins efficace)– Les Instructions atomique

• x = x (op) exp avec (op) : +, -, *, /, etc• x = f(x,exp) exp : une expression

arithmétique indépendante de x

• Ces directives peuvent par exemple servir à effectuer une réduction « manuelle » en cours de calcul

Atomic / Critical

Page 25: Présentation rapide d’

25

Barrier / flush

• La directive BARRIER est une barrière de synchronisation : tous les threads l’atteignant attendront que les autres threads arrivent à la barrière avant de continuer l’exécution

• La directive FLUSH(variable) permet de rafraîchir la variable partagée variable visible de tous les processeurs. Elle est d'autant plus utile que la mémoire d'une machine est hiérarchisée. Elle peut servir à synchroniser

Barrier / Flush

Page 26: Présentation rapide d’

26

• Dans une boucle parallélisée avec OMP DO/for, la directive ORDERED permet de s’assurer que l’ordre des opérations à l’intérieur de la zone de la directive sera exécutée dans l’ordre correspondant aux itérations de la boucle, comme dans le cas séquentiel. Ceci est utile principalement en mode debug.

Ordered (plutôt en Debug)

Page 27: Présentation rapide d’

27

• Fonctions permettant de connaître le rang des différents threads ainsi que le nombre total de threads, – omp_get_num_threads(), omp_get_tread_num()

• Synchronisation par des verrous– omp_init_lock(),– omp_set/unset_lock(), – omp_test_lock()…

• Savoir si l’on est dans une zone parallèle ou pas– omp_in_parallel()

• Mesurer le temps écoulé en seconde, avec quelle précision– omp_get_wtime(), omp_get_wtick()

• …

Des fonctions de la bibliothèque OpenMP

Page 28: Présentation rapide d’

28

• Calcul de la trace d’une matrice An

• Rappel : la trace d’une matrice est la somme des éléments de sa diagonale (matrice nécessairement carrée)

• Mathématiquement, on sait que :

• Immédiatement, on voit facilement que le problème peut être parallélisé en calculant la somme des éléments diagonaux sur plusieurs processeurs puis en utilisant une réduction pour calculer la trace globale

n

k

kkAATrace1

,)(

Exemple : Trace d’une matrice

Page 29: Présentation rapide d’

29

#include <stdio.h>

#include <omp.h>

void main(int argc, char ** argv)

{

int me, np, root=0;

int N; /* On suppose que N = m*np */

double A[N][N];

double traceA = 0;

/* Initialisation de A */

/* … */

#pragma omp parallel default(shared)

#pragma omp for reduction (+:trace)

{

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

{

traceA += A[i][i]

}

}

printf("La trace de A est : %f \n", traceA);

}

Exemple : Trace d’une matrice

Page 30: Présentation rapide d’

30

• Note sur l’implémentation

• Le parallélisme imbriqué

• OpenMP2

Partie 3 : Notions avancées

Page 31: Présentation rapide d’

31

• La création sémantique de multiples zones parallèles ne signifie pas forcement leur création réelle…

Modèle abstrait

Implémentation probable

Notes sur l’implémentation

Page 32: Présentation rapide d’

32

Le thread maître insère des taches dans la pile de taches

Les threads esclaves exécutent la boucle :{prendre une tâche dans la pile; exécuter la tâche}

Le thread maître exécute des taches de la pile. Si elle est vide, il attend la terminaison par les autres threads

Le maître exécute le code séquentiel

Le thread maître exécute le code séquentiel

Un environnement possible d’exécution

Notes sur l’implémentation

Page 33: Présentation rapide d’

33

• La notion de parallélisme imbriqué fait référence à la possibilité d’ouvrir une région parallèle à l’intérieur d’une région déjà parallèle

• Immédiatement, on peut voir les applications dans le cas de la parallelisation des nids de boucles, par exemple pour procéder ‘par blocs’

• Toutefois, la plupart des compilateurs sérialisent les régions imbriquées, par manque de support au point de vue du système d’exploitation (en pratique, seules les NEC SX5 et les Compaq ES-40 permettent une telle approche)

Parallélisme imbriqué

Page 34: Présentation rapide d’

34

• OpenMP est avant tout un outil qui a pour but de procurer un mode de parallelisation attractif car incrémental et simple d’utilisation

• Il est avant tout promu par les constructeurs et les fabricants de compilateurs

• Se concentrant uniquement sur l’aspect de la parallelisation des taches, par rapport à d’autres outils comme HPF, des études en cours essaient d’y ajouter cet aspect de placement de données

Remarques

Page 35: Présentation rapide d’

35

• Le site officiel du ‘standard’ OpenMP (en Anglais)– http://www.openmp.org

• Les cours de l’IDRIS (en Français)– http://www.idris.fr/data/cours/parallel/openmp/

Plus d’information =>