Introduction au calcul parallèle: OPENMP
Transcription
Introduction au calcul parallèle: OPENMP
Introduction au calcul parallèle: OPENMP Pascal Viot September 3, 2016 Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 1 / 21 Avant-propos Les processeurs sont constitués d’un nombre de coeurs (ou unités de calcul) qui augmente avec le temps: initialement, un seul, puis deux, maintenant souvent 4, voire 6 ou 8 jusqu’à 20 pour des serveurs de calcul. Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 2 / 21 Avant-propos Les processeurs sont constitués d’un nombre de coeurs (ou unités de calcul) qui augmente avec le temps: initialement, un seul, puis deux, maintenant souvent 4, voire 6 ou 8 jusqu’à 20 pour des serveurs de calcul. Par rapport à un parallèlisme où les calculs se font sur différentes machines, on peut utiliser le fait que sur une seule machine, la mémoire utilisée par l’ensemble des unités de calcul est la même et peut être accessible théoriquement simplement par tous. Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 2 / 21 Avant-propos Les processeurs sont constitués d’un nombre de coeurs (ou unités de calcul) qui augmente avec le temps: initialement, un seul, puis deux, maintenant souvent 4, voire 6 ou 8 jusqu’à 20 pour des serveurs de calcul. Par rapport à un parallèlisme où les calculs se font sur différentes machines, on peut utiliser le fait que sur une seule machine, la mémoire utilisée par l’ensemble des unités de calcul est la même et peut être accessible théoriquement simplement par tous. On peut faire calculer les différentes unités en même temps, à condition de ne pas vouloir se marcher sur les pieds (c’est-à-dire de ne pas écrire en même temps aux mêmes emplacements mémoire). Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 2 / 21 Avant-propos Les processeurs sont constitués d’un nombre de coeurs (ou unités de calcul) qui augmente avec le temps: initialement, un seul, puis deux, maintenant souvent 4, voire 6 ou 8 jusqu’à 20 pour des serveurs de calcul. Par rapport à un parallèlisme où les calculs se font sur différentes machines, on peut utiliser le fait que sur une seule machine, la mémoire utilisée par l’ensemble des unités de calcul est la même et peut être accessible théoriquement simplement par tous. On peut faire calculer les différentes unités en même temps, à condition de ne pas vouloir se marcher sur les pieds (c’est-à-dire de ne pas écrire en même temps aux mêmes emplacements mémoire). La bibliothèque OPENMP contenu dans les deux compilateurs Gnu et Intel permet de réaliser ces opérations. Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 2 / 21 Plan OPENMP: définition Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 3 / 21 Plan OPENMP: définition Définition du monde de calcul Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 3 / 21 Plan OPENMP: définition Définition du monde de calcul Compilation et exécution d’un programme OPENMP, variables d’environnement Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 3 / 21 Plan OPENMP: définition Définition du monde de calcul Compilation et exécution d’un programme OPENMP, variables d’environnement Boucle parallèle Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 3 / 21 Plan OPENMP: définition Définition du monde de calcul Compilation et exécution d’un programme OPENMP, variables d’environnement Boucle parallèle Fonctions d’exécution Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 3 / 21 Plan OPENMP: définition Définition du monde de calcul Compilation et exécution d’un programme OPENMP, variables d’environnement Boucle parallèle Fonctions d’exécution Réduction Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 3 / 21 Plan OPENMP: définition Définition du monde de calcul Compilation et exécution d’un programme OPENMP, variables d’environnement Boucle parallèle Fonctions d’exécution Réduction Conclusion et références. Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 3 / 21 OPENMP: définition et différentes versions OPENMP: La version courante est la 4.5 et date de Novembre 2015. Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 4 / 21 OPENMP: définition et différentes versions OPENMP: La version courante est la 4.5 et date de Novembre 2015. Site: http://openmp.org/wp/. Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 4 / 21 OPENMP: définition et différentes versions OPENMP: La version courante est la 4.5 et date de Novembre 2015. Site: http://openmp.org/wp/. Les compilateurs contiennent la bibliothèque OPENMP, en particulier le compilateur Gnu et le compilateur Intel Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 4 / 21 OPENMP: définition et différentes versions OPENMP: La version courante est la 4.5 et date de Novembre 2015. Site: http://openmp.org/wp/. Les compilateurs contiennent la bibliothèque OPENMP, en particulier le compilateur Gnu et le compilateur Intel OPENMP est un bibliothèque pour les langages Fortran, C, et C++. Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 4 / 21 OPENMP: définition et différentes versions OPENMP: La version courante est la 4.5 et date de Novembre 2015. Site: http://openmp.org/wp/. Les compilateurs contiennent la bibliothèque OPENMP, en particulier le compilateur Gnu et le compilateur Intel OPENMP est un bibliothèque pour les langages Fortran, C, et C++. La programmation avec OPENMP peut se ramener principalement à insérer des directives dans un programme séquentiel existant Cela signifie que le programme peut toujours fonctionner en séquentiel ou en utilisant des unités de calcul associées à une mémoire centrale unique. Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 4 / 21 OPENMP: définition et différentes versions OPENMP: La version courante est la 4.5 et date de Novembre 2015. Site: http://openmp.org/wp/. Les compilateurs contiennent la bibliothèque OPENMP, en particulier le compilateur Gnu et le compilateur Intel OPENMP est un bibliothèque pour les langages Fortran, C, et C++. La programmation avec OPENMP peut se ramener principalement à insérer des directives dans un programme séquentiel existant Cela signifie que le programme peut toujours fonctionner en séquentiel ou en utilisant des unités de calcul associées à une mémoire centrale unique. Les ordinateurs étant constitués de un ou plusieurs ordinateurs et réliés en réseau, l’idéal est de combiner OPENMP et MPI, mais cela reste plus compliqué pour le développement. Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 4 / 21 Définition du monde de calcul, initialisation et fin d’execution Mémoire Réseau Unité Code Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 5 / 21 Définition du monde de calcul, initialisation et fin d’execution(2) #include <stdio.h> int main(void) { #pragma omp parallel { printf("Hello, world.\n"); } printf("bonjour, monde.\n"); return 0; } Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 6 / 21 Compilation et exécution d’un programme OPENMP, variables d’environnement la directive #pragma omp parallel ainsi que les accolades qui suivent indiquent que le code de ce bloc doit être parallèlisé. Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 7 / 21 Compilation et exécution d’un programme OPENMP, variables d’environnement la directive #pragma omp parallel ainsi que les accolades qui suivent indiquent que le code de ce bloc doit être parallèlisé. Ainsi l’impression Hello, World apparaı̂tra autant de fois que des unités de calcul auront été sollicités Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 7 / 21 Compilation et exécution d’un programme OPENMP, variables d’environnement la directive #pragma omp parallel ainsi que les accolades qui suivent indiquent que le code de ce bloc doit être parallèlisé. Ainsi l’impression Hello, World apparaı̂tra autant de fois que des unités de calcul auront été sollicités Pour compiler ce programme avec gcc: gcc hello.c -fopenmp -o hello Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 7 / 21 Compilation et exécution d’un programme OPENMP, variables d’environnement la directive #pragma omp parallel ainsi que les accolades qui suivent indiquent que le code de ce bloc doit être parallèlisé. Ainsi l’impression Hello, World apparaı̂tra autant de fois que des unités de calcul auront été sollicités Pour compiler ce programme avec gcc: gcc hello.c -fopenmp -o hello Pour compiler ce programme avec intel: icc hello.c -openmp -o hello Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 7 / 21 Compilation et exécution d’un programme OPENMP, variables d’environnement la directive #pragma omp parallel ainsi que les accolades qui suivent indiquent que le code de ce bloc doit être parallèlisé. Ainsi l’impression Hello, World apparaı̂tra autant de fois que des unités de calcul auront été sollicités Pour compiler ce programme avec gcc: gcc hello.c -fopenmp -o hello Pour compiler ce programme avec intel: icc hello.c -openmp -o hello Si on execute ce programme, il choisit le nombre d’unités disponibles. Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 7 / 21 Compilation et exécution d’un programme OPENMP, variables d’environnement la directive #pragma omp parallel ainsi que les accolades qui suivent indiquent que le code de ce bloc doit être parallèlisé. Ainsi l’impression Hello, World apparaı̂tra autant de fois que des unités de calcul auront été sollicités Pour compiler ce programme avec gcc: gcc hello.c -fopenmp -o hello Pour compiler ce programme avec intel: icc hello.c -openmp -o hello Si on execute ce programme, il choisit le nombre d’unités disponibles. Pour fixer celles-ci, on donne la variable d’environnement dans la fenêtre terminal avant de lancer le programme export OMP NUM THREADS=20 Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 7 / 21 Compilation et exécution d’un programme OPENMP, variables d’environnement (2) Le nombre d’unités que l’on fixe est virtuel, et ne correspond pas nécessairement au nombre physique. Toutefois, pour un programme de calcul, il convient de ne pas dépasser le nombre physique car l’exécution ne peut pas être plus rapide si on dépasse la limite (à des subtilités près avec le multitheading). Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 8 / 21 Compilation et exécution d’un programme OPENMP, variables d’environnement (2) Le nombre d’unités que l’on fixe est virtuel, et ne correspond pas nécessairement au nombre physique. Toutefois, pour un programme de calcul, il convient de ne pas dépasser le nombre physique car l’exécution ne peut pas être plus rapide si on dépasse la limite (à des subtilités près avec le multitheading). La directive exécute N fois le même groupe d’instructions. Il convient donc de modifier la programmation pour que un calcul soit réparti et non pas executé N fois. Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 8 / 21 Compilation et exécution d’un programme OPENMP, variables d’environnement (2) Le nombre d’unités que l’on fixe est virtuel, et ne correspond pas nécessairement au nombre physique. Toutefois, pour un programme de calcul, il convient de ne pas dépasser le nombre physique car l’exécution ne peut pas être plus rapide si on dépasse la limite (à des subtilités près avec le multitheading). La directive exécute N fois le même groupe d’instructions. Il convient donc de modifier la programmation pour que un calcul soit réparti et non pas executé N fois. Limitations physiques d’un programme OMP Pour qu’une partie du code soit exécutée en faisant à N unités de calcul, le système doit créer des fils (threads), puis à la fin les détruire. Le temps nécessaire n’est pas toujours négligeable même si par rapport à MPI, nous n’avons pas besoin d’échanger des données. Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 8 / 21 Compilation et exécution d’un programme OPENMP, variables d’environnement (2) Le nombre d’unités que l’on fixe est virtuel, et ne correspond pas nécessairement au nombre physique. Toutefois, pour un programme de calcul, il convient de ne pas dépasser le nombre physique car l’exécution ne peut pas être plus rapide si on dépasse la limite (à des subtilités près avec le multitheading). La directive exécute N fois le même groupe d’instructions. Il convient donc de modifier la programmation pour que un calcul soit réparti et non pas executé N fois. Limitations physiques d’un programme OMP Pour qu’une partie du code soit exécutée en faisant à N unités de calcul, le système doit créer des fils (threads), puis à la fin les détruire. Le temps nécessaire n’est pas toujours négligeable même si par rapport à MPI, nous n’avons pas besoin d’échanger des données. Le temps associé à ce processus est de l’ordre de 1µs. A nouveau très supérieur au temps d’horloge du processeur. Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 8 / 21 Boucle parallèle La directive pour rendre une boucle parallèle est #pragma omp parallel for Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 9 / 21 Boucle parallèle La directive pour rendre une boucle parallèle est #pragma omp parallel for Avec cette directive, le programme est capable de découper la boucle en différentes parties exécutées sur des unités de calcul différentes. Une fois réalisée, le programme détruit les threads. Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 9 / 21 Boucle parallèle La directive pour rendre une boucle parallèle est #pragma omp parallel for Avec cette directive, le programme est capable de découper la boucle en différentes parties exécutées sur des unités de calcul différentes. Une fois réalisée, le programme détruit les threads. On peut regarder avec l’instruction top dans une autre fenêtre terminal que le pourcentage est supérieur à 100%, ce qui illustre le fait que le programme mobilise plusieurs unités de calcul lors de l’exécution. Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 9 / 21 Boucle parallèle La directive pour rendre une boucle parallèle est #pragma omp parallel for Avec cette directive, le programme est capable de découper la boucle en différentes parties exécutées sur des unités de calcul différentes. Une fois réalisée, le programme détruit les threads. On peut regarder avec l’instruction top dans une autre fenêtre terminal que le pourcentage est supérieur à 100%, ce qui illustre le fait que le programme mobilise plusieurs unités de calcul lors de l’exécution. On peut ajouter sur l’instruction précédente des directives supplémentaires qui spécifient quelles sont les variables qui sont communes à l’ensemble des threads et celles qui sont internes. Par défaut, le compilateur est censé bien deviner, mais rien ne vous empèche de le guider pour faire les bon choix. Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 9 / 21 Boucle parallèle La directive pour rendre une boucle parallèle est #pragma omp parallel for Avec cette directive, le programme est capable de découper la boucle en différentes parties exécutées sur des unités de calcul différentes. Une fois réalisée, le programme détruit les threads. On peut regarder avec l’instruction top dans une autre fenêtre terminal que le pourcentage est supérieur à 100%, ce qui illustre le fait que le programme mobilise plusieurs unités de calcul lors de l’exécution. On peut ajouter sur l’instruction précédente des directives supplémentaires qui spécifient quelles sont les variables qui sont communes à l’ensemble des threads et celles qui sont internes. Par défaut, le compilateur est censé bien deviner, mais rien ne vous empèche de le guider pour faire les bon choix. Pour une boucle avec un indice de boucle appelé i, on peut écrire #pragma omp parallel for default(shared), private(i) Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 9 / 21 Boucle parallèle La directive pour rendre une boucle parallèle est #pragma omp parallel for Avec cette directive, le programme est capable de découper la boucle en différentes parties exécutées sur des unités de calcul différentes. Une fois réalisée, le programme détruit les threads. On peut regarder avec l’instruction top dans une autre fenêtre terminal que le pourcentage est supérieur à 100%, ce qui illustre le fait que le programme mobilise plusieurs unités de calcul lors de l’exécution. On peut ajouter sur l’instruction précédente des directives supplémentaires qui spécifient quelles sont les variables qui sont communes à l’ensemble des threads et celles qui sont internes. Par défaut, le compilateur est censé bien deviner, mais rien ne vous empèche de le guider pour faire les bon choix. Pour une boucle avec un indice de boucle appelé i, on peut écrire #pragma omp parallel for default(shared), private(i) En changeant l’instruction OMP NUM THREADS, on peut changer le nombre par défaut de threads utilisé. Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 9 / 21 Boucle parallèle (2) #include <stdio.h> #include <math.h> #include<stdlib.h> inline double essai(double x) { return(5.0+10.0*x+x*x*exp(x)*log(x+0.1)+sqrt(abs(x)));} int main(){ int NITER=200000000; double *a; a=(double *) malloc(sizeof(double)*NITER); #pragma omp parallel for default(shared) for (int j=0;j<NITER;j++){ a[j] = essai(j*0.01);} exit(0); } Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 10 / 21 Fonctions d’exécution Il existe plusieurs fonctions d’exécution qui permettent d’avoir des informations sur les processus parallèlisés et/ou modifie à l’intérieur du programme la manière dont la parallélisation est réalisée. Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 11 / 21 Fonctions d’exécution Il existe plusieurs fonctions d’exécution qui permettent d’avoir des informations sur les processus parallèlisés et/ou modifie à l’intérieur du programme la manière dont la parallélisation est réalisée. Parmi ces fonctions, citons omp get num threads() qui donne le nombre de threads, omp get thread num() qui donne le numéro du thread et omp get wtime qui donne le temps en valeur décimale. Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 11 / 21 Fonctions d’exécution #include <stdio.h> #include <math.h> #include<stdlib.h> #include<omp.h> inline double essai(double x) { return(5.0+10.0*x+x*x*exp(x)*log(x+0.1)+sqrt(abs(x)));} int main(){ int NITER=20000000; double *a; a=(double *) malloc(sizeof(double)*NITER); #pragma omp parallel { int nthreads=omp_get_num_threads(); double debut=omp_get_wtime(); #pragma omp parallel for default(shared) for (int j=0;j<NITER;j++){ a[j] = essai(j*0.01);} double fin=omp_get_wtime(); printf("nombre de threads %d temps %e \n",nthreads,fin-debut); } exit(0); } Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 12 / 21 Réduction On peut colllecter les données sur chaque unité de calcul et réaliser les opérations élémentaire d’addition et de multiplication. Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 13 / 21 Réduction On peut colllecter les données sur chaque unité de calcul et réaliser les opérations élémentaire d’addition et de multiplication. l’instruction s’ajoute comme argument d’un pragma comme reduction(operator:list) Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 13 / 21 Réduction On peut colllecter les données sur chaque unité de calcul et réaliser les opérations élémentaire d’addition et de multiplication. l’instruction s’ajoute comme argument d’un pragma comme reduction(operator:list) Outre les opérations usuelles, on a aussi la possibilité de rechercher le plus grand ou le plus petit élément d’une liste. Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 13 / 21 Premier programme scientifique #include <stdio.h> #include <stdlib.h> #include <math.h> #include<omp.h> double f( double ); double f( double a ) { return (4.0 / (1.0 + a*a)); } int main( int argc, char *argv[]) { int n= 1000000000, myid, numprocs; double PI25DT = 3.141592653589793238462643; double pi, h, sum, x; double startwtime = 0.0, endwtime; h = 1.0 / (double) n; sum = 0.0; #pragma omp parallel reduction(+:sum) if (omp_get_thread_num() == 0) {startwtime = omp_get_wtime();} #pragma omp parallel for for (int i = 0; i <= n; i ++) { x = h * ((double)i - 0.5); sum += f(x); } pi = h * sum; if (omp_get_thread_num() == 0) { printf("pi is approximately %20.15e, Error is %e\n", pi, fabs(pi - PI25DT)); endwtime = omp_get_wtime(); printf("wall clock time = %f\n",endwtime-startwtime); } exit(0); } Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 14 / 21 Clauses OPENMP OpenMP étant une bibliothèque à mémoire partagée, la plupart des variables du code sont visibles par tous les threads par défaut. Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 15 / 21 Clauses OPENMP OpenMP étant une bibliothèque à mémoire partagée, la plupart des variables du code sont visibles par tous les threads par défaut. Mais parfois des variables privées sont nécessaires pour éviter les conflits en mémoire et il est nécessaire de passer des valeurs entre la partie séquentielle et dans la région parallèle. La gestion des données se fait à travers des clauses de partage d’attribut de données en les ajoutant à la directive OpenMP Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 15 / 21 Clauses OPENMP (2) Les différents types de clauses sont shared: les données au sein d’une région parallèle sont partagées, ce qui signifie visibles et accessibles par tous les threads simultanément. Par défaut, toutes les variables dans la région de partage du travail sont partagés à l’exception du compteur d’itérations de la boucle. Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 16 / 21 Clauses OPENMP (2) Les différents types de clauses sont shared: les données au sein d’une région parallèle sont partagées, ce qui signifie visibles et accessibles par tous les threads simultanément. Par défaut, toutes les variables dans la région de partage du travail sont partagés à l’exception du compteur d’itérations de la boucle. private: les données au sein d’une région parallèle sont propres à chaque thread, ce qui signifie que chaque thread aura une copie locale et l’utilisera comme une variable temporaire. Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 16 / 21 Clauses OPENMP (2) Les différents types de clauses sont shared: les données au sein d’une région parallèle sont partagées, ce qui signifie visibles et accessibles par tous les threads simultanément. Par défaut, toutes les variables dans la région de partage du travail sont partagés à l’exception du compteur d’itérations de la boucle. private: les données au sein d’une région parallèle sont propres à chaque thread, ce qui signifie que chaque thread aura une copie locale et l’utilisera comme une variable temporaire. 1 Une variable privée n’est pas initialisée et la valeur n’est pas conservée pour une utilisation en dehors de la région parallèle. Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 16 / 21 Clauses OPENMP (2) Les différents types de clauses sont shared: les données au sein d’une région parallèle sont partagées, ce qui signifie visibles et accessibles par tous les threads simultanément. Par défaut, toutes les variables dans la région de partage du travail sont partagés à l’exception du compteur d’itérations de la boucle. private: les données au sein d’une région parallèle sont propres à chaque thread, ce qui signifie que chaque thread aura une copie locale et l’utilisera comme une variable temporaire. 1 Une variable privée n’est pas initialisée et la valeur n’est pas conservée pour une utilisation en dehors de la région parallèle. 2 Par défaut, les compteurs d’itération en boucle dans les constructions en boucle OpenMP sont privées. Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 16 / 21 Clauses OPENMP (2) Les différents types de clauses sont shared: les données au sein d’une région parallèle sont partagées, ce qui signifie visibles et accessibles par tous les threads simultanément. Par défaut, toutes les variables dans la région de partage du travail sont partagés à l’exception du compteur d’itérations de la boucle. private: les données au sein d’une région parallèle sont propres à chaque thread, ce qui signifie que chaque thread aura une copie locale et l’utilisera comme une variable temporaire. 1 Une variable privée n’est pas initialisée et la valeur n’est pas conservée pour une utilisation en dehors de la région parallèle. 2 Par défaut, les compteurs d’itération en boucle dans les constructions en boucle OpenMP sont privées. 3 default Permet au programmeur de préciser que la valeur par défaut des données dans une région parallèle sera soit shared, private, firstprivate ou none. Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 16 / 21 Clauses OPENMP (2) Les différents types de clauses sont shared: les données au sein d’une région parallèle sont partagées, ce qui signifie visibles et accessibles par tous les threads simultanément. Par défaut, toutes les variables dans la région de partage du travail sont partagés à l’exception du compteur d’itérations de la boucle. private: les données au sein d’une région parallèle sont propres à chaque thread, ce qui signifie que chaque thread aura une copie locale et l’utilisera comme une variable temporaire. 1 Une variable privée n’est pas initialisée et la valeur n’est pas conservée pour une utilisation en dehors de la région parallèle. 2 Par défaut, les compteurs d’itération en boucle dans les constructions en boucle OpenMP sont privées. 3 default Permet au programmeur de préciser que la valeur par défaut des données dans une région parallèle sera soit shared, private, firstprivate ou none. 4 none L’option none oblige le programmeur à déclarer chaque variable dans la région parallèle en utilisant les clauses de partage d’attribut de données. Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 16 / 21 Clauses OPENMP (3) Les différents types de clauses sont firstprivate: comme private, sauf initialisé à la valeur d’origine. Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 17 / 21 Clauses OPENMP (3) Les différents types de clauses sont firstprivate: comme private, sauf initialisé à la valeur d’origine. lastprivate: comme private, sauf que la valeur d’origine est mis à jour après l’exécution de la partie parallèle. Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 17 / 21 Clauses OPENMP (3) Les différents types de clauses sont firstprivate: comme private, sauf initialisé à la valeur d’origine. lastprivate: comme private, sauf que la valeur d’origine est mis à jour après l’exécution de la partie parallèle. reduction permet de faire une collecte globale sur l’ensemble en fin d’exécution. Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 17 / 21 Clauses OPEMMP (4) Les différents types de clauses sont firstprivate: comme private, sauf initialisé à la valeur d’origine. Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 18 / 21 Clauses OPEMMP (4) Les différents types de clauses sont firstprivate: comme private, sauf initialisé à la valeur d’origine. lastprivate: comme private, sauf que la valeur d’origine est mis à jour après l’exécution de la partie parallèle. Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 18 / 21 Clauses OPEMMP (4) Les différents types de clauses sont firstprivate: comme private, sauf initialisé à la valeur d’origine. lastprivate: comme private, sauf que la valeur d’origine est mis à jour après l’exécution de la partie parallèle. reduction permet de faire une collecte globale sur l’ensemble en fin d’exécution. Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 18 / 21 Clauses de synchronisation La chirurgie fine de la programmation OPENMP se fait avec les directives de synchronisation critical: le bloc de code sera exécuté par un seul thread à la fois, et non exécuté simultanément par plusieurs threads. Il est souvent utilisé pour protéger les données partagées pour éviter les conflits d’écriture en mémoire. Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 19 / 21 Clauses de synchronisation La chirurgie fine de la programmation OPENMP se fait avec les directives de synchronisation critical: le bloc de code sera exécuté par un seul thread à la fois, et non exécuté simultanément par plusieurs threads. Il est souvent utilisé pour protéger les données partagées pour éviter les conflits d’écriture en mémoire. atomic: la mise à jour en mémoire (écriture ou en lecture-modification-écriture) dans la prochaine instruction sera exécutée de façon atomique. Il ne fait pas tout l’énoncé atomique, seule la mise à jour de mémoire est atomique. Un compilateur peut utiliser les instructions matérielles spécifiques pour une meilleure performance que lors de l’utilisation critique. Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 19 / 21 Clauses de synchronisation La chirurgie fine de la programmation OPENMP se fait avec les directives de synchronisation critical: le bloc de code sera exécuté par un seul thread à la fois, et non exécuté simultanément par plusieurs threads. Il est souvent utilisé pour protéger les données partagées pour éviter les conflits d’écriture en mémoire. atomic: la mise à jour en mémoire (écriture ou en lecture-modification-écriture) dans la prochaine instruction sera exécutée de façon atomique. Il ne fait pas tout l’énoncé atomique, seule la mise à jour de mémoire est atomique. Un compilateur peut utiliser les instructions matérielles spécifiques pour une meilleure performance que lors de l’utilisation critique. ordered: le bloc structuré est exécuté dans l’ordre dans lequel les itérations sera exécuté en boucle séquentielle Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 19 / 21 Clauses de synchronisation La chirurgie fine de la programmation OPENMP se fait avec les directives de synchronisation critical: le bloc de code sera exécuté par un seul thread à la fois, et non exécuté simultanément par plusieurs threads. Il est souvent utilisé pour protéger les données partagées pour éviter les conflits d’écriture en mémoire. atomic: la mise à jour en mémoire (écriture ou en lecture-modification-écriture) dans la prochaine instruction sera exécutée de façon atomique. Il ne fait pas tout l’énoncé atomique, seule la mise à jour de mémoire est atomique. Un compilateur peut utiliser les instructions matérielles spécifiques pour une meilleure performance que lors de l’utilisation critique. ordered: le bloc structuré est exécuté dans l’ordre dans lequel les itérations sera exécuté en boucle séquentielle barrier Chaque thread attend jusqu’à ce que tous les autres threads de l’équipe aient atteint ce point. Une construction de travail partagé a une synchronisation par barrière par défault à la fin. Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 19 / 21 Un exemple de clause de synchronisation #include <stdio.h> #include <math.h> #include<stdlib.h> #include <omp.h> #define NITER 20000000 double essai(double x) { double c=10.0; return(5.0+c*x+x*x*exp(x)*log(x+0.1)+sqrt(abs(x))); } int main(){ double *a; a=(double *) malloc(sizeof(double)* NITER); int b=0; #pragma omp parallel default(shared) { #pragma omp parallel for for (int j=0;j<NITER;j++){ { a[j] = essai(j/10.0);} if((j%1000) ==0){ #pragma omp atomic b++; } } } printf(" valeur de b %d\n",b); exit(0); } Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 20 / 21 Conclusion et références La bibliothèque OPENMP a été développée pour plusieurs langages Fortran, C, C++ et s’impose aujourd’hui pour utiliser les unités de calcul d’un processeur de manière efficace. Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 21 / 21 Conclusion et références La bibliothèque OPENMP a été développée pour plusieurs langages Fortran, C, C++ et s’impose aujourd’hui pour utiliser les unités de calcul d’un processeur de manière efficace. Développer un programme OPENMP est une tâche plus aisée que celle avec la bibliothèque MPI, mais le nombre de coeurs physiques que l’on peut solliciter reste souvent inférieur à la dizaine, ce qui n’est pas négligeable mais est très inférieur avec la bibliothèque MPI. Pascal Viot Introduction au calcul parallèle: OPENMP September 3, 2016 21 / 21