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 —