Université de Provence MASTER INFORMATIQUE Programmation Parallèle et Distribuée 2010-2011 Programmation Parallèle et Distribuée Partiel jeudi 10 mars 2011 2h00 Aucun document autorisé. Les réponses doivent être argumentées. Les parties sont indépendantes. Le barème est indicatif. Le sujet est composé de 4 pages + 2 pages d annexe. 1 Questions de cours (4,5 points) a) Qu est-ce-qu une machine PRAM? Préciser les différents modes d accès possibles à la mémoire partagée. (1 point) b) Qu est-ce qu un sémaphore? (1 point) c) Expliquer en une douzaine de lignes ce qu est un objet distant et les objectifs et principes de fonctionnement de Java RMI. (1,5 points) d) Quel est le rôle d un rmiregistry? (1 point) 2 Multiplication avec des PRAM (4 points) a) Étant donné un tableau d entiers T de taille n on cherche à calculer la multiplication de tous les éléments du tableau ( n i=1 T [i]). Donner un algorithme CREW efficace en pseudo-code pour une machine PRAM à n processeurs effectuant ce produit. (3 points) Solution : pour chaque proc i en parallèle { tant que ( il existe processeur i tel que next[i]!= NULL ) { si (next[i]!= NULL ) { T[next[i]] = produit(t[i], T[next[i]]) next[i] = next[next[i]] // saut de pointeur 1
Si i == taille(t)-1 alors résultat=t[taille(t)-1] b) Quelle est la complexité de votre algorithme de multiplication (donner la complexité avec la notation O)? Quelle est sa complexité totale? (1 point) Solution : On note n la taille du tableau en entrée. La complexité de l algorithme est O(log n). Sa complexité totale est O(n log n). 3 Algorithme Java (6 points) On considère le code java suivant : public c l a s s Mystery extends Thread{ s t a t i c AtomicInteger counter=new AtomicInteger ( 0 ) ; Random r= new Random ( ) ; public Mystery ( ) { / / e n d o r t l e t h r e a d de 1 à 100 m i l l i s e c o n d e s public void pause ( ) { i n t time=r. n e x t I n t ( 1 0 0 ) + 1 ; sleep ( time ) ; System. out. p r i n t l n ( Temps + time ) ; catch ( InterruptedException i e ){ System. out. p r i n t l n ( Thread interrompu + counter. get ( ) ) ; public void run ( ) { for ( i n t i =0; i <10; i ++){ i n t temp=counter. get ( ) ; counter. s e t ( temp + 1 ) ; public s t a t i c void main ( S t r i n g [ ] argv ){ Mystery thread1= new Mystery ( ) ; Mystery thread2= new Mystery ( ) ; thread1. s t a r t ( ) ; 2
thread2. s t a r t ( ) ; thread1. j o i n ( ) ; thread2. j o i n ( ) ; catch ( InterruptedException i e ){ System. out. p r i n t l n ( Thread interrompu + i e ) ; System. out. p r i n t l n ( Valeur f i n a l e : + counter. get ( ) ) ; a) À quoi sert le bloc try dans la fonction main? (1 point) Solution : La méthode join() étant bloquante, il est possible qu un autre thread essaye d interrompre le processus alors qu il est en attente à cause de l appel de join(). Dans un tel cas, le thread lance l exception InterruptedException. On doit donc mettre l appel de join() dans un bloc try pour capturer l exception. b) Quel est le nombre maximum de Threads pouvant s exécuter en parallèle lors d une exécution de cette fonction sur une machine avec 4 processeurs? (0,5 point) Solution : Il y a trois threads : le thread principal (main) et les deux threads lancés par celui-ci (thread1 et thread2) c) Quelle est la valeur maximale que peut afficher cette fonction? (on suppose qu aucun thread ne s arrête prématurément) (2 points) Solution : Cette fonction peut afficher une valeur de 20. Cette valeur est atteinte durant une exécution telle que la variable n est pas modifié entre la lecture et son écriture par un Thread. Entre les exécutions des lignes int temp=counter.get() ; et counter.set(temp+1) ; par un thread, l autre thread ne doit pas écrire la variable counter. C est possible dans le cas ou les pauses aléatoires sont courtes. d) Quelle est la valeur minimale que peut afficher cette fonction? (on suppose qu aucun thread ne s arrête prématurément) (2,5 points) Solution : Cette fonction peut afficher une valeur de 2. Une exécution menant à cette valeur est la suivante : (a) Le premier processus lit counter (valeur 0) (b) Le deuxième processus lit puis écrit counter neuf fois (valeur 9) (c) Le premier processus écrit counter (valeur 1) (d) Le deuxième processus lit counter (valeur 1) (e) Le premier processus lit puis écrit counter neuf fois (valeur 10). (f) Le deuxième processus écrit counter (valeur finale 2) 3
Les processus écrivent puis lisent successivement counter dix fois chacun. Cette exécution correspond bien à une exécution possible dans le cas ou la pause aléatoire entre la première lecture et écriture du premier processus est longue et que la pause aléatoire entre la dernière lecture et écriture du deuxième processus est longue. 4 Problème du Père Noël (5,5 points) On considère le problème suivant, dit du Père Noël. Le Père Noël dort au Pôle Nord tant qu il n est pas réveillé par ses neuf rênes ou par six de ses dix elfes. A son réveil, il effectue l une des actions suivantes de manière atomique : Si ce sont les rênes qui l ont réveillé, le Père Noël les harnache, remplit le traîneau de jouets et part ensuite les livrer dans le monde entier. Au retour, il permet aux rennes de se mettre en vacances. Si ce sont des elfes qui l ont réveillé, le Père Noël propose de nouvelles idées de jouets à ceux-ci. Les elfes repartent alors fabriquer des jouets avec leurs collègues. Les rênes sont prioritaires sur les elfes. On souhaite créer une classe Java PereNoel permettant de résoudre le problème. Afin de simuler le temps pris par les taches décrites (comme la distribution de jouets) vous pouvez utiliser la fonction pause() de l exercice 3. a) Écrire une méthode réveilparunrenne() qui permet aux rennes de réveiller le Père Noël. La fonction doit être bloquante tant que tous les rennes ne sont pas réunis. (1,5 points) b) Écrire une méthode réveilparunelfe() qui permet aux elfes de réveiller le Père Noël. La fonction doit être bloquante tant que le nombre d elfe requis n est pas atteint. (1,5 points) c) On souhaite maintenant avoir une version distribuée résolvant le problème avec les rennes et elfes en clients et le Père Noël comme serveur. Expliquer en une quinzaine de lignes votre solution. (2,5 points) 4
public c l a s s PereNoel { f i n a l i n t nbrennesrequis =9; f i n a l i n t nbelfesrequis =6; I n t e g e r nbrennes ; I n t e g e r nbelfes ; public PereNoel ( ) { nbrennes=new I n t e g e r ( 0 ) ; nbelfes=new I n t e g e r ( 0 ) ; occupe= f a l s e ; synchronized public void reveilparunrenne ( ) { i f ( nbrennes. incrementandget ( ) <nbrennesrequis ){ nbrennes. wait ( ) ; catch ( InterruptedException i e ){ System. out. p r i n t l n ( Thread renne interrompu + i e ) ; else { nbrennes. s e t ( 0 ) ; nbrennes. n o t i f y A l l ( ) ; synchronized public void reveilparunelfe ( ) { i f ( nbelfes. incrementandget () < nbelfesrequis ){ nbelfes. wait ( ) ; catch ( InterruptedException i e ){ System. out. p r i n t l n ( Thread e l f e interrompu + i e ) ; else { nbelfes. s e t ( 0 ) ; nbelfes. n o t i f y A l l ( ) ; 5
5 Liste chainée avec PRAM (exercice bonus) (4 points) Soit L une liste chaînée contenant n objets coloriés soit en bleu, soit en rouge. On souhaite concevoir un algorithme CREW efficace qui sépare les élément bleus des éléments rouge (c est-à-dire qui change le chainage de la liste chainée de départ pour qu elle ne contiennent que des objets bleus). Pour cet algorithme, on supposera que l on a autant de processeurs que la taille de la liste et que chaque processeur a accès à l élément i de la liste avec la liste(i), la couleur de l élément i avec couleur(i) (renvoyant une couleur : bleu ou rouge) et le pointeur de chainage de la liste avec suivant(i) (renvoyant le numéro de l élément suivant) a) Donner le pseudo-code de l algorithme. (3 points) b) Quelle est la complexité de votre algorithme? (donner la complexité avec la notation O) (1 point) 6