Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

algorithme parallele

Télécharger au format pdf ou txt
Télécharger au format pdf ou txt
Vous êtes sur la page 1sur 40

Complexité et algorithme avance

REPUBLIQUE DU CAMEROUN REPUBLIC OF CAMEROON

******** ********

PAIX-TRAVAL-PATRIE PEACE-WORKFATHERLAND
********
********
UNIVERSITY OF DSCHANG
UNIVERSITE DE DSCHANG
********
********
FACULTY OF SCIENCES
FACULTES DES SCIENCES
********
********
DEPARTMENT OF MATHS-INFOS
DEPARTEMENT DE MATHS-INFO
Informatique4 Option RSD
INF417
COMPLEXITE ET ALGORITHME AVANCE

Chapitre7

INTRODUCTION A LA PARALLELISATION D’ALGORITHME

Travail Réalisé par:


NOM&PRENOM MATRICULE OPTION
SOULEYMAN BECHIR NAHAR CM-UDS-21SCI 1537 RSD
PEUHTAO GNEBE TCHINCHACKE CM-UDS-21SCI RSD

Superviseur : Professeur KENGNE T.Vianney

Année Académique 1

2024-2025
Complexité et algorithme avance

Table des matières


Introduction Générale ..................................................................................................................... 2
A-HISTORIQUE ET EVOLUTION DE L’ALGORITHEME PARALLELE ........................... 3
B-DOMMAINE D’APPLICATION ........................................................................................... 4
C- Ce quoi le parallélisme ? ........................................................................................................ 5
LES DIFFERENTS TYPES DE PARALLELISME: ..................................................................... 6
Algorithme parallèle ........................................................................................................................ 7
Les Machines Parallèles .................................................................................................................. 7
1.Les machines parallèles à mémoire partagée ............................................................................ 9
2- Les machines parallèles à mémoire distribuée........................................................................ 9
Le modele PRAM ......................................................................................................................... 10
Mesure de performance ................................................................................................................. 12
Accélération .............................................................................................................................. 12
Accélération relative .................................................................................................................. 12
Efficacité ................................................................................................................................... 13
Iso-efficacité .............................................................................................................................. 13
III- TCHNIQUES DE PARALLELISATION .............................................................................. 13
Decomposition des Problemes .................................................................................................. 13
Analyse de dependance entre tache ........................................................................................... 14
B. Synchronisation et communication ...................................................................................... 16
Définition : ................................................................................................................................ 16
Types de synchronisation : ........................................................................................................ 16
Protocoles de communication (MPI, OpenMP) ........................................................................ 17
IV. Outils et Environnements de Développement ........................................................................ 18
C Environnements de développement de algorithme paralleles ............................................... 20
C. Exemples d’implémentation d’algorithmes parallèles ............................................................. 22
COMPLEXITE: ............................................................................................................................ 23
IMPORTANCES ET DEFIS DE L’ALGORITHME PARALLELE ........................................... 24
Importance des Algorithmes Parallèles ..................................................................................... 24
Défis des Algorithmes Parallèles .............................................................................................. 24
Principaux modèles de programmation parallèle :........................................................................ 25
Architectures à mémoire partagée ............................................................................................. 25
Architectures à mémoire distribuée........................................................................................... 25
2
Complexité et algorithme avance

UTILISATION DE openMP......................................................................................................... 26
● Description : ........................................................................................................................... 26
Structure d’OpenMP : architecture logicielle ............................................................................... 26
Modèle d’exécution OpenMP ....................................................................................................... 27
Directives et les clauses OpenM ................................................................................................... 27
Definition de directive ............................................................................................................... 27
Definition de clause ................................................................................................................... 27
Structure d’une directive OpenMP ............................................................................................ 27
Structure generale de clause ...................................................................................................... 27
Principales directives OpenMP ..................................................................................................... 28
a.Construction de régions parallèles.......................................................................................... 28
Les clauses................................................................................................................................. 28
b.Partage du travail .................................................................................................................... 29
c.Synchronisation ...................................................................................................................... 31
d. Gestion de tâches ................................................................................................................... 32
INSTALLATION ET CONFIGURATION DE openMP ............................................................. 33
Avantages et défis de openMP ...................................................................................................... 35
Avantages d’OpenMP ............................................................................................................... 35
Défis et limites d’OpenMP ........................................................................................................ 36
CONCLUSION ............................................................................................................................. 38

3
Complexité et algorithme avance

Introduction Générale
La parallélisation d’algorithmes est devenue un sujet central dans le domaine de l’informatique et
des sciences des données, en raison de l’explosion des volumes de données et de la complexité
croissante des calculs nécessaires pour les traiter. Avec l’avènement des architectures multi-cœurs
et des systèmes distribués, il est désormais possible d’exécuter plusieurs tâches simultanément,
offrant ainsi des gains de performance significatifs par rapport aux approches séquentielles
traditionnelles. Dans ce contexte, les chercheurs et les ingénieurs se tournent vers la parallélisation
comme une solution pour optimiser les temps de calcul et améliorer l’efficacité des algorithmes.
Cependant, la parallélisation d’algorithmes pose plusieurs défis techniques et théoriques. La
décomposition d’un problème en sous-tâches indépendantes n’est pas toujours triviale, et la
gestion de la communication entre ces sous-tâches peut engendrer des surcoûts qui annulent les
bénéfices attendus. De plus, la synchronisation entre les processus parallèles peut devenir un
goulot d’étranglement, affectant la performance globale du système. Ainsi, il est crucial de
comprendre comment concevoir des algorithmes qui tirent pleinement parti des architectures
parallèles tout en minimisant les problèmes liés à la concurrence et à la coordination.
L’objectif de ce chapitre est d’explorer les différentes méthodes de parallélisation d’algorithmes,
en mettant en lumière les techniques existantes et les meilleures pratiques pour leur mise en œuvre.
Nous examinerons les principes fondamentaux de la parallélisation, ainsi que des études de cas
illustrant l’application de ces concepts dans divers domaines, tels que le traitement d’images,
l’apprentissage automatique et la simulation numérique. En fin de compte, ce chapitre vise à
fournir une compréhension approfondie des enjeux et des opportunités offerts par la
parallélisation, tout en proposant des pistes pour améliorer l’efficacité des algorithmes dans un
monde de plus en plus axé sur le calcul parallèle.

2
Complexité et algorithme avance

A-HISTORIQUE ET EVOLUTION DE L’ALGORITHEME PARALLELE

L’histoire des algorithmes parallèles est riche et complexe, s’étendant sur plusieurs décennies.
Voici un aperçu des principales étapes et développements dans ce domaine :
Années 1950-1960 : Les débuts
• Concepts de base : Les premiers travaux sur le calcul parallèle ont émergé avec l’essor des
ordinateurs. Les idées sur la décomposition des tâches et le traitement simultané ont commencé à
apparaître.
• Architecture : Les architectures de machines parallèles comme les ordinateurs à instructions
multiples et données multiples (MIMD) et les ordinateurs à instructions uniques et données
multiples (SIMD) ont été conceptualisées.

▎Années 1970 : Formalisation et recherche


• Théorie des graphes : Les chercheurs ont commencé à formaliser les algorithmes parallèles en
utilisant la théorie des graphes pour représenter les relations entre les tâches.
• Algorithmes de tri et de recherche : Des algorithmes parallèles pour le tri (comme le tri par fusion
parallèle) et la recherche (comme la recherche binaire parallèle) ont été développés.
Années 1980 : Progrès significatifs
• Modèles de calcul : Des modèles tels que le modèle PRAM (Parallel Random Access Machine)
ont été introduits pour analyser la complexité des algorithmes parallèles.
• Langages de programmation : L’émergence de langages comme *Occam* et *Cilk* a facilité
l’écriture d’algorithmes parallèles.

▎Années 1990 : Évolution des architectures


• Clusters et Grilles : Le développement des clusters de calcul et des grilles informatiques a permis
d’exécuter des algorithmes parallèles sur des systèmes distribués.
• Algorithmes avancés : Des algorithmes parallèles pour des problèmes complexes, comme la
factorisation de grands nombres ou les simulations physiques, ont été conçus.
Années 2000 : Montée en puissance
• Multi-core et GPU : L’avènement des processeurs multi-cœurs et des unités de traitement
graphique (GPU) a révolutionné le calcul parallèle, permettant une exploitation massive du
parallélisme.
• Bibliothèques et frameworks : Des bibliothèques comme OpenMP, MPI, et CUDA ont été créées
pour simplifier le développement d’applications parallèles.
Années 2010 à aujourd’hui : Maturité et applications
• Intelligence Artificielle : Les algorithmes parallèles sont devenus cruciaux dans le domaine de
l’intelligence artificielle, notamment pour l’entraînement de modèles de deep learning.
3
Complexité et algorithme avance

• Big Data : Le traitement parallèle est essentiel pour gérer les grandes quantités de données, avec
des frameworks comme Apache Hadoop et Spark.
• Recherche continue : La recherche sur les algorithmes parallèles continue d’évoluer, se
concentrant sur l’efficacité énergétique, la tolérance aux pannes et l’optimisation des
performances.
B-DOMMAINE D’APPLICATION
Les algorithmes parallèles trouvent des applications dans de nombreux domaines variés, tirant
parti de leur capacité à traiter simultanément plusieurs tâches pour améliorer l’efficacité et réduire
le temps de calcul. Voici quelques-uns des principaux domaines d’application :
1. Calcul scientifique et simulations
• Météorologie : Prévisions météorologiques nécessitant des simulations complexes de modèles
climatiques.
• Dynamique des fluides : Simulation de l’écoulement des fluides pour des applications en
ingénierie et en physique.
• Modélisation moléculaire : Études de la dynamique moléculaire pour comprendre les
interactions entre atomes et molécules.
2. Intelligence artificielle et apprentissage automatique
• Entraînement de modèles : L’entraînement de réseaux de neurones profonds (deep learning)
utilise des algorithmes parallèles pour traiter de grandes quantités de données.
• Traitement du langage naturel : Applications comme la traduction automatique et l’analyse de
sentiments nécessitent un traitement parallèle pour traiter rapidement de grandes quantités de texte.
3. Analyse de données et Big Data
• Traitement de données massives : Utilisation d’outils comme Apache Hadoop et Apache Spark
pour le traitement parallèle de grandes bases de données.
• Analyse statistique : Algorithmes parallèles pour effectuer des analyses statistiques sur des
ensembles de données volumineux.
4. Graphes et réseaux
• Recherche sur les graphes : Algorithmes parallèles pour le parcours de graphes, le calcul de
chemins les plus courts ou la détection de communautés dans les réseaux sociaux.
• Optimisation de réseaux : Résolution de problèmes d’optimisation dans les réseaux, comme le
routage ou la planification.
5. Vision par ordinateur
• Traitement d’images : Algorithmes parallèles pour le traitement d’images en temps réel,
comme la détection d’objets ou la segmentation d’image.
• Reconnaissance faciale : Utilisation d’algorithmes parallèles pour améliorer la vitesse et
l’efficacité des systèmes de reconnaissance faciale.
4
Complexité et algorithme avance

6. Cryptographie et sécurité
• Facteurs de grands nombres : Algorithmes parallèles pour la factorisation de grands nombres,
utilisée dans la cryptographie.

• Analyse de sécurité : Traitement parallèle pour analyser les menaces et détecter les intrusions
dans les systèmes informatiques.
7. Ingénierie et conception assistée par ordinateur (CAO)
• Simulation et optimisation : Utilisation d’algorithmes parallèles pour optimiser la conception
et simuler le comportement des structures.
• Analyse par éléments finis : Calculs complexes pour simuler les réponses physiques des
matériaux sous diverses conditions.
8. Bioinformatique
• Analyse génomique : Traitement parallèle pour l’analyse des séquences ADN et la recherche
sur les gènes.
• Modélisation des protéines : Simulation des interactions entre protéines et autres biomolécules.
9. Finance
• Modélisation financière : Utilisation d’algorithmes parallèles pour simuler des scénarios
économiques ou évaluer des options financières.
• Analyse des risques : Traitement parallèle pour évaluer rapidement les risques associés à divers
investissements.
10. Jeux vidéo
• Rendu graphique : Utilisation du parallélisme pour le rendu en temps réel dans les jeux vidéo,
permettant des graphismes plus riches et plus détaillés.
• IA des personnages non-joueurs (PNJ) : Traitement parallèle pour gérer les comportements
complexes des PNJ dans un environnement de jeu.
C- Ce quoi le parallélisme ?

L’avancé technologique, dans tous les domaines de la vie moderne, demande de plus en plus de
puissance de calculs. La course à la vitesse des processeurs a atteint ses limites en terme de
réchauffement des circuits et de fréquences alors les constructeurs se sont tournés vers la
parallélisation des traitements et la création de processeurs multicœurs qu’on peut facilement
assimiler à des machines parallèles (Figure 11). La parallélisation des traitements est alors une
tendance qui se démocratise à tous les utilisateurs par contre aux temps où il fallait des
supercalculateurs pour pouvoir exécuter des programmes parallèles.

5
Complexité et algorithme avance

Figure 11: Architecture interne Processeur Intel I7

LES DIFFERENTS TYPES DE PARALLELISME:


Il existe deux types de parallelisme:
1-Le parallelisme de données
Il consiste a utilise ou a executé la meme operation sur des processeurs differents et sur des données
differentes
2-Le parallelisme d’instructions
c’est l’execution des plusieurs operations differentes sur des processeures differents
Les defis de dependance
Il est important de comprendre qu’il y a des defis a prendre en compte
Defi 1: dependances des données
D’apres le code precedent ci-dessous, la premiere instruction met à jour la variable x dont la valeur
est modifiée dans l’instrucion qui se trouve juste apres :
X = y+1 ou X = y+1 ou X = y+1
Z = x+1 Y = z+2 X = z+1
Defis2: Dependance de controle
1.a = b+c
2.if(a<0)
3. {d=e+f ;}
4.g = d+h ;
Defis3 Dépendance de Ressources
C’est la situation où le nombre de processeur est insuffisants pour effectuer des taches parallèles

6
Complexité et algorithme avance

Defis4 Temps de communication


La communication entre processeurs dans un système parallèle peut augmenter des taches
parallèles

Algorithme parallèle
Un algorithme parallèle est conçu pour s’exécuter sur une machine parallèle pour résoudre un
problème en améliorant le temps de calcul tout en respectant les contraintes de complexité en
temps calcul et mémoire.
La conception d’un algorithme parallèle pour un problème donné est beaucoup plus complexe que
la conception d’un algorithme séquentiel du même problème car elle demande la prise en compte
de plusieurs facteurs tels que : la partie du programme qui peut être traitée en parallèle, la manière
de distribuer les données, les dépendances des données, la répartition de charges entre les
processeurs, les synchronisations entre les processeurs. Il y a essentiellement deux méthodes pour
concevoir un algorithme parallèle, l’une consiste à détecter et à exploiter le parallélisme à
l’intérieur d’un algorithme séquentiel déjà existant, l’autre consistant à inventer un nouvel
algorithme dédié.

Les Machines Parallèles


Les machines parallèles sont construites autour d’un ensemble de nœuds interconnectés, chacun
est constitué d’un ou plusieurs processeurs identiques, ou non, qui collaborent pour l’exécution
d’une application. Les machines paralleles peuvent etre classées en se basant sur:
1.Flux d’instuctions: sequences d’instructions executees par la machines ;
2.Flux de données: sequence de données appelées par le flux d’instruction.
.SISD pour Single Instruction, Singel Data(un seule instruction une seul donnes) : c’est le modèle
classique de Von Neumann où un seul processeur exécute une seule instruction sur une seule
donnée (un seul flot de données) à la fois résidant dans une seule mémoire.

7
Complexité et algorithme avance

.SIMD pour Single Instruction, Multiple Data : le contrôle est centralisé sur un seul processeur,
les autres processeurs sont synchronisés entre chaque instruction du même algorithme qu’ils
exécutent ;

MISD pour Multiple Instruction, Single Data : une même donnée est traitée
simultanément par plusieurs processeurs.

MIMD pour Multiple Instruction, Multiple Data : le contrôle est réparti sur tous les processeurs
et la synchronisation, lorsqu’elle est nécessaire, est réalisée par communication. Chaque
processeur peut exécuter un algorithme différent ;

NB: le modele MIMD est le plus utilisé.

8
Complexité et algorithme avance

On distingue deux types d’architecture MIMD:


1.Les machines parallèles à mémoire partagée
Ces machines sont caractérisées par une horloge indépendante pour chaque processeur, mais une
seule mémoire partagée entre ces processeurs, où tous les processeurs lisent et écrivent dans le
même espace d’adressage mémoire, ce qui permet de réaliser un parallélisme de données et de
contrôles (Figure 12). Le programmeur n’a pas besoin de spécifier l’emplacement des données, il
définit seulement la partie du programme que doit exécuter chaque processeur en plus de la gestion
de la synchronisation.
Ce type d’architecture possède plusieurs avantages dont la simplicité, la scalabilité et la
parallélisation de haut niveau. Son inconvénient majeur est lié principalement à la limite de la
bande passante du réseau d’interconnexion

P1 P2 P3 Pn

Réseau d’interconnexion

Mémoire partagée

Figure 12 : Machine parallèle à mémoire partagée.


2- Les machines parallèles à mémoire distribuée
Dans ce type de machine, chaque processeur possède sa propre mémoire locale, où il exécute des
instructions identiques ou non aux autres processeurs. Les différents nœuds définis par l’ensemble
mémoires+processeurs sont reliés entre eux par un réseau d’interconnexion (Figure 13). Le
parallélisme est implémenté par échange de messages.
L’avantage principal des machines parallèles à mémoire distribuée est l’augmentation facile du
nombre de processeurs avec des moyens simples, tels que les clusters. Seulement elles présentent
plus de difficulté dans la programmation.

P1 P2 P3 Pn

M1 M2 M3 Mn

Réseau d’interconnexion 9
Complexité et algorithme avance

Figure 13 : Machine parallèle à mémoire distribuée.

Le modele PRAM
Le PRAM (Parallel Random Access Machine) est un modèle théorique utilisé en informatique
pour étudier les algorithmes parallèles. Il sert à simuler et analyser comment plusieurs processeurs
peuvent résoudre un problème simultanément et efficacement.
Caractéristiques du modèle PRAM :
1. Processeurs multiples :
Le modèle suppose qu’il existe un grand nombre de processeurs identiques disponibles pour
exécuter des instructions en parallèle.
2. Mémoire partagée :
Tous les processeurs ont accès à une mémoire unique et partagée, où ils peuvent lire ou écrire des
données.
3. Temps synchrone :
Les processeurs exécutent leurs instructions en parallèle et de manière synchrone. Chaque
instruction prend exactement un cycle.
4. Accès à la mémoire :
Les processeurs peuvent accéder à n’importe quelle position de la mémoire en un temps constant
(c’est une hypothèse idéale).
Modèles d’accès à la mémoire dans PRAM :
Selon la gestion des conflits d’accès simultané à une même case mémoire, plusieurs variantes du
modèle PRAM existent :
1. EREW (Exclusive Read, Exclusive Write) :
Lecture exclusive : Une seule lecture peut être effectuée sur une case mémoire à un moment donné.
Écriture exclusive : Une seule écriture peut être effectuée sur une case mémoire à un moment
donné.
Modèle le plus restrictif.
2. CREW (Concurrent Read, Exclusive Write) :
Lecture concurrente : Plusieurs processeurs peuvent lire une même case mémoire en même temps.
Écriture exclusive : Une seule écriture est permise à un moment donné.
3. CRCW (Concurrent Read, Concurrent Write) :
Lecture concurrente : Plusieurs processeurs peuvent lire une même case mémoire en parallèle.
Écriture concurrente : Plusieurs processeurs peuvent écrire sur une même case mémoire en
parallèle.
10
Complexité et algorithme avance

Il existe plusieurs règles pour gérer les conflits d’écriture :

Arbitrary CRCW : Un processeur est choisi au hasard pour effectuer l’écriture.


Common CRCW : Tous les processeurs doivent écrire la même valeur.
Priority CRCW : Le processeur avec la plus haute priorité effectue l’écriture.
Avantages et limites du PRAM :
Avantages :
1. Simplicité pour analyser les algorithmes parallèles.
2. Permet de comprendre les limites théoriques de la parallélisation.
3. Base pour développer des algorithmes efficaces sur des systèmes réels.
Limites :
1. Hypothèse irréaliste : accès simultané en temps constant à la mémoire.
2. Néglige les coûts de communication entre les processeurs et la mémoire.
3. Pas directement applicable aux architectures matérielles modernes, mais inspirant pour leur
conception.
Applications du PRAM :
1. Analyse de problèmes complexes (tri parallèle, recherche, graphes).
2. Optimisation d’algorithmes pour architectures parallèles réelles (comme GPU ou clusters).
3. Modélisation de réseaux massivement parallèles.
Différents types de réseaux d’interconnexion ont été mis en place pour relier les différents nœuds
des machines parallèles. On peut citer principalement : l’anneau, Grille torique, Fat Tree,
hypercube et d’autres architectures hybrides (Figure 14).

P0 P1 P2 P3

P4 P5 P6 P7

P8 P9 P10 P11

P12 P1 P14 P15

11
Complexité et algorithme avance

P0
P7 P1

P2
P6

P5 P3 Figure 14: Différentes architectures de réseau


P4
d’interconnexion.

Mesure de performance

Le but essentiel de la parallélisation est de gagner en performance de calcul, des facteurs


on été mis aux points pour mesurer ces performances [38].
Accélération

On peut définir le temps d’exécution d’une application parallèle comme étant le temps
d’exécution du processeur qui termine en dernier. On appelle accélération d’un
algorithme parallèle A, le rapport entre le temps tseq de l’algorithme séquentiel optimal
par le temps tpar(np) de l’algorithme parallèle fonction du nombre de processeurs.

Acc(A) = tseq / tpar(np)

L’accélération est maximale lorsqu’elle est égale au nombre de processeurs, c’est à dire
lorsque le travail réalisé par l’algorithme séquentiel optimal a été parfaitement réparti sur
les processeurs et que cette répartition n’a pas induit de coût supplémentaire.

Cependant, nous pouvons remarquer que l’expression de l’accélération est dépendante


du nombre de processeurs, c’est pourquoi il est nécessaire de définir une notion
d’efficacité où de taux d’activité.
Accélération relative

En pratique, pour avoir une réelle mesure de l’accélération, on doit introduire le temps
additionnel nécessaire à la conception et implémentation de l’algorithme parallèle.

Acc(A)R = tseq / ( tpar(np) + implémentation sur p processeurs))

12
Complexité et algorithme avance

Efficacité

En utilisant les notations introduites précédemment, on définit l’efficacité d’un


algorithme parallèle A comme étant le rapport

e(A)= tseq / (tpar(np) * np )

L’efficacité est proche de 1 quand l’accélération est maximale. Si un programme obtient


une efficacité de 0,6, cela signifie qu’il n’a réellement exécuté l’algorithme que pendant
60% du temps de l’exécution. Le reste du temps est réparti en communications,
synchronisations, équilibre de charge.
Iso-efficacité

L’iso-efficacité d’un algorithme parallèle est définie par la quantité de travail


supplémentaire nécessaire pour garantir l’efficacité parallèle quand le nombre de
processeurs augmente. Dans certains cas il est possible de définir un algorithme parallèle
efficace pour un certain nombre de processeurs. Mais, cette efficacité n’existe plus quand
le nombre de processeurs augmente. C’est une situation de famine : il n’y a pas assez de
travail pour tous les processeurs. L’iso-efficacité mesure la quantité de travail à ajouter
pour maintenir l’efficacité.

III- TCHNIQUES DE PARALLELISATION


Decomposition des Problemes
La décomposition des problèmes est une technique essentielle en parallélisation qui consiste à
diviser un problème complexe en sous-problèmes plus petits et plus gérables. Voici quelques
étapes et considérations pour appliquer cette technique :
Étapes de décomposition :
1. Analyse du problème :
• Comprendre les caractéristiques du problème à résoudre.
• Identifier les parties du problème qui peuvent être résolues indépendamment.
2. Identification des sous-problèmes :
• Diviser le problème principal en sous-problèmes qui peuvent être traités simultanément.
• Assurer que chaque sous-problème a une taille suffisante pour justifier le coût de la
parallélisation.
3. Évaluation des dépendances :

13
Complexité et algorithme avance

• Analyser les dépendances entre les sous-problèmes pour éviter les conflits.
• Minimiser les communications entre les tâches parallèles pour améliorer l’efficacité.
4. Distribution des tâches :
• Allouer les sous-problèmes aux différentes unités de traitement (cœurs, threads, machines).
• Utiliser des techniques de charge équilibrée pour répartir équitablement le travail.
5. Synchronisation :
• Mettre en place des mécanismes de synchronisation si nécessaire pour gérer les résultats des
sous-problèmes.
• Assurer que les données partagées sont correctement gérées pour éviter les conditions de
concurrence.
6. Agrégation des résultats :
• Combiner les résultats des sous-problèmes pour obtenir la solution finale.
• Vérifier l’intégrité et la cohérence des résultats après l’agrégation.
Exemples de décomposition :
• Calcul numérique : Dans le cas d’une simulation numérique, on peut décomposer le domaine
spatial en mailles, où chaque maille est traitée indépendamment.
• Traitement d’images : Une image peut être divisée en blocs, chaque bloc étant traité par un thread
différent pour appliquer des filtres ou transformations.
• Tri de données : Les algorithmes de tri peuvent utiliser la décomposition par fusion (merge sort)
ou par partitionnement (quick sort), où chaque sous-tableau est trié indépendamment avant d’être
fusionné.
Analyse de dependance entre tache
L’analyse de dépendance entre tâches est une étape cruciale dans la parallélisation des processus,
car elle permet d’identifier comment les différentes tâches interagissent entre elles. Cela aide à
déterminer si les tâches peuvent être exécutées en parallèle ou si certaines doivent être exécutées
séquentiellement. Voici un aperçu des concepts clés et des méthodes pour effectuer cette analyse.
Concepts Clés
1. Dépendances :
• Dépendance de données : Une tâche dépend des résultats d’une autre tâche. Par exemple, si la
tâche A produit une donnée qui est utilisée par la tâche B, alors B dépend de A.
• Dépendance de contrôle : Une tâche doit attendre qu’une autre tâche soit terminée avant de
commencer, souvent en raison de conditions ou de flux de contrôle.
2. Graphes de dépendance :

14
Complexité et algorithme avance

• Les tâches et leurs dépendances peuvent être représentées sous forme de graphes orientés, où
chaque nœud représente une tâche et chaque arête représente une dépendance. Cela permet de
visualiser les relations et d’identifier les tâches indépendantes.
3. Exécution parallèle :
• Les tâches qui n’ont pas de dépendances entre elles peuvent être exécutées simultanément, ce
qui réduit le temps d’exécution global.
Étapes de l’analyse de dépendance
1. Identification des tâches :
• Décomposer le problème en tâches distinctes qui peuvent être exécutées.
2. Identification des dépendances :
• Analyser chaque tâche pour déterminer quelles autres tâches sont nécessaires pour son
exécution.
• Documenter les dépendances sous forme de liste ou de matrice.
3. Représentation graphique :
• Créer un graphe de dépendance pour visualiser les relations entre les tâches. Cela peut aider à
identifier des cycles ou des goulets d’étranglement.
4. Évaluation des impacts :
• Évaluer l’impact des dépendances sur la parallélisation. Par exemple, une tâche avec plusieurs
dépendances peut devenir un point de blocage pour l’exécution parallèle.
5. Optimisation :
• Rechercher des moyens d’atténuer les dépendances, par exemple en réorganisant les tâches ou
en modifiant l’algorithme pour réduire le couplage entre les tâches.
Outils et Techniques
• Analyse statique : Utiliser des outils d’analyse statique pour examiner le code source et identifier
automatiquement les dépendances.
• Modèles de programmation : Utiliser des modèles comme les modèles de calcul parallèle (par
exemple, MapReduce) qui facilitent l’identification et la gestion des dépendances.
• Planification dynamique : Utiliser des algorithmes de planification qui prennent en compte les
dépendances lors de l’allocation des ressources.
Exemples
• Dans un algorithme de tri, si vous avez deux sous-tableaux à trier, vous pouvez trier chaque sous-
tableau indépendamment (pas de dépendance) puis fusionner les résultats (dépendance).
2 1 0 5 7 6 9

15
Complexité et algorithme avance

2 1 0 5 7 6 9

• Dans un pipeline de traitement d’images, chaque étape du pipeline peut dépendre des résultats
de l’étape précédente (dépendance séquentielle).

1- Strategies de decompotion: en taches et en données


1. Décomposition en Tâches
• Description : Diviser le travail en unités de traitement indépendantes (tâches) qui peuvent être
exécutées simultanément.
• Caractéristiques :
• Chaque tâche effectue une opération distincte sur des données.
• Les tâches peuvent être exécutées sur différents processeurs ou cœurs.
• Exemples :
• Traitement d’images : chaque tâche applique un filtre différent à une image.
• Algorithme de type “divide and conquer”( ex: trie rapide)
2. Décomposition en Données
• Description : Diviser les données en segments qui seront traités par des unités de traitement
parallèles.
• Caractéristiques :
• Chaque unité de traitement opère sur une portion des données, souvent de manière similaire.
• Idéal pour les opérations répétitives ou homogènes sur de grandes quantités de données.
• Exemples :
• Traitement de texte : chaque processus traite un segment différent d’un document.
• Bases de données : exécution de requêtes simultanément sur différentes partitions d’une table.
B. Synchronisation et communication
a- Synchronisation
Définition :
La synchronisation est le processus qui permet de coordonner l’exécution de plusieurs processus
ou threads pour éviter des conflits lors de l’accès à des ressources partagées.
Types de synchronisation :
1. Verrous (Locks) : Utilisés pour protéger des sections critiques, garantissant qu’une seule entité
accède à la ressource à la fois.
16
Complexité et algorithme avance

2. Sémaphores : Permettent de contrôler l’accès à un nombre limité de ressources. Ils peuvent être
utilisés pour signaler l’état de disponibilité d’une ressource.
3. Barrières : Synchronisent tous les processus à un point spécifique avant de continuer, assurant
que tous ont atteint la même étape.

Importance :
La synchronisation est essentielle pour préserver l’intégrité des données et éviter les conditions de
course, où plusieurs threads essaient simultanément de modifier une même ressource.
Inconvénients :
Cependant, la synchronisation peut entraîner une surcharge de performance et des risques de
blocage si elle est mal configurée.
b- Communication
Définition :
La communication permet l’échange d’informations entre différents processus ou threads, souvent
situés sur des nœuds distincts.

Types de communication :
1. Communication partagée : Utilisation de la mémoire partagée pour échanger des données,
souvent dans des systèmes avec des threads sur le même nœud.
2. Communication par message : Envoi et réception de messages entre processus, particulièrement
dans les systèmes distribués. Des protocoles comme MPI (Message Passing Interface) sont
couramment utilisés.
Importance :
La communication est cruciale pour coordonner les tâches et échanger les données nécessaires à
l’exécution des tâches parallèles.
Inconvénients :
Elle peut introduire une latence due aux distances entre processus et à la gestion des erreurs de
communication, rendant le système plus complexe.
Protocoles de communication (MPI, OpenMP)
MPI (Message Passing Interface)
Qu’est-ce que c’est ?
MPI est un standard qui permet à plusieurs processus de communiquer entre eux. Il est souvent
utilisé dans les superordinateurs et les clusters pour exécuter des programmes en parallèle.
Comment ça fonctionne ?
17
Complexité et algorithme avance

• Passage de messages : Les processus envoient et reçoivent des messages pour échanger des
données.
• Environnements distribués : Chaque processus peut s’exécuter sur une machine différente, ce qui
est idéal pour les calculs intensifs.
Quand l’utiliser ?
Utilisez MPI lorsque vous avez besoin de faire des calculs sur plusieurs ordinateurs ou serveurs,
par exemple pour des simulations scientifiques ou des traitements de grandes quantités de données.
OpenMP (Open Multi-Processing)
Qu’est-ce que c’est ?
OpenMP est une API qui permet d’écrire des programmes multi-threadés. Elle fonctionne sur des
systèmes où plusieurs threads partagent la même mémoire.
Comment ça fonctionne ?
• Parallélisme partagé : Un programme principal peut créer plusieurs threads pour exécuter
différentes parties du code en même temps.
• Directives simples : Les développeurs ajoutent des directives dans le code pour indiquer quelles
sections doivent s’exécuter en parallèle.
Quand l’utiliser ?
Utilisez OpenMP lorsque vous travaillez sur un seul ordinateur avec plusieurs cœurs et que vous
souhaitez accélérer le traitement de tâches, comme le traitement d’images ou les calculs
numériques.
En résumé
• MPI : Bon pour les environnements distribués (plusieurs machines), basé sur le passage de
messages.
• OpenMP : Idéal pour les systèmes à mémoire partagée (un seul ordinateur), basé sur le
parallélisme avec des threads.
Ces deux outils sont puissants et servent à améliorer la performance des applications en tirant parti
du parallélisme, mais ils sont utilisés dans des contextes différents.

IV. Outils et Environnements de Développement


A- Présentation des principales bibliothèques et frameworks
1. OpenMP, MPI, Pthreads, TBB, CUDA
a. OpenMP (Open Multi-Processing)
• Type : API pour le parallélisme à mémoire partagée.
• Langages : Principalement C, C++, et Fortran.
• Caractéristiques :
18
Complexité et algorithme avance

• Utilise des directives (pragmas) pour indiquer quelles parties du code doivent être exécutées en
parallèle.
• Permet de gérer facilement les threads et la synchronisation.
• Idéal pour tirer parti des architectures multicœurs sur un seul ordinateur.
• Utilisation : Traitement d’images, simulations numériques, applications scientifiques.
2. MPI (Message Passing Interface)
• Type : Standard pour la communication entre processus dans des environnements distribués.
• Langages : C, C++, Fortran, Python, etc.
• Caractéristiques :
• Permet aux processus de s’exécuter sur différentes machines et de communiquer via l’envoi et
la réception de messages.
• Supporte une large gamme de topologies de communication (point à point, collectives).
• Très utilisé dans les supercalculateurs et les clusters.
• Utilisation : Simulations scientifiques, calculs intensifs, traitement de grandes quantités de
données.
3. Pthreads (POSIX Threads)
• Type : API pour le parallélisme à mémoire partagée.
• Langages : C et C++.
• Caractéristiques :
• Fournit un modèle de programmation basé sur des threads légers.
• Offre des fonctions pour créer, gérer et synchroniser des threads.
• Permet un contrôle fin sur la gestion des threads.
• Utilisation : Applications nécessitant une gestion précise des threads, systèmes d’exploitation,
serveurs web.
4. TBB (Threading Building Blocks)
• Type : Bibliothèque C++ pour le parallélisme à mémoire partagée.
• Langages : C++.
• Caractéristiques :
• Fournit des abstractions de haut niveau pour la programmation parallèle (par exemple, des
algorithmes parallèles, des conteneurs concurrentiels).
• Gère automatiquement la répartition des tâches entre les threads.

19
Complexité et algorithme avance

• Optimisé pour tirer parti des architectures multicœurs modernes.


• Utilisation : Applications nécessitant une performance élevée sur des systèmes multicœurs,
traitement d’images, simulations.
5. CUBA (CUDA Unified Binary Architecture)
• Type : Framework pour la programmation parallèle sur GPU.

• Langages : C, C++, Python (via PyCUDA).


• Caractéristiques :
• Permet de tirer parti de la puissance de calcul des unités de traitement graphique (GPU) de
NVIDIA.
• Fournit un modèle de programmation basé sur des kernels exécutés sur le GPU.
• Optimisé pour le calcul parallèle massif.
• Utilisation : Apprentissage automatique, simulations physiques, traitement d’images et vidéos.

C Environnements de développement de algorithme paralleles


Lors du développement d’applications parallèles et distribuées, il est essentiel de disposer d’un
environnement de développement robuste pour optimiser les performances. Voici un aperçu des
environnements de développement et des outils de profiling couramment utilisés dans ce domaine.

a. Environnements de Développement
1. IDE (Environnements de Développement Intégré)
• Visual Studio :
• Supporte C++, C#, et d’autres langages.
• Intégration avec des outils comme OpenMP et Pthreads.
• Outils de débogage avancés et intégration de contrôle de version.
• Eclipse :
• Supporte plusieurs langages via des plugins (C/C++, Java, etc.).
• Peut être configuré pour utiliser MPI et OpenMP.
• PyCharm :
• Pour le développement en Python, avec support pour des bibliothèques comme Dask ou
PyCUDA.
2. Compilateurs
20
Complexité et algorithme avance

• GCC (GNU Compiler Collection) :


• Supporte OpenMP et Pthreads, largement utilisé sur Linux.
• Intel C++ Compiler :
• Optimisé pour le matériel Intel, avec support pour OpenMP et TBB.

• NVCC (NVIDIA CUDA Compiler) :


• Utilisé pour compiler des applications CUDA pour le calcul sur GPU.
3. Systèmes de Gestion de Version
• Git :
• Outil incontournable pour la gestion des versions de code source.
• Permet de collaborer facilement avec d’autres développeurs.
B. Outils de Profiling
1. Profilage de Performance
• gprof :
• Outil de profilage pour les programmes C/C++ compilés avec GCC.
• Fournit des informations sur le temps passé dans chaque fonction.
• Valgrind (Callgrind) :
• Outil d’analyse de performance qui peut fournir des informations détaillées sur l’utilisation
du cache et le temps d’exécution des fonctions.
• Intel Vtune Profiler :
• Outil avancé pour le profilage d’applications C/C++ et Java, offrant des analyses détaillées
sur les performances, l’utilisation des threads, et plus encore.
• Perf :
• Outil intégré dans le noyau Linux pour le profilage des performances à bas niveau.
2. Profilage de Mémoire
• Valgrind (Memcheck) :
• Outil pour détecter les fuites de mémoire et les accès à la mémoire non valides.
• AddressSanitizer :
• Outil intégré dans GCC et Clang pour détecter les erreurs d’accès à la mémoire.
3. Outils Spécifiques au Parallélisme

21
Complexité et algorithme avance

• TAU (Tuning and Analysis Utilities) :


• Outil de profilage qui prend en charge le profilage d’applications parallèles utilisant MPI,
OpenMP, et Pthreads.
• HPCToolkit :
• Outil pour analyser les performances des applications parallèles, permettant d’explorer le
comportement des threads et l’utilisation des ressources.
4. Outils de Visualisation
• ParaView :
• Utilisé pour visualiser les résultats du profilage et analyser les performances graphiquement.
• VisIt :
• Outil de visualisation scientifique qui peut être utilisé pour représenter les données générées
par les outils de profilage.

C. Exemples d’implémentation d’algorithmes parallèles

5 4 9 1 7 11 28 67 40

Tableau divisé :
1. Thread 1 : 5 4

2. Thread 2 : 9 1 7

3. Thread 3 : 11 28 67 40

Étapes de recherche
1. Thread 1 commence à chercher le nombre 28 dans sa portion :
- Il vérifie 5 (pas trouvé)
- Il vérifie 4 (pas trouvé)
- Thread 1 ne trouve pas 28 et renvoie False.
2. Thread 2 cherche dans sa portion :
- Il vérifie 9 (pas trouvé)
- Il vérifie 1 (pas trouvé)

22
Complexité et algorithme avance

- Il vérifie 7 (pas trouvé)


- Thread 2 ne trouve pas 28 et renvoie False.
3. Thread 3 examine sa portion :
- Il vérifie 11 (pas trouvé)
- Il vérifie 28 (trouvé !)
- Thread 3 trouve 28 et renvoie True.
Rassemblement des résultats
Après que chaque thread ait terminé sa recherche, on collecte les résultats :
- Résultats des threads :
- Thread 1 : False
- Thread 2 : False
- Thread 3 : True
Décision finale
On vérifie si au moins un des résultats est True. Comme Thread 3 a trouvé 28, le résultat final de
la fonction de recherche parallèle est :
Résultat final : True

COMPLEXITE:
Complexité temporelle
1. Division du tableau : Supposons que le tableau initial ait une taille n . Si nous divisons ce
tableau en p portions égales pour p threads, chaque thread va traiter une portion de taille
n/p .
2. Recherche dans chaque portion : Chaque thread effectue une recherche linéaire dans sa
portion. La complexité de la recherche linéaire dans une portion de taille n/p est O((n/p))
.
3. Exécution parallèle : Les threads s’exécutent simultanément. Dans le meilleur des cas, si
un des threads trouve l’élément recherché, la recherche s’arrête, et le temps total sera
dominé par le temps du thread qui a trouvé l’élément.
En considérant le scénario où l’élément est trouvé par un thread, la complexité temporelle est :
O((n / p))
Dans le pire des cas, si l’élément n’est pas présent, tous les threads devront terminer leur recherche,
ce qui donnerait une complexité temporelle totale de :O(n)

23
Complexité et algorithme avance

IMPORTANCES ET DEFIS DE L’ALGORITHME PARALLELE


L’algorithme parallèle joue un rôle crucial dans le domaine de l’informatique moderne, en
particulier avec l’essor des architectures multicœurs et des systèmes distribués. Voici une vue
d’ensemble de son importance ainsi que des défis associés.
Importance des Algorithmes Parallèles
1. Performance Améliorée :
• Les algorithmes parallèles permettent d’exécuter plusieurs opérations simultanément, ce qui
peut réduire considérablement le temps d’exécution pour des tâches lourdes ou complexes.
2. Utilisation Efficace des Ressources :
• Avec des processeurs multicœurs, les algorithmes parallèles exploitent pleinement les
ressources matérielles disponibles, augmentant ainsi l’efficacité globale du système.
3. Traitement de Grands Volumes de Données :
• Dans des domaines comme le big data, le traitement parallèle est essentiel pour analyser et
traiter rapidement de grandes quantités de données.
4. Applications dans Divers Domaines :
• Les algorithmes parallèles sont utilisés dans de nombreux domaines, notamment la simulation
scientifique, le rendu graphique, l’intelligence artificielle, et la recherche opérationnelle.
5. Amélioration de la Scalabilité :
• Les systèmes parallèles peuvent être conçus pour s’adapter à des charges de travail croissantes,
permettant aux applications de rester performantes même avec des volumes de données en
augmentation.
Défis des Algorithmes Parallèles
1. Complexité de Conception :
• Concevoir des algorithmes parallèles peut être plus complexe que leurs homologues
séquentiels. Il faut prendre en compte la synchronisation, la communication entre les
threads/processus et la gestion des ressources.
2. Synchronisation et Concurrence :
• Gérer l’accès concurrent aux ressources partagées peut entraîner des problèmes tels que les
conditions de course, les blocages (deadlocks) et les interblocages (livelocks).
3. Diminution des Rendements :
• L’augmentation du nombre de threads n’entraîne pas toujours une réduction proportionnelle
du temps d’exécution. Des facteurs comme la surcharge de communication entre threads peuvent
limiter les gains de performance.
4. Difficulté de Débogage :
• Le débogage d’applications parallèles est souvent plus difficile en raison de la nature non
déterministe de l’exécution parallèle, où le comportement peut varier d’une exécution à l’autre.
24
Complexité et algorithme avance

5. Portabilité et Compatibilité :
• Les algorithmes parallèles doivent être adaptés à différentes architectures matérielles (CPU,
GPU, clusters) et peuvent rencontrer des problèmes de compatibilité selon l’environnement
d’exécution.
6. Gestion de la Mémoire :
• La gestion efficace de la mémoire devient plus complexe dans un environnement parallèle,
surtout lorsqu’il s’agit de partager ou d’accéder à des données entre différents threads ou
processus.

Principaux modèles de programmation parallèle :


Architectures à mémoire partagée
1. Intrinsics instructions vectorielles assembleur (Intel SSE2, ARM NEON) très bas niveau
2.Posix Threads bibliothèque standardisée, bas niveau
3.OpenMP API standard de fait
4. CUDA plateforme propriétaire pour accélérateurs
5.OpenCL API et langage pour SMP + accélérateurs
Architectures à mémoire distribuée
1.Sockets bibliothèque standardisée, bas niveau
2.MPI Message Passing Interface, bibliothèque standard de fait pour les architectures à mémoire
distribuée (fonctionne aussi sur les SMP), remaniement important du code

25
Complexité et algorithme avance

UTILISATION DE openMP
● Description :
OpenMP (Open Multi-Processing) est une interface de programmation pour le calcul parallèle sur
architecture à mémoire partagée. Cette API est supportée sur de nombreuses plateformes, incluant
Unix et Windows, pour les langages de programmation C/C++ et Fortran. Il se présente sous la
forme d'un ensemble de directives, d'une bibliothèque logicielle et de variables d'environnement.
OpenMP est portable et dimensionnable. Il permet de développer rapidement des applications
parallèles à petite granularité en restant proche du code séquentiel.

Structure d’OpenMP : architecture logicielle

1.Directives pour expliciter le Programme C/C++ OpenMP API

Parallélisme, les
Synchronisations et le statut Directives
Compilation #pragma
des données (privées, omp
Partagées...)
2.Bibliothèque pour des Bibliothèque
Édition de liens
Fonctionnalités spécifiques #include
<omp.h>
(Informations dynamiques,
Actions sur le runtime...)
Exécution Variables
3.Variables d’environnement environment
OMP_
Pour influer sur le programme à exécuter
(nombre de threads, stratégies
d’ordonnancement...)

26
Complexité et algorithme avance

Modèle d’exécution OpenMP

C’est un modele de programmation parallele concu pour les architectures a memoire partage. Il
perme de developper des applications multithreadées en utilisant un ensemble d’annotation sous
forme de directives de compilation, des fonctions de biblioheques, et des variables
d’environnement.
Voici les principaux concepts du modele d’execution openMp:

Thread maître Équipe de threads


fork
region parallele

join

Directives et les clauses OpenM


Definition de directive
une directive est une instruction spéciale utilisée pour indiquer au compilateur comment
paralléliser le code. Les directives permettent de gérer la création et la synchronisation des threads
ainsi que de spécifier comment les données doivent être partagées entre ces threads. Elles sont
écrites sous forme de commentaires spéciaux, de sorte que le code reste compilable même sans
OpenMP activé.
Definition de clause
C’est un mot-clé ou une instruction qui modifie ou configure le comportement d’une directive. Les
clauses sont souvent utilisées pour specifier comment les variables sont partagées entre les thread,
definir des options d’execution ou obtimiser les performances
Structure d’une directive OpenMP
En C/C++ : Les directives commencent par #pragma omp, suivi du type de directive et des
options.
#pragma omp directive [clauses]
En Fortran : Elles commencent par un commentaire spécial (par exemple, !$OMP).
Structure generale de clause
#pragma omp directive [clauses]
27
Complexité et algorithme avance

Exemple
#pragma omp parallele private(x)
Shared(y) num_threads(5)
Dans cet exemple, les clauses sont:
.private(x): rend la variable x privée pour chaque thread.
.shared(y): partage la variable y entre tous les threads.
Num_threads(4): limite le nombre de threads à 4

Principales directives OpenMP


a.Construction de régions parallèles
1. Directives de parallélisation : Elles permettent d’exécuter une section de code en
parallèle.
Fonctionnement :
Quand un thread rencontre une directive parallel, il crée une équipe de threads dont il devient le
thread maître de numéro 0 ; les threads de l’équipe exécutent tous le bloc Le nombre de threads
dépend, dans l’ordre, de l’évaluation de la clause if, de la clause num_threads, de la primitive
omp_set_num_threads(), de la variable d’environnement OMP_NUM_THREADS, de la valeur
par défaut Il existe une barrière implicite à la fin de la région parallèle
Exemple :
#pragma omp parallel
{
/ / Ré gion p a r a l l è l e
}
Les clauses
1.Clause if
i f ( /∗ Exp ression s c a l a i r e ∗/ )
Quand elle est présente, une équipe de threads n’est créée que si l’expression scalaire est différente
de zéro, sinon la région est exécutée séquentiellement par le thread maîtr
Exemple d’utilisation de la clause if
#include < s t d i o . h>
#de fine PARALLEL 1 / / 0 pour sé q u e nt i e l , != 0 pour p a r a l l è l e
i n t main ( ) { #pragma omp p a r a l l e l i f (PARALLEL )
p r i n t f ( " Hello , openMP \ n " ) ;

28
Complexité et algorithme avance

re tu rn 0;
}
2.Clause num_threads
Format de la clause num_threads
num_threads ( /∗ Exp ression e n t i è re ∗/ )
- Spécifie le nombre de threads de l’équipe qui exécutera la prochaine région parallèle
- L’expression entière doit s’évaluer en une valeur entière positive
b.Partage du travail
c’est une instruction donnée au compilateur pour geré l’execution parallele du code. Ces directives
fonctionnent comme “ordre” que le programmeur donne au compilateur afin de definir que parties
du code doivent etre executées par plusieurs threads, comment les données doivent etre partagées,
et comment les taches doivent etre reparties.
1.Directives(for) pour les boucles : Elles permettent de paralléliser des boucles pour répartir les
itérations sur plusieurs threads.

Exemple :
#pragma omp parallel for
For (int i = 0; i < 10; i++) {
Printf(“i = %d\n”, i);}
Indique que les itérations de la boucle qui suit la directive doivent être exécutées en parallèle par
l’équipe de threads
- La variable d’itération est privée par défaut
- Les boucles doivent avoir une forme itérative simple [doc]
- Les bornes doivent être les mêmes pour tous les threads
- Les boucles infinies ou while ne sont pas supportées
- Rappel : le programmeur est responsable de la sémantique
- Clauses possibles : schedule, ordered, private, firstprivate, lastprivate, reduction, collapse, nowait
Thread maître Équipe de threads

Iterations

29
Complexité et algorithme avance

2.Directive sections : définit des blocs à exécuter en parallèle


Elle permet de specifier des blocs de code independants à executer en parrallele.chaque bloc, defini
par directive section, sera executé par un thread different, si possible.
Exemple
#pragma omp sections [ clau se [ clau se ] . . . ]
{
#pragma omp sec tion
/ / Bloc 1 . . .
#pragma omp sec tion
/ / Bloc N
}

Commentaires
Cet exemple Indique que les instructions dans les différentes sections doivent être exécutées en
parallèle par l’équipe de threads
- Chaque section n’est exécutée qu’une seule fois
- Les sections doivent être définies dans l’étendue statique
- Clauses possibles : private, firstprivate, lastprivate, reduction, nowait
Thread maître Équipe de threads

Section
sections : répartit suivant des sections prédéfinies
3.Directive single
Elle est utilisée pour especifier qu’un seul thread dans une equipe doit executer un bloc de code
tandis que les autres threads attands à un barriere implicite à la fin de ce bloc, sauf si cette barriere
est explicitement suprimé avec l’option nowait ( une close).
30
Complexité et algorithme avance

Exemple:
#pragma omp single [ clau se [ clau se ] . . . ] {
/ / Bloc
}
Spécifie que le bloc d’instructions suivant la directive sera exécuté par un seul thread
- On ne peut pas prévoir quel thread exécutera le bloc
- Utile pour les parties de code non thread-safe (par exemple les entrées/sorties)
- Clauses possibles : private, firstprivate, copyprivate, nowait

Thread maitre Single : un seul thread exécute une section prédéfini

Équipe de threads

c.Synchronisation
Directives de synchronisation : Elles gèrent la coordination entre les threads, comme les barrières
ou les sections critiques.
1. Directive Master : déclare un bloc à exécuter par le thread maître
Elle permet d’executer un bloc de code uniquement par les threads maitres (le thread ayant
l’identité 0 dans l’equipe de threads).
Exemple:
#pragma omp master {
/ / Bloc
}
Spécifie que le bloc d’instructions suivant la directive sera exécuté par le seul thread maître, les
autres threads passent cette section de code
- Pas de barrière implicite ni à l’entrée ni à la fin du bloc
- Clauses possibles : aucune
2. Directive critical : bloc à n’exécuter qu’un thread à la fois
31
Complexité et algorithme avance

Exemple :
#pragma omp c r i t i c a l [ nom] {
/ / Bloc
}
Spécifie que le bloc d’instructions suivant la directive doit être exécuté un seul thread à la fois
- Si un thread exécute un bloc protégé par la directive critical et qu’un second arrive à ce bloc,
alors le second devra attendre que le premier ait terminé avant de commencer l’exécution du bloc
- Les blocs précédés de directives critical avec un même nom sont exécutés en exclusion mutuelle
-Clauses possibles : aucune
3. Directive atomic instruction dont l’écriture mémoire est atomique
Exemple:
#pragma omp atomic
//Instructiond’affectatio
Spécifie que l’affectation (évaluation et écriture de la variable affectée) suivant la directive doit
être réalisée de manière atomique
- Plus efficace que la directive critical dans ce cas
- Formes d’instruction particulières
- Clauses possibles : aucune
4. Directive barrier : attente que tous les threads arrivent à ce point
Exemple
#pragma omp b a r ri e r
-Synchronisation entre tous les threads d’une équipe
- Quand un thread arrive à la directive barrier il attend que tous les autres threads y soient arrivés
; quand cela arrive, les threads poursuivent leur exécution en parallèle
- Doit être rencontrée par tous les threads ou aucun : attention aux interblocages (deadlocks)
- Clauses possibles : aucune
d. Gestion de tâches
Elles permettent de décomposer le travail en tâches indépendantes.
1.directive task : déclaration d’une tâche fille
Exemple :
#pragma omp task [ clau se [ clau se ] . . . ] {
32
Complexité et algorithme avance

/ / Bloc
}
Crée une nouvelle tâche composée du bloc d’instruction suivant la directive
- La tâche créée est soit exécutée immédiatement par le thread qui l’a créée (voir clauses), soit
ajoutée au pool
- Par défaut variables shared si toujours shared depuis la première région parallèle, firstprivate
sinon
- Clauses possibles : if (sémantique différente de la directive parallel), final, untied, default,
mergeable, private, firstprivate, shared
2. Directive taskwait : attente de la fin des tâches filles
Exemple :
#pragma omp taskwai
Spécifie un point d’attente de la terminaison de toutes les sous-tâches créées par le thread
rencontrant la directive
-Il s’agît d’une barrière spécifique aux tâches I Clauses possibles : aucune

INSTALLATION ET CONFIGURATION DE openMP


L’installation et la configuration d’OpenMP dépendent de votre système d’exploitation (Windows
ou Linux) et du compilateur que vous souhaitez utiliser (GCC, Clang ou Visual Studio). Voici un
guide détaillé pour vous permettre de configurer OpenMP.
1. Comprendre OpenMP
OpenMP n’est pas une bibliothèque autonome, mais une extension du compilateur. Elle s’active
via des options spécifiques lors de la compilation du code, comme -fopenmp (GCC/Clang) ou
/openmp (Visual Studio).
2. Configuration d’OpenMP sur Linux
Étape 1 : Installer un compilateur compatible
Les compilateurs courants comme GCC et Clang prennent en charge OpenMP. Voici comment les
installer
Avec GCC
1. Mettez à jour vos paquets :
Sudo apt update
2. Installez GCC :
Sudo apt install gcc g++
3. Vérifiez que GCC est installé et supporte OpenMP :
33
Complexité et algorithme avance

Gcc –version
Avec Clang
1. Installez Clang :
Sudo apt install clang
2. Installez la bibliothèque OpenMP pour Clang :
Sudo apt install libomp-dev
Étape 2 : Configurer et tester
1. Écrivez un programme OpenMP (exemple ci-dessous) :
#include <stdio.h>
#include <omp.h>
Int main() {
#pragma omp parallel
{
Printf(“Bonjour depuis le thread %d\n”, omp_get_thread_num());
Return 0;}
2. Compilez avec GCC :
Gcc -fopenmp programme.c -o programme
3. Exécutez l’exécutable :
./programme
Si vous utilisez Clang :
Clang -fopenmp programme.c -o programme
./programme
4. Configuration d’OpenMP sur Windows
Option 1 : Utilisation de MinGW (GCC)
1. Téléchargez et installez MinGW-w64 :
Rendez-vous sur MinGW-w64 et téléchargez la version adaptée.
Configurez le chemin d’accès à MinGW dans votre variable d’environnement PATH (ajoutez le
répertoire bin).
2. Vérifiez que GCC est installé :
Gcc –version
34
Complexité et algorithme avance

3. Compilez un programme avec OpenMP :


Gcc -fopenmp programme.c -o programme
Programme.exe
Option 2 : Utilisation de Visual Studio
1. Téléchargez Visual Studio Community Edition :
Téléchargez Visual Studio.
2. Ajoutez les outils C++ :
Pendant l’installation, sélectionnez le chargement de bureau avec C++.
OpenMP est inclus dans Visual Studio.
3. Activez OpenMP dans un projet :
Ouvrez Visual Studio.
Allez dans Propriétés du projet → C/C++ → Commandes supplémentaires.
Ajoutez /openmp pour activer OpenMP.
4. Compilez et exécutez le projet.

Avantages et défis de openMP


Avantages d’OpenMP
OpenMP est largement utilisé pour la programmation parallèle sur des systèmes multi-cœurs, et il
présente plusieurs avantages :
1. Facilité d’utilisation
Approche basée sur les directives : Vous pouvez paralléliser des sections de code en ajoutant des
directives #pragma sans réécrire tout le programme.
Intégration avec des compilateurs standards : OpenMP est supporté par des compilateurs
populaires comme GCC, Clang et Visual Studio.
Apprentissage rapide : Les développeurs familiarisés avec C, C++ ou Fortran peuvent rapidement
adopter OpenMP.
2. Flexibilité
Vous pouvez paralléliser à différents niveaux de granularité (boucles, blocs de code, etc.).
Supporte les architectures multi-cœurs et les processeurs partagés (SMP).
3. Portabilité
OpenMP est indépendant de la plateforme : le même code peut être exécuté sur Windows, Linux
ou macOS avec un compilateur compatible.
4. Scalabilité
35
Complexité et algorithme avance

Il permet d’utiliser efficacement plusieurs cœurs sans avoir à gérer manuellement les threads.
Vous pouvez ajuster dynamiquement le nombre de threads (omp_set_num_threads() ou
OMP_NUM_THREADS).
5. Compatibilité avec les applications séquentielles
Le code reste fonctionnel en mode séquentiel si OpenMP est désactivé. Cela facilite le débogage
ou les tests.
6. Fonctionnalités avancées
Gestion automatique des threads : Le runtime gère la création et la terminaison des threads.
Réduction des variables : OpenMP simplifie le calcul des valeurs globales grâce à des clauses
comme reduction.
Synchronisation des threads : Avec des outils comme #pragma omp critical, il est facile de protéger
des sections critiques du code.
Défis et limites d’OpenMP
Malgré ses nombreux avantages, OpenMP présente aussi certains défis qu’il est important de
comprendre :
1. Limitations liées à la mémoire partagée
2. OpenMP est conçu pour les systèmes à mémoire partagée (SMP). Sur des architectures
distribuées, il peut ne pas être adapté.
Problèmes de contention : Plusieurs threads accédant à la même ressource peuvent provoquer des
ralentissements (par exemple, verrouillage ou sections critiques).
3. Difficulté de débogage
Les programmes parallèles sont souvent difficiles à déboguer à cause des problèmes comme les
conditions de course ou les blocages.
Les erreurs de parallélisation peuvent être non déterministes, ce qui complique leur reproduction.
4. Performance limitée
Overhead des threads : L’utilisation de threads a un coût en termes de performance
(création/destruction, synchronisation).
Granularité : Une parallélisation trop fine peut entraîner des frais généraux supérieurs aux gains
en performance.
Les performances dépendent de la taille des tâches parallèles et de la capacité du système.
5. Programmation complexe
Bien qu’OpenMP simplifie la parallélisation, les concepts avancés (réduction, synchronisation,
partage de données) peuvent être complexes pour les débutants.

36
Complexité et algorithme avance

Nécessite une compréhension approfondie de l’architecture du matériel pour une parallélisation


optimale.
6. Compatibilité et portabilité limitées
Tous les compilateurs ne supportent pas l’intégralité des fonctionnalités d’OpenMP, ce qui peut
entraîner des comportements non cohérents sur différentes plateformes.
7. Restrictions sur les types de tâches parallèles
OpenMP est principalement adapté aux tâches parallèles embarquées dans des boucles ou des
sections indépendantes. Il est moins efficace pour les graphes de tâches complexes ou les
dépendances dynamiques.
8. Dépendance au matériel
L’efficacité dépend du matériel sous-jacent (nombre de cœurs, architecture mémoire, etc.). Un
code OpenMP peut être inefficace sur des systèmes avec peu de cœurs ou une architecture non
uniforme (NUMA).
Conseils pour relever les défis
1. Débogage :
Utilisez des outils comme gdb, Intel Inspector ou Visual Studio Debugger pour identifier les
conditions de course et les blocages.
2. Optimisation :
Analysez les goulots d’étranglement avec des outils de profilage (ex. : perf, Intel Vtune).
Ajustez la granularité des tâches pour limiter l’overhead.
3. Amélioration de la portabilité :
Testez le code sur différents systèmes et compilateurs.
Évitez de dépendre des fonctionnalités spécifiques à un compilateur.

37
Complexité et algorithme avance

CONCLUSION

La parallélisation des algorithmes représente une avancée majeure dans le domaine de


l’informatique, répondant aux exigences croissantes en matière de performance et d’efficacité dans
le traitement des données. À mesure que les architectures matérielles évoluent vers des systèmes
multicœurs et distribués, il devient impératif pour les développeurs et les chercheurs de maîtriser
les principes de la conception d’algorithmes parallèles.

Ce chapitre a mis en lumière les avantages significatifs de la parallélisation, notamment


l’accélération des temps de calcul, l’optimisation de l’utilisation des ressources et la capacité à
traiter de vastes volumes de données. Cependant, il a également souligné les défis inhérents à cette
approche, tels que la complexité de conception, la gestion de la synchronisation, et les problèmes
de débogage.

En conclusion, bien que la parallélisation d’algorithmes ouvre la voie à des performances


exceptionnelles, elle nécessite une compréhension approfondie des concepts sous-jacents ainsi
qu’une approche méthodique pour surmonter les obstacles techniques. En intégrant ces
connaissances, les professionnels de l’informatique peuvent non seulement améliorer l’efficacité
de leurs applications, mais aussi contribuer à l’innovation continue dans un monde de plus en plus
axé sur le traitement parallèle.

38

Vous aimerez peut-être aussi