3.6 Conclusion
4.1.3 Respect continu des invariants de coh´erence
4.1.3.1 Introduction
On a vu qu’un des probl`emes de concurrence venait du fait que les donn´ees pouvaient passer par des ´etats incoh´erents. Nous d´efinissons ici formellement cette notion de coh´erence des donn´ees, et analysons comment la coh´erence peut ˆetre continuellement respect´ee (dans le cas o`u il n’y a qu’un seul ´ecrivain).
Il y a plusieurs applications `a cela. Le respect continu d’invariants est souvent une condition n´ecessaire8
pour assurer la coh´erence lorsqu’il y a ´ecritures et lectures de mˆeme donn´ees en parall`ele. Ainsi, mˆeme si cette technique demande de s´erialiser les ´ecritures (par exemple avec un lock classique), les lectures peuvent ˆetre faites en parall`eles.
Une autre application est pour l’utilisation des revocable lock, vu plus tard. La terminaison de l’ex´ecution de sections critiques couvertes par ces locks n’est pas garantie ; donc ils doivent laisser la m´emoire dans un ´etat coh´erent.
Nous avons utilis´e extensivement ces propri´et´es pour obtenir le syst`eme de m´emoire virtuelle parall`ele ; dans ce cas les « lecteurs » sont les processeurs directe- ment lorsqu’ils acc`edent aux tables des pages.
4.1.3.2 Forme canonique des pr´edicats sur les donn´ees
On d´efinit un invariant de coh´erence comme un pr´edicat sur des adresses (i.e. de variables). Un ensemble d’adresses est coh´erente si tous les invariants de coh´erences sur ces adresses sont vrais.
Le mat´eriel permet la modification d’un mot de mani`ere atomique ; ainsi tout invariant portant sur un seul mot peut ˆetre facilement respect´e.
Soit a et b deux ensembles d’adresses disjointes ; et Paet Pb des pr´edicats portant
sur les valeurs possibles de resp. a et b. On peut ´ecrire un pr´edicat compos´e Pa∪b
`a l’aide d’une formule logique sur Pa et Pb. Il est clair que tout pr´edicat portant
sur un ensemble de donn´ees a ∪ b peut s’´ecrire comme la composition inductive de pr´edicats sur des ensembles de donn´ees a et b disjoints et strictement plus petits.
Nous analysons maintenant comment un pr´edicat Pa∪b(d) compos´e des 2 pr´edicats
Pa(a) et Pb(b) peut rester vrai, quand Pa(a) et Pb(b) changent suite aux modifications
de a et b. La Table 4.1 donne une liste des compositions possibles de Pa(a) et Pb(b) ;
4.1.3. Respect continu des invariants de coh´erence Pa(a) = 0 Pb(b) = 0 Pa(a) = 0 Pb(b) = 1 Pa(a) = 1 Pb(b) = 0 Pa(a) = 1 Pb(b) = 1 Formule ´equivalente 0 0 0 0 0 0 0 0 1 Pa(a) ∧ Pb(b) 0 0 1 0 Pa(a) ∧ ¬Pb(b) 0 0 1 1 Pa(a) 0 1 0 0 ¬Pa(a) ∧ Pb(b) 0 1 0 1 Pb(b) 0 1 1 0 Pa(a) ⇐⇒ ¬Pb(b) 0 1 1 1 ¬Pa(a) ⇒ Pb(b) 1 0 0 0 ¬Pa(a) ∧ ¬Pb(b) 1 0 0 1 Pa(a) ⇐⇒ Pb(b) 1 0 1 0 ¬Pb(b) 1 0 1 1 ¬Pa(a) ⇒ ¬Pb(b) 1 1 0 0 ¬Pa(a) 1 1 0 1 Pa(a) ⇒ Pb(b) 1 1 1 0 Pa(a) ⇒ ¬Pb(b) 1 1 1 1 1
Tab. 4.1 – Ensemble des compositions possibles de 2 pr´edicats.
ces compositions peuvent ˆetre regroup´ees (Pa(a) et Pb(b) jouant des rˆoles sym´etriques,
tout comme Pa(a) et ¬Pa(a), Pb(b) et ¬Pb(b)).
• Cas 0 : Pa∪b ne peut jamais ˆetre satisfait.
• Cas 1 : Pa∪b est toujours satisfait.
• Cas Pa(a) : Pa(a) doit toujours ˆetre satisfait, et Pb(b) est inutile. Notons que
ces trois premiers cas ne sont pas vraiment des compositions.
• Cas Pa(a) ∧ Pb(b) : les deux pr´edicats doivent chacun ˆetre toujours satisfaits,
ind´ependamment l’un de l’autre. Ainsi, toute modification de a ou de b doit continuellement respecter resp. Pa(a) ou Pb(b).
• Cas Pa(a) ⇒ Pb(b) : pour satisfaire Pa∪b, il est possible de ne pas respecter
l’un ou deux des deux pr´edicats. Cependant, il est interdit de passer par l’´etat Pa(a) ∧ ¬Pb(b), ce qui implique que les modifications doivent se faire dans un
certain ordre (Figure 4.1).
• Cas Pa(a) ⇐⇒ Pb(b) : les deux pr´edicats doivent tous les deux ˆetre simul-
tan´ement satisfaits, ou simultan´ement insatisfaits. Cependant, comme a et b sont `a des adresses disjointes, passer d’un ´etat `a l’autre implique de passer par l’un des ´etats interm´ediaires Pa(a) ∧ ¬Pb(b) ou Pb(a) ∧ Pb(b) qui sont tous
les deux interdits. On ne peut donc pas passer d’un ´etat `a l’autre, comme le monter la Figure 4.1 ; ce qui fait que ce cas se ram`ene au cas Pa(a) ∧ Pb(b). Le
¬Pa(a) ∧ Pb(b) Pa(a) ∧ Pb(b) ¬Pa(a)∧¬Pb(b) modifie a modifie a modifie b modifie b Pa→ Pa ¬P(b) → ¬P (b)
Fig. 4.1 – Ordre des modifications qui respectent l’invariant Pa(a) ⇒ Pb(b).
fait que cette composition n’est pas utilisable est l’inconv´enient majeur par rapport aux sections critiques habituelles.
En utilisant la forme canonique des invariants, il est ainsi possible de savoir si un invariant de coh´erence peut ˆetre ou non continuellement respect´e.
´
Equivalences cach´ees Il faut prendre garde `a ce que nous appelons des “´equivalence cach´ees”. C’est `a dire que si l’invariant est Pa(a) ⇒ Pb(b), il faut que l’´etat
¬Pa(a) ∧ Pb(b) soit explicitement autoris´e.
Par exemple, on ne peut ´ecrire l’invariant i = j sous forme canonique ainsi : ∀n, i= n ⇒ j = n
Si on appelle Pnle pr´edicat i = n, et Pn′ le pr´edicat j = n, il est en fait impossible
d’avoir ¬Pn∧ Pn′ : si i = m 6= n, alors en appliquant Pm ⇒ Pm′ on a forc´ement
j = m. Ainsi, il faut ´ecrire l’invariant comme :
∀n, i= n ⇐⇒ j = n
Par la suite, nous supposons avoir retir´e toutes les ´equivalences cach´ees. 4.1.3.3 Pratique : affaiblissement des invariants
Certaines propri´et´es ne peuvent donc pas ˆetre assur´ees de mani`ere continue, d`es qu’il y a une ´equivalence `a assurer. Nous voyons maintenant diff´erents moyens par lesquels ces contraintes peuvent ˆetre contourn´ees. On peut g´en´eralement modifier les invariants afin de les mettre sous la bonne forme, ce que nous appelons affaiblissement des invariants.
Copie partiellement synchronis´ee Ainsi, tout invariant de la forme f (a) = g(b), o`u a et b sont des ensembles d’adresses disjoints, s’´ecrit sous forme canonique
∀n, f(a) = v ⇐⇒ g(b) = v
et ne peut ˆetre assur´e par un revocable lock. Par contre, on peut souvent transformer ces invariants en :
∀v 6= 0, f(a) = v ⇒ g(b) = v
I.e., soit a contient une copie de b, soit a n’est pas synchronis´e avec b. Ce dernier invariant peut ˆetre respect´e de mani`ere continue.
4.1.3. Respect continu des invariants de coh´erence
In´egalit´e Les ´egalit´es ne peuvent pas ˆetre continuellement respect´ees, mais les in´egalit´es le peuvent. I.e. l’invariant
s = |{ x ∈ B | P (x) }| ne peut ˆetre respect´e, au contraire de l’invariant
s ≥ |{ x ∈ B | P (x) }| que l’on ´ecrit sous forme canonique par :
∀n, s≥ n ⇒ |{ x ∈ B | P (x) }| ≤ n
Pour respecter cet invariant, il faut que les modifications `a s et B soient faites dans cet ordre :
s++ |{ x ∈ B | P (x) }|--
|{ x ∈ B | P (x) }|++ s--
En g´en´eral, on a envie que l’invariant avec in´egalit´e soit continuellement respect´e, mais sans ´eviter que s soit compl`etement en d´ecalage par rapport `a ce qu’il repr´esente. On peut s’assurer de cela lorsqu’on a un m´ecanisme qui donne une garantie de terminaison, comme la section non pr´eemptible ou le rollforward lock (ou le lock classique). s et sa valeur sont donc seulement temporairement en d´ecalage, et ce d´ecalage ne peut ˆetre que d’un seul cot´e.
On utilise cette propri´et´e pour des compteurs de r´ef´erences, par exemple pour le compteur du nombre de fois o`u est mapp´e une page en m´emoire : ce compteur est toujours sup´erieur au nombre de mappings effectifs. Ainsi, si ce compteur est `a 0, cela signifie que la page n’est pas mapp´ee. L’annexe C.2.2.1 pr´esente ce probl`eme et son impl´ementation en d´etail.
Indicateur de validit´e Si on veut ne pas respecter un pr´edicat Pbsur un ensemble
de donn´ees b de mani`ere temporaire, il suffit de trouver un ensemble de donn´ees a et un pr´edicat Pa tel que Pa(a) soit faux quand Pb l’est. Le plus simple pour cela
est que a soit un bool´een : si a est vrai, b est coh´erent, sinon b peut ne pas l’ˆetre. apeut ˆetre plac´e dans le mˆeme mot que le verrou pour gagner de la place. Cette technique est tr`es souvent utilisable. Le 2-handed ´emulation de Greenwald [GC96] en est une application.
4.1.3.4 Conclusion
On peut souvent trouver des moyens pour respecter un invariant de mani`ere continue, ce qui est souvent utile dans les programmes parall`eles. Cela permet souvent de ne pas utiliser de primitives de synchronisation (en particulier cela aide pour faire les lectures parall`element aux ´ecritures), ou des primitives plus l´eg`eres pour les ´ecritures. Ces primitives sont ´etudi´ees dans la section suivante.