Title: Parallelisme
1Parallelisme
- (Basé sur Concepts of Programming Languages, 8th
edition, by Robert W. Sebesta, 2007)
2Les différents types de Parallelisme
- Le parallelisme dans l'exécution de logiciel peut
se produire à quatre niveaux différents - Niveau des instructions de machines - exécutant
deux ou plus instructions de machine
simultanément. - Niveau des instructions de code - exécutant deux
instructions de code source ou plus
simultanément. - Niveau des Unités - exécutant deux unités ou plus
de sous-programme simultanément. - Niveau des Programmes - exécutant deux
programmes ou plus simultanément. - Puisqu'aucune issue reliee a la conception de
langue n'est impliquée dand le parallelisme au
niveau des instructions-machine et au niveau des
programmes, ils ne sont pas discutés dans ce
cours.
3Les différents types darchitectures a
processeurs multiples
- Les deux catégories les plus communes
darchitectures a processeurs multiples sont - Single-Instruction Multiple-Data (SIMD)
Architectures a processeurs multiples qui
exécutent la même instruction simultanément,
chacun sur des données différentes. - Multiple-Instruction Multiple-Data (MIMD)
Architectures a processeurs multiples qui opèrent
indépendamment mais dont les opérations peuvent
être synchronisés.
4Les différentes catégories de Parallelisme
- Il y a deux catégories distinctes de control
parallele d'unités - Le parallelisme Physique Plusieures unités
appartenant au même programme sont exécutées
littéralement en parallele sur différents
processeurs. - Le parallelisme Logique - Plusieures unités
appartenant au même programme semblent (au
programmeur et a l'application) etre exécute en
parallele sur différents processeurs. En fait,
l'exécution réelle des programmes a lieu de
maniere intercalée sur un processeur simple. - Pour le programmeur et le createur de langage,
les deux types de parallelisme sont les mêmes.
5Tâches I
- Une Tâche ou un processus est une unité de
programme, semblable à un sous-programme qui peut
être exécutée en parallele avec d'autres unités
du même programme. - Il y a trois différences entre les tâches et les
sous-programmes - Une tâche peut commencer implicitement tandis
qu'un sous-programme doit être appelé
explicitement. - Quand une unité de programme appelle une tâche,
elle n'a pas besoin d'attendre que la tâche à
accomplir soit terminée avant de continuer la
sienne. - Quand l'exécution d'une tâche est accomplie, la
commande peut ou peut ne pas retourner à l'unité
qui l'a appelée.
6Tâches II
- Il y a deux catégories de Tâches
- Heavyweight Tâches tâches exécutées dans leur
propre espace mémoire. - Lightweight Tâches tâches qui fonctionnent
toutes dans le même espace mémoire. - Lightweight tâches sont plus faciles a mettre en
application que les heavyweight tâches. - Les tâches peuvent typiquement communiquer avec
dautre tâches afin de partager le travail
nécessaire pour accomplir le programme . - Les tâches qui ne communiquent pas avec ou
n'affectent pas l'exécution d'autres tâches
sappellent des tâches disjointes. - Typiquement, les tâches ne sont pas disjointes et
doivent synchroniser leur exécution, partager les
données, ou les deux a la fois.
7Synchronisation
- La synchronisation est un mécanisme qui controle
l'ordre dans lequel les tâches sont exécutées.
Ceci peut être fait par la coopération ou
la compétition. - La synchronisation pour coopération est exigée
entre une tâche A et une tâche B quand
la tâche A doit attendre que la tâche B
soit terminée pour continuer son exécution. - La synchronisation pour competition est exigée
entre deux tâches quand toutes deux
exigent l'utilisation d'une certaine
ressource qui ne peut pas être employée
simultanément. - Pour la synchronisation pour coopération, des
tâches spécifiques doivent être accomplies avant
quune nouvelle tâche puisse-t-etre exécuté,
tandis que, pour la synchronisation pour
competition, certaines ressources doivent etre
liberees avant quune nouvelle tâche s'exécute.
8Un exemple de synchronisation pour coopération
- Le Problème Du Producteur et du
Consommateur
- Le programme 1 produit des données Le programme
2 emploie les données. - La synchronisation est nécessaire
- L'unité du consommateur ne doit pas prendre des
données si la mémoire tampon est vide - L'unité du producteur ne peut pas placer de
nouvelles données dans la mémoire tampon si elle
n'est pas vide
9Exemple de synchronisation pour competition I
- Nous avons deux tâches (A et B) et une variable
partagée (TOTAL) - La tâche A doit additionner 1 à TOTAL
- La tâche B doit multiplier TOTAL par 2.
- Chaque tâche accomplit son opération en utilisant
le processus suivant - Chercher la valeur dans TOTAL
- effectuer l'opération arithmétique
- Remettre la nouvelle valeur dans TOTAL
- TOTAL a une valeur originale de 3.
10Exemple de synchronisation pour competition II
- Sans synchronisation pour competition, 4 valeures
peuvent résulter de l'exécution des deux tâches - Si A saccomplit avant que B ne commence? 8
- Si A et B cherchent le TOTAL avant que l'un ou
l'autre remette la nouvelle valeur dedans, alors
nous avons - Si A remet la nouvelle valeur dans TOTAL en
premier? 6 - Si B remet la nouvelle valeur dans TOTAL en
premier ? 4 - Si B saccomplit avant qu'A ne commence? 7
- Ce genre de situation s'appelle un état de course
parce que deux taches ou plus font la course pour
utiliser les ressources partagées et le résultat
dépend de quelle tache arrive la premiere.
11Comment pouvons nous permettre lacces
mutuellement exclusif à une ressource partagée? I
- Une méthode générale consiste à considérer la
ressource en tant quentite quune tâche peut
posséder et ne permettre qua une tâche de la
posseder à la fois. - Afin de posseder une ressource partagée, une
tâche doit demander la permission dy accéder. - Quand une tâche a fini dutiliser une ressource
partagée qu'elle possède, elle doit labandonner
de maniere a ce que la ressource soit rendue
disponible à d'autres tâches.
12Comment pouvons nous permettre lacces
mutuellement exclusif à une ressource partagée? II
- Afin que cet arrangement général marche, nous
devons poser deux conditions - Il doit y avoir une manière de retarder
l'exécution des tâches - L'exécution de tâches doit être controllée
- L'exécution de tâches est controllée par le
scheduleur qui contrôle le partage des
processeurs parmi les tâches en créant des
tranches de temps et les distribuant tour a tour. - Le travail du scheduleur, cependant, n'est pas
aussi simple qu'il peut sembler en raison des
delais de taches qui sont nécessaires pour la
synchronisation et lattente pendant les
opérations d'entrée-sortie.
13États des tâche
- Afin de simplifier limplantation dattentes pour
la synchronisation, les tâches peuvent être dans
différents états - Nouvelle la tâche a été créée mais n'a pas
encore commencé son exécution - Prête la tâche est prête à executer mais elle
nexecute pas en ce moment. Elle se trouve dans
la file d'attente des tâches prêtes . - En execution la tâche est exécutée en ce moment
- Bloquée la tâche nest pas presentement en
execution parce qu'elle a été interrompue par un
de plusieurs événements (habituellement une
opération d'I/O). - Morte Une tâche meurt une fois son exécution
terminee ou lorsquelle est explicitement tuée
par le programme.
14Perte de Vie
- Supposez que les tâches A et B aient besoin des
ressources X et Y pour terminer leurs travaux. - Supposez que la tâche A gagne la possession de X
et la tâche B gagne la possession de Y. - Après une certaine exécution, la tâche A a besoin
de gagner possession de Y, mais doit attendre
que la tâche B la libère. De même la tâche B doit
gagner possession de X mais doit attendre que la
tâche A la libere. - Ni l'une ni l'autre des tâches n'abandonne la
ressource quelle possède, et en conséquence,
toutes les deux perdent leur vie. - Ce genre de perte de vie s'appelle un inter
blocage ou deadlock. - Les inter blocages sont des menaces sérieuses à
la fiabilité d'un programme et doivent être
évitées.
15Question de conception pour le parallelisme
Mécanismes pour la synchronisation
- Nous discutons maintenant de trois méthodes qui
permettent lacces mutuellement exclusif aux
ressources - Les Sémaphores
- Les Moniteurs
- Le passage de Messages
- Dans chaque cas, nous discuterons de la maniere
dont la méthode peut être employée pour implanter
la synchronisation pour coopération et la
synchronisation pour competition.
16Sémaphores I
- Une sémaphore est une structure de données se
composant d'un nombre entier et d'une file
d'attente qui stocke des descripteurs de tâche. - Un descripteur de tâche est une structure de
données qui stocke toutes les informations
appropriées sur l'état d'exécution d'une tâche. - Le concept d'une sémaphore est que, pour fournir
l'accès limité à une structure de données, des
gardes sont placées autour du code qui accède à
la structure.
17Sémaphores II
- Un garde permet au code gardé d'être exécuté
seulement quand une condition particuliere est
vraie. Un garde peut être employé pour permettre
à une seule tâche à la fois d'accéder à une
structure de données partagée. - Une sémaphore est limplantation d'un garde. Les
demandes d'accès à la structure de données qui ne
peut pas être honorées sont stockées dans la file
d'attente du descripteur de tâche de la sémaphore
jusqu'à ce que l'accès puisse-t-etre accorde. - Il y a deux opérations liées à une sémaphore
attendre et libérer
18Sémaphores Opérations dAttente et de Libération
- Release(Sem)
- If Sems queue is empty (no task is waiting) then
- Increment Sems counter
- else
- Put the calling task in the task-ready queue
- Transfer control to a task from Sems queue.
- Wait(Sem)
- If Sems counter gt 0 then
- Decrement Sems counter
- else
- Put the caller in Sems queue
- Attempt to transfer control to some ready task
(if the task queue is empty, deadlocks occur)
19Synchronisation De Coopération Le Problème Du
Producteur Consommateur défini à l'aide des
sémaphores
semaphore fullspots, emptyspots fullspot.count
0 Emptyspot.count BUFLEN
task producer loop -- produce VALUE --
wait(emptyspots) DEPOSIT(VALUE)
release(fullspots) end loop end producer
- task consummer
- loop
- wait(fullspots)
- FETCH(VALUE)
- release(emptyspots)
- -- consume VALUE --
- end loop
- end consumer
20Synchronization de Competition Exécution
partagée de la mémoire tampon implementation
avec semaphores
semaphore access, fullspots, emptyspots Access.co
unt 1 fullspot.count 0 Emptyspot.count
BUFLEN
task producer loop -- produce VALUE --
wait(emptyspots) wait(access)
DEPOSIT(VALUE) release(access)
release(fullspots) end loop end producer
task consummer loop wait(fullspots)
wait(access) FETCH(VALUE) release(access)
release(emptyspots) -- consume VALUE -- end
loop end consumer
21Inconvénients des sémaphores
- L'utilisation des sémaphores pour la
synchronisation crée un environnement peu sûr. - Dans La Synchronisation De Coopération
- Loubli de l'instruction wait(emptyspots)
causerait un débordement de la mémoire tampon. - Loubli de l'instruction wait(fullspots)
causerait un underflow de la
mémoire tampon - Dans La Synchronisation De Competition
- Loubli de l'instruction wait(access) de l'une ou
l'autre des tâches peut causer un
accès peu sûr à la mémoire tampon - Loubli de l'instruction release(access) de l'une
ou l'autre des tâche peut causer un
interblocage. - Aucune de ces erreurs ne peut être vérifiée au
moment de la compilation puisqu'elles dépendent
de la sémantique du programme.
22Moniteurs
- Les moniteurs résolvent les problèmes des
sémaphores en encapsulant les structures de
données partagées avec leurs opérations et en
cachant leur exécution.
Monitor
Processus Sub 1
Mémoire Tampon
Insérer
Processus Sub 2
Supprimer
Processus Sub 3
Processus Sub 4
23Synchronisation de competition et de coopération
en utilisant des moniteurs
- Synchronisation De Competition Puisque tous les
accès sont résidents au le moniteur,
limplantation du moniteur peut garantir l'accès
synchronisé en permettant seulement un accès à la
fois. - Synchronisation De Coopération La coopération
entre les processus demeure a la charge du
programmeur qui doit s'assurer qu'une memoire
tampon partagée ne subisse pas dunderflow ou
de débordement. - Évaluation Les moniteurs sont une meilleure
manière de fournir la synchronisation que les
sémaphores, bien que certains des problèmes des
sémaphores dans l'exécution de la synchronisation
de coopération se retrouvent.
24Passage de Messages Synchronisé
- Supposez que la tâche A et la tâche B sont toutes
deux en exécution, et que A souhaite envoyer un
message à B. Si B est occupé, il n'est pas
souhaitable de permettre à une autre tâche de
l'interrompre. - Au lieu de cela, B peut signaler à d'autres tâche
le moment ou il est prêt a recevoir des messages.
A ce moment la, la tâche A peut envoyer un
message. Quand la transmission a enfin lieu, nous
parlons dun rendez-vous. - Le passage de messages (synchronise ou nom) est
disponible en Ada. La Synchronisation de
competition et la Synchronisation de
coopération peuvent être toutes deux mises en
application en utilisant ce paradigme.
25Le Parallelisme en Java Threads
- Les unités concourantes en Java sont des méthodes
appelées run dont le code peut être exécute en
parallele avec d'autres méthodes du meme type
(appartenant a d'autres objets) et avec la
méthode principale. - Le processus dans lequel la méthode run est
exécutee s'appelle un thread. - Les threads du Java sont des tâches lightweight,
ce qui signifie quelles sont toutes executees
dans le même espace memoire. - Pour définir une classe contenant une méthode de
type run, on peut définir une sous-classe de la
classe prédéfinie thread et remplacer sa methode
run par une nouvelle methode.
26Le Classe Thread
- Dans la classe Thread, il y a deux méthodes
predefinies run et start. Le code de la méthode
run décrit les actions de Thread. La méthode
start commence sa thread comme unité concourante
en appelant sa méthode run. - Quand un programme a des threads multiples, un
scheduleur doit déterminer quels threads
sexecuteront à quel moment. - La classe Thread fournit plusieures méthode pour
le control de l'exécution des threads - yield demande a un thread en exécution de
rendre le processeur - sleep bloque un thread pendant un nombre
specifié de millisecondes - join force une méthode a retarder son exécution
jusqu'à ce qu'une autre thread ait accompli son
exécution - interrupt envoie un message à un thread, le
forcant a terminer.
27Priorité des Threads
- Les threads peuvent avoir différentes priorités.
- La priorité de défaut d'une thread est la meme
que celle de la thread qui l'a créée. - La priorité d'une thread peut être changée en
utilisant la méthode setPriority. getPriority
retourne la priorité actuelle d'une thread. - Quand il y a des threads a différentes priorités,
le comportement du scheduleur est commandé par
ces priorités. Une thread a priorité inférieure
sera executee seulement sil ny a pas de thread
a priorité plus élevée dans la file d'attente
quand une occasion se présente.
28Synchronisation de competition en Java I
- En Java, la synchronisation de competition est
implantee en indiquant quune méthode ayant accès
à des données partagées doit avoir finie son
execution avant qu'une autre méthode soit
exécutée sur le même objet. - Ceci est fait en ajoutant le modificateur
synchronized à la définition de la méthode. - Class ManageBuf
- Private int 100 buf
-
- Public synchronized void deposit (int item)
- Public synchronized void fetch (int item)
-
-
- Un objet dont les méthodes sont toutes
synchronisées correspond a un moniteur.
29Synchronisation de competition en Java II
- Un objet peut avoir plus dune méthode
synchronisée il peut egalement avoir une ou
plusieures méthodes non synchronisees. - Si pour une méthode particulière, seul une petite
partie des instructions emploient la structure de
données partagée, on peut employer une
instruction synchronisée seulement pour la partie
du code qui emploie la structure de données
partagée - Synchronize (expression)
- instructions(s)
- Remarque l'expression évaluee correspond à un
objet - Les objets a méthodes synchronisées doivent avoir
une file d'attente liée à eux, pour stocker les
méthodes synchronisées qui ont essayé de
sexecuter sur eux.
30Synchronisation de Coopération en Java
- La synchronisation de coopération en Java emploie
trois méthodes définies dans Object, la classe
souche du Java. Ce sont les methodes suivantes - wait() chaque objet a une liste d'attente
contenant toutes les threads qui ont appelé
wait() sur l'objet. - notify() est employé pour dire a un thread en
attente que l'événement qu'il attendait s'est
produit. - notifyall() réveille toutes les threads de la
liste d'attente de l'objet, commençant leur
exécution juste aprés leur appel a wait().
Notifyall est souvent employé a la place de
notify. - Ces trois méthodes peuvent seulement etre
appelees de linterieur d'une méthode
synchronisée car elles utilisent la serrure
placée sur un objet par une telle méthode
31Un Exemple Java
- Voir le Manuel pp. 588-590
32Évaluation du Parallelisme en Java
- Le parallelisme en Java est relativement simple
mais efficace. - Cependant, puisque les threads du Java sont
lightweight, elles ne permettent pas aux tâches
d'être distribuées sur des processeurs dotés de
mémoires différentes, qui pourraient même se
trouver sur des ordinateurs différents localisés
a différents endroits . - C'est la que limplementation du parallelisme
plus compliquée de l'ADA a des avantages par
rapport à celle du Java.