• Aucun résultat trouvé

Respect continu des invariants de coh´erence

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.