Présentation de l'API OpenMP
OpenMP est une API de programmation parallèle pour les langages C, C++ et Fortran. Elle permet de définir des régions de code pouvant être exécutées en parallèle. Elle a été définie en octobre 1997 pour Fortran et en octobre 1998 pour C et C++.
Principes
OpenMP est une API basée sur les threads, lorsque que le programme arrive dans une région marquée comme parallèle, il crée une équipe de threads qui exécutent la région en parallèle. Les threads sont créés à partir du thread principal, qui est appelé thread principal. Les threads sont synchronisés à la fin de la région parallèle, et le thread parallèle reprend l'exécution du programme de manière séquentielle.
Directives
OpenMP utilise un ensemble de directives de préprocesseur pour définir les régions parallèles. Ces directives sont des mots-clés qui commencent par #pragma omp
. Les directives sont suivies d'un ensemble d'arguments qui définissent le comportement de la région parallèle. Les directives sont définies dans le fichier omp.h
qui est inclus dans les fichiers C et C++ et dans le fichier omp_lib.h
qui est inclus dans les fichiers Fortran.
Principales directives
création de régions parallèles
Parallel
Crée une équipe de threads qui exécutent la région parallèle. Le nombre de threads lancés est défini soit :
- l'évaluation d'une éventuelle clause if
- de la clause num_threads si elle est présente
- de la fonction omp_set_num_threads si elle est appelée avant la directive
- et enfin de la variable d'environnement OMP_NUM_THREADS si elle est définie
for
Une des premières directives que l'on montre lorsque que l'on parle de OpenMP, en effet, elle permet de paralléliser un calcul en n'ajoutant qu'une seule ligne à un programme déjà existant. La directive for
permet de paralléliser une boucle for en créant un ensemble de threads qui exécutent la boucle en parallèle. La directive for
est définie de la façon suivante :
#pragma omp for
for (int i = 0; i < 100000; i++) {
// Code de la boucle
}
Directive sur le statut des variables
OpenMP fonctionne sur les machines à mémoire partagée, les variables seront donc partagées entre les threads, on a donc besoin de mécanismes de contrôle permettant d'indiquer quels threads peuvent modifier ou lire une variable.
Private
La directive private
permet de définir une liste de variables comme privées, chaque thread aura une copie des variables qui ne sera pas partagée avec les autres.
Shared
Permets de définir une liste de variables comme partagées, les threads d'une même équipe auront accès à la variable.
Firstprivate
La directive firstprivate
permet de définir une liste de variables comme privées, mais initialise la variable avec la valeur de la variable du thread principal.
Lastprivate
La directive lastprivate
permet de définir une liste de variables comme privées, mais initialise la variable avec la valeur de la variable du dernier thread.
Réduction
La directive reduction
permet de définir une liste de variables comme privées, mais initialise la variable avec la valeur de la variable du dernier thread.
Default
Indique le comportement par défaut des variables d'une région parallèle, si aucunes autres directives sur le statut des variables n'est présente, les variables utilisent le comportement par défaut.
Directives de synchronisation
Barrier
La directive barrier
permet de synchroniser les threads, quand un thread atteint la directive, il attend les autres threads. Une fois tous les threads arrivés à la directive, les threads peuvent continuer à s'exécuter.
Critical
Cette directive indique que le bloc suivant doit être exécuté par un seul thread à la fois. Si un thread arrive dans la région marquée comme critique alors qu'un thread est déjà à l'intérieur, il attend que l'autre thread sorte de la région critique avant d'y entrer.
Atomic
La directive atomic
permet d'exécuter une opération atomique. Une opération atomique est une opération qui ne peut pas être interrompue par un autre thread.
Master
Seul le thread principal peut exécuter le bloc marqué comme master
.
Flush
flush
force les threads à mettre à jour les variables partagées passées en argument de la directive.
Exemples :
#include<stdio.h>
#include<stdlib.h>
int main (int argc, char const *argv[]){
int n;
for(n=0;n<8;n++){
printf("Element %d traité\n",n);
}
return EXIT_SUCCESS;
}
Résultat:
Element 0 traité
Element 1 traité
Element 2 traité
…
Mais en utilisant OpenMp
#include<stdio.h>
#include<stdlib.h>
#include<omp.h>
int main (int argc, char const *argv[]){
int n;
#pragma omp parallel for
for(n=0;n<8;n++){
printf("Element %d traité par le thread %d \n",n,omp_get_thread_num());
}
return EXIT_SUCCESS;
}
Résultat :
Element 0 traité par le thread 0
Element 4 traité par le thread 1
Element 1 traité par le thread 0
Element 5 traité par le thread 1
Element 2 traité par le thread 0
Element 6 traité par le thread 1
Element 3 traité par le thread 0
Element 7 traité par le thread 1
Avantages et inconvénients
Avantages
- OpenMP est un standard ancien et reconnu, il y a beaucoup de documentation disponible.
- OpenMP offre de bonnes performances si le programmeur sait l'utiliser correctement.
- Pour paralléliser un programme, l'effort de programmation est relativement faible, le programme original n'est pas beaucoup modifié.
- le code produit est portable, de nombreux compilateurs supportent OpenMP.
Inconvénients
- C'est au programmeur de trouver où il peut être intéressant de paralléliser son programme, et de trouver les bonnes directives pour le faire.
- Pour obtenir les meilleures performances, le programmeur doit avoir bien réfléchi à la parallélisation de son programme et bien connaître les directives OpenMP.
Conclusion
Nous pouvons donc conclure que la mise en œuvre d'OpenMP pour optimiser l'utilisation des processeurs à cœurs multiples est simple.
Par contre, l'absence d'un déboguer efficace pour OpenMP complique un peu l'écriture des programmes.
Cependant, c’est un code parallèle plus efficace et de niveau inférieur. Mais également, OpenMP cache les détails de bas niveau et permet au programmeur de décrire le code parallèle avec des constructions de haut niveau, ce qui est aussi simple qu’il peut obtenir. OpenMP a des directives qui permettent au programmeur de spécifier la région parallèle.
Congratulations @fatieez! You have completed the following achievement on the Hive blockchain And have been rewarded with New badge(s)
Your next target is to reach 400 upvotes.
You can view your badges on your board and compare yourself to others in the Ranking
If you no longer want to receive notifications, reply to this comment with the word
STOP
Check out the last post from @hivebuzz:
Support the HiveBuzz project. Vote for our proposal!
Bonjour !
En tant que membre francophone de Hive, vous avez été ajouté à l'auto-vote.
La puissance de vote de base est de 25%, deux votes par tranche de 24h et 7 max par semaine.
Vous pouvez augmenter la puissance de vote en déléguant à la Ruche si vous le souhaitez. Voici notre serveur Discord si vous avez des questions ou juste pour discuter avec d'autres francophones de Hive !
https://discord.gg/46gdrud
Bienvenue dans la Ruche !