ISET Sousse Module : Atelier Programmation Parallèle
---------------------------------------------------------------------------------------------------------------------
TP2 : Programmation avec OpenMP
L'objectif de ce TP est de découvrir [OpenMP]([Link] en expérimentant les
différentes directives depuis les plus bas niveaux jusqu'aux constructions les plus sophistiquées
autour des boucles.
Pour compiler un code [Link] avec OpenMP et générer l’executable programme, saisir
g++ -std=c++11 -fopenmp [Link] -o programme
Manipulation 1 : Découverte de directives
1. Hello parallel world!
Pour cette première partie, il suffit de disposer d'un compilateur C++ avec support pour OpenMP,
d'un terminal ouvert et d'un éditeur de fichiers. Commençons par créer un fichier Makefile pour
préciser quel compilateur utiliser et quels arguments lui passer à la compilation.
CXX=g++
CXXFLAGS=-std=c++11 -Wall -Wextra -pedantic -fopenmp
Et voici notre premier programme OpenMP [Link]
Si tout se passe bien, la commande make hello devrait compiler ce programme et au lancement
on obtient un comportement très séquentiel.
$ ./hello
Bonjour
Nous sommes 1 threads dans cette équipe
Au revoir
Q1. Relancez la commande en plaçant `TRUE` dans la variable d'environnement
`OMP_DISPLAY_ENV` et interpréter le résultat.
ISET Sousse Module : Atelier Programmation Parallèle
---------------------------------------------------------------------------------------------------------------------
1.1. pragma omp parallel
La directive #pragma omp parallel indique que l'instruction (ou le bloc d'instructions) qui
suit doit être exécuté par une équipe de threads (souvenez-vous qu'openMP repose sur le
paradigme de programmation parallèle fork-join).
Q2. Ajoutez la directive `#pragma omp parallel` juste avant la ligne qui affiche `Bonjour` puis
recompilez et exécutez le programme `hello`. Quelle sortie obtenez-vous ? Pourquoi autant de
fois `Bonjour` et si peu de fois `Au revoir` ?
Modifiez le programme pour que ce soit tout le bloc d'affichage `Bonjour` + `Au revoir` qui soit
parallélisé. Quel affichage obtenez-vous ? Reste-t-il identique si vous relancez le programme ?
La fonction de bibliothèque omp_get_num_threads permet de connaître le nombre total
de threads dans l'équipe et la fonction omp_get_thread_num indique le numéro du thread
courant.
La variable d'environnement OMP_NUM_THREADS permet de spécifier le nombre de
threads souhaités. Il est aussi possible d'utiliser la fonction de la bibliothèque
omp_set_num_threads mais l'utilisation d'une variable d'environnement permet de changer
la valeur plus facilement sans recompiler le programme.
Les variables déclarées à l'intérieur d'un bloc parallèle sont par défaut privées : chaque
thread dispose de sa propre variable. Les variables déclarées à l'extérieur d'un bloc parallèle
et celles allouées sur le tas sont partagées par tous les threads de l'équipe.
1.2. pragma omp critical, single, barrier
La directive #pragma omp critical définit une section critique, une portion de code qui ne
peut être accédée par les threads qu'un seul à la fois.
Q3. Modifiez votre programme pour que les affichages ne s'entremêlent pas : associer une section
critique à chaque ligne d'affichage.
La directive #pragma omp barrier définit une barrière de synchronisation, un rendez-vous
que tous les threads doivent avoir rejoint avant d'être autorisés à poursuivre leur exécution.
Q4. Modifiez votre programme pour que personne ne dise `au revoir` avant que tout le monde n'ait
terminé de dire `bonjour` !
La directive #pragma omp single définit une section de code qui sera exécutée par un
unique thread.
Q5. Modifiez votre programme pour qu'un seul thread annonce le nombre de threads de l'équipe
une fois que tout le monde a dit `bonjour` et qu'un second thread (pas nécessairement le même)
annonce la fin du TP ensuite, avant que tout le monde dise `au revoir`.
ISET Sousse Module : Atelier Programmation Parallèle
---------------------------------------------------------------------------------------------------------------------
1.3. On récapitule et on mesure le temps de calcul !
Voici un programme [Link] que nous allons paralléliser. Il utilise la fonction de
bibliothèque omp_get_wtime pour mesurer le temps réel écoulé entre deux points du programme.
Q6. Compilez et exécutez le programme. Vérifiez que la variable `pass` doit être égale à `TOTAL`
en fin de programme. Si besoin, modifier la valeur de `TOTAL` pour avoir un temps d'exécution
de l'ordre de `1000ms`.
2. For, Collapse, Schedule et reduction
Q7. Comprenez et distinguez ces directives OpenMP.
Manipulation 2 : Fonctionnement parallèle
Pour les fichiers fournis avec ce TP (présents dans le classroom : 2cu5hm6
Q8. Identifiez l’objectif du chaque programme.
Q9. Examinez la structure du chaque programme et discutez.