INTRODUCTION À LINDA
Transcription
INTRODUCTION À LINDA
INTRODUCTION À LINDA 1. REMARQUE PRÉLIMINAIRE PRÉAMBULE Linda n'est pas un langage de programmation mais uniquement un langage de coordination qui définit un modèle de communication et de synchronisation. Ce modèle se veut indépendant des langages de programmation et indépendant des machines parallèles existants ou futurs. Mais il est bien clair qu'une telle généralité ne peut pas être atteinte. De l'avis même des auteurs, ce modèle est plus ou moins lié aux langages de programmation C et Fortran et aux machines parallèles asynchrones existantes aujourd'hui telles que les machines MIMD avec ou sans mémoire partagée (cf. [CG 90], notamment pages 20 et 39). Le modèle Linda n'est certes pas la solution à tous nos problèmes de programmation parallèle. Il mérite cependant que nous nous y attardons un petit peu. Linda est issu des innombrables travaux de recherche des années 85 se souciant de définir des modèles de programmation plus ou moins indépendants des • • machines parallèles et langages de programmation existants et futurs. Il n'est pas étonnant qu'à l'heure actuelle une entreprise aussi ambitieuse ne puisse qu'aboutir à une solution partielle, voire insatisfaisante. Cette relative indépendance de tout langage de programmation a évidemment comme avantage que le langage de programmation d'accueil peut tout aussi bien être: Mais quel dommage que Carriero et Gelernter, les auteurs de Linda, ne se soient pas donnés la peine de définir proprement leur modèle! Et ceci ni dans [CG 89] où ils ont manifestement la prétention «d'être les meilleurs», ni dans [CG 90] où ils se donnent pourtant la peine d'exhiber une méthodologie de programmation parallèle «orientée CLinda». • • • • L'auteur de ces notes de cours ne prétend pas du tout remédier à ces lacunes, mais uniquement clarifier quelque peu la frontière floue entre le défini et le non défini du modèle Linda. Fribourg, le 31 mai 1991 un langage procédural (p. ex. de la famille C, Pascal, Modula2, Ada); un langage déclaratif (p. ex. de la famille des langages de la programmation logique tel Prolog); un langage fonctionnel (p. ex. Common Lisp, Scheme); un langage objectal (p. ex. Simula 67, Smalltalk, C++, Eiffel). Cette universalité a toutefois comme grave désavantage que certaines notions importantes (telles la notion de variables ou le mécanisme d'unification pourtant intimement lié au modèle Linda) ne peuvent pas être définies dans le modèle Linda. Elles ne peuvent être définies ou contraintes que par le langage de programmation d'accueil. Béat Hirsbrunner On peut alors à juste titre se poser la question suivante: le prix de cette universalité n'est-il pas beaucoup trop élevé ou en d'autres termes ne vaudrait-il pas mieux restreindre et préciser la sémantique du modèle Linda afin de permettre au minimum la preuve de programme telle que le permet par exemple le modèle CSP de Hoare ? PLAN 1. Remarque préliminaire 2. Définition de Linda 3. Définition d'un tuple 4. Définition d'un anti-tuple 5. Définition des opérations de lecture d'un tuple 6. Définition des opérations de retrait d'un tuple 7. Définition des opérations de rajout d'un tuple 8. Définition du mécanisme d'unification 9. Exemple 1: calcul des nombres premiers ≤ n 10. Exemple 2: problème des philosophes Références 2. DÉFINITION DE LINDA Linda est un modèle de mémoire composé: a) d'une collection de tuples, appelée l'espace des tuples. Cet espace est souvent noté Ts. (Comme plusieurs exemplaires de tuples identiques peuvent coexister simultanément dans — 1 — Ts, il s'agit bien d'une collection et non pas d'un ensemble); coordination et donc indépendant et orthogonal à tout langage de programmation), les deux termes techniques anglais actual et formal seront respectivement traduits en français par paramètre valeur et paramètre formel. b) d'un ensemble d'opérations qui permettent de manipuler les tuples de l'espace Ts. Cet ensemble d'opérations est très restreint et contient uniquement des opérations de rajout, retrait et lecture de tuples de l'espace Ts; Remarque 1. Les anti-tuples sont utilisés par le mécanisme d'unification qui essaie toujours d'unifier un anti-tuple à un tuple. c) d'un mécanisme d'unification qui permet aux opérations définies sur l'espace Ts d'accéder aux tuples de Ts. Remarque 2. Un anti-tuple ne peut pas contenir de champs de processus. Cette restriction est imposée par la définition des opérations de lecture et de retrait de tuples. 3. DÉFINITION D'UN TUPLE Exemple. Le tuple suivant représente un anti-tuple (par convention, tout paramètre formel d'un anti-tuple est préfixé d'un point d'interrogation "?"): Un tuple est une suite finie et ordonnée de champs typés. Chaque champ contient soit une valeur typée, soit un processus. ("un anti-tuple", ? x) Un tuple qui ne contient que des valeurs typées est appelé un tuple de données. Un exemple d'un tuple de données qui contient deux champs est donné par: 5. DÉFINITION DES OPÉRATIONS DE LECTURE D'UN TUPLE ("un tuple de données", 3.14159). Un tuple qui contient au moins un processus est appelé un tuple de processus. Un exemple d'un tuple de processus qui contient trois champs est donné par: • rd(a): Si il existe un tuple de données t dans l'espace des tuples Ts qui s'unifie avec l'anti-tuple a alors les paramètres valeurs de t sont assignés aux paramètres formels de a et le processus appelant reprend son exécution sinon le processus appelant est suspendu. L'unification et par conséquent l'activation du processus appelant sont garanties dans un temps fini et équitable à partir du moment où une unification devient possible. ("un tuple de processus", cos(x), sin(x)). Un tuple de données est une entité passive. Un tuple de processus par contre est une entité active qui échange des données en générant, lisant et consommant des tuples de données. Dès qu'un tuple de processus a terminé son exécution il se transforme en un tuple de données (non distingable des autres tuples de données). Les tuples de processus s'exécutent en parallèle. 4. DÉFINITION D'UN ANTI-TUPLE Si au moment de l'activation de l'unification, plusieurs tuples peuvent s'unifier avec l'anti-tuple a, une unification au hasard est choisie. On suppose que ce choix est fait de manière équitable. Un anti-tuple est une suite finie et ordonnée de champs typés. Chaque champ contient soit une valeur typée, soit une place libre typée susceptible d'accueillir une valeur du même type. De même si à un moment donné plusieurs anti-tuples en attente d'une unification peuvent s'unifier avec un tuple t, alors une des unifications possibles est choisie au hasard. On suppose de nouveau que ce choix est fait de manière équitable. Terminologie. En anglais un champ du premier type est appelé un actual (au sens français d'existant ?) et un champ du deuxième type un formal (au sens français de paramètre formel ?). Au risque de faire de malheureuses confusions avec un quelconque langage de programmation (rappelons que Linda se veut être un langage de Remarque 1. La sémantique exacte du terme équitable n'est pas définie par le modèle Linda. Il en est de même pour le concept de — 2 — l'activation de l'unification. 7. DÉFINITION DES OPÉRATIONS DE RAJOUT D'UN TUPLE Remarque 2. L'appel de rd(a) est «équivalent» à un appel de procédure bloquant. • out(t): Le tuple t est d'abord évalué, puis rajouté à l'espace des tuples. Le processus appelant reprend ensuite son exécution. • rdp(a): Idem à rd(a) mais non bloquant. Plus précisément: Remarque. Plusieurs tuples identiques peuvent donc coexister simultanément dans l'espace des tuples. Dans ce sens la structure de l'espace des tuples est bien une collection et non pas un ensemble. Si il existe un tuple de données t dans l'espace des tuples Ts qui s'unifie avec l'anti-tuple a alors les paramètres valeurs de t sont assignés aux paramètres formels de a, rdp retourne la valeur 1 au processus appelant et le processus appelant reprend son exécution sinon aucune unification n'a lieu, rdp retourne la valeur 0 au processus appelant et le processus appelant reprend son exécution. • eval(t): Un processus p permettant d'évaluer le tuple t est créé. Lorsque ce processus est créé, le processus appelant reprend immédiatement son exécution. Le processus p ainsi créé s'exécute en parallèle avec tous les autres processus se trouvant dans le système. Aussi longtemps que le tuple t n'est pas évalué, ce tuple est considéré comme un tuple de processus. Il se transforme en un tuple de données dès que le processus p termine son exécution. Remarque. L'appel de rdp(a) est «équivalent» à un appel de procédure non bloquant. On peut aussi considérer l'appel de rdp(a) comme un appel classique de procédure dans un langage de programmation procédural qui retourne au processus appelant la valeur 1 en cas de succès et la valeur 0 en cas d'échec. Remarque. Si le tuple t contient n champs de processus, le modèle Linda ne précise pas si l'appel eval(t) crée en fait 1 ou n+1 processus. En C-Linda il est précisé que ce sont n+1 et non pas 1 processus qui sont créés. 6. DÉFINITION DES OPÉRATIONS DE RETRAIT D'UN TUPLE 8. DÉFINITION DU MÉCANISME D'UNIFICATION • in(a): Le modèle Linda ne précise pas le mécanisme d'unification. Cette notion doit être définie lors de la réalisation de Linda dans un langage de programmation donné. A titre d'exemple on peut trouver une réalisation de Linda dans un environnement du langage de programmation C dans l'annexe A de [CG 90]. Idem à rd(a) mais le tuple t, qui a été unifié à l'anti-tuple a, est retiré de l'espace des tuples. • inp(a): Idem à rdp(a) mais si un tuple t a été unifié à l'anti-tuple a alors ce tuple t est retiré de l'espace des tuples. — 3 — 9. EXEMPLE 1: CALCUL DES NOMBRES PREMIERS ≤ N 10. EXEMPLE 2: PROBLÈME DES PHILOSOPHES Une solution en pseudo code "Pascal-Linda" est donnée par la figure 1. Cette solution utilise le fait que i est un nombre premier si et seulement si i n'est pas divisible par j, où j est un nombre premier quelconque plus petit que la racine carré de i. Le problème est le suivant: une table ronde est dressée avec n assiettes, une baguette entre chaque deux assiettes et un bol de riz au milieu; il y a aussi n philosophes assis autour de la table; chaque philosophe est dans un cycle infini de «penser - manger»; pour pouvoir manger un philosophe a besoin des deux baguettes qui se trouvent à côté de son assiette; afin de ne pas affamer ses collègues, il repose les baguettes à leur place chaque fois après avoir mangé. Une solution bien plus efficace utilisant le même algorithme de base est discutée dans [CG 90], chapitre 5.2. (Indication: l'inefficacité de la solution de la figure 1 est essentiellement due à une granularité de parallélisme trop fine). Une solution en pseudo code "Pascal-Linda" est donnée par la figure 2. L'abscence d'interblocage est assurée par la contrainte supplémentaire que pour manger, un philosophe a encore besoin d'un ticket et qu'au total seul n-1 tickets sont disponibles. Exercice: le lecteur est vivement invité à exprimer, dans son langage de programmation préféré, une solution analogue à celle de la figure 1. L'équité et l'abscence de famine sont assurées par l'équité définie au niveau du mécanisme d'unification. (Si cette équité n'était pas réalisée à ce niveau, alors un philosophe lent pourrait systématiquement se faire piquer ses baguettes par ses voisins plus rapides). Le problème est de trouver tous les nombres premiers entre 1 et n. % création de n-1 tuples de processus, % un par nombre entier ≤ n for i := 2 to n do eval("nombre premier", i, est_premier(i)); end for; % création de n baguettes, n philosophes et % n-1 tickets for i := 1 to n do out("baguette", i); eval(philosophe(i)); if i < n then out("ticket") end if; end for; % lecture des nombres premiers ≤ n for i := 2 to n do rd("nombre premier", i, ? ok); end for; % définition d'un philosophe procedure philosophe(i:integer); begin loop forever penser; in("ticket"); in("baguette", i); in("baguette", (i+1) div n); manger; out("baguette", i); out("baguette", (i+1) div n); out("ticket"); end loop; end philosophe; % définition de la procédure est_premier procedure est_premier(i:integer) : boolean; var j: integer; begin for j := 2 to sqrt(i) do rd("nombre premier", j, ? ok); if ok and (i mod j = 0) then return false end if; end for; return true; end est_premier; Figure 2. Une solution en pseudo "Pascal-Linda" au problème des philosophes. Figure 1. Une solution en pseudo "Pascal-Linda" au problème des nombres premiers n. — 4 — RÉFÉRENCES [CG 89] [CG 90] Nicholas Carriero, David Gelernter : "Linda in context"; Communications of ACM, vol. 32 (n° 4, April 1989) p. 444-458. Nicholas Carriero, David Gelernter : "How to write parallel programs: a first course"; The MIT Press, 1990. — 5 —