Logiques de programmes, quatri`eme cours
Parall ´elisme `a m ´emoire partag ´ee : la logique de s ´eparation concurrente
Xavier Leroy 2021-03-25
Coll`ege de France, chaire de sciences du logiciel [email protected]
Introduction : Le calcul parall `ele
`a m ´emoire partag ´ee
Le calcul parall `ele
Faire travailler ensemble plusieurs unit´es de calcul (CPU) pour effectuer une tˆache plus rapidement.
Deux principales modalit´es du parall´elisme :
`a m´emoire partag´ee `a m´emoire distribu´ee
bus CPU CPU CPU CPU
RAM
r´eseau CPU
RAM
CPU RAM
CPU RAM
CPU RAM De nombreuses r´ealisations combinant les deux mod`eles : multicœurs, multiprocesseurs, GPU,clusters,grids,cloud, . . .
Quelques dates dans l’histoire du calcul parall `ele
1962 Premier multiprocesseur sym´etrique : le Burroughs D825 (1 `a 4 CPUs partageant 1 `a 16 modules m´emoire).
1965 D´ebut du projet Multics, le premier syst`eme d’exploitation moderne avec support pour multiprocesseurs.
1973 Xerox Parc : stations de travail Alto + r´eseau Ethernet.
Premier gros calcul distribu´e (rendu d’images).
1999 Lancement de SETI@home et de Folding@home, deux ´enormes calculs distribu´es sur Internet .
2006 Premiers processeurs multicœursgrand public (Intel Core Duo et AMD Athlon 64 X2).
2012 (environ) Tous les processeurs pour PC, tablettes et smartphones sont multicœurs.
Le parall ´elisme `a m ´emoire partag ´ee
Int´erets :
• Tous les processeurs ont acc`es direct `a toutes les donn´ees.
• Pas de duplication des donn´ees.
• Communications tr`es rapides (via des zones de m´emoire partag´ee).
Difficult´es :
• Risque d’interf´erence entre les actions des processeurs.
• En particulier : les courses critiques (race conditions).
Course critique (race condition)
Plusieurs acc`es simultan´es `a la mˆeme case m´emoire, dont au moins un acc`es en ´ecriture.
Cas 1 : deux ´ecritures simultan´ees.
set(`,1) set(`,2)
Le programme ne contrˆole pas quelle valeur finit dans la case`. Cas 2 : ´ecriture et lecture simultan´ees
set(`,1) letx=get(`)
Le programme ne contrˆole pas quelle valeur est lue dansx.
Un exemple de course critique
x:=x+1 x:=x+1
Compil´e en 3 instructions (lecture, calcul, ´ecriture) : lett=get(&x)in
lett=t+1in set(&x,t)
lett=get(&x)in lett=t+1in set(&x,t)
Un exemple de course critique
x:=x+1 x:=x+1
Une ex´ecution possible : lett=get(&x)in lett=t+1in set(&x,t)
lett=get(&x)in lett=t+1in set(&x,t) Avecx=0 initialement, on termine surx=2.
Un exemple de course critique
x:=x+1 x:=x+1
Une autre ex´ecution possible : lett=get(&x)in lett=t+1in
lett=get(&x)in set(&x,t)
lett=t+1in set(&x,t) Avecx=0 initialement, on termine surx=1.
Un exemple plus r ´ealiste
La partieproducteurd’un sch´ema producteur/consommateur : chaque processus produit des donn´eesxet les stocke dans un tampon partag´eT(un tableau de tailleNindex´e pari).
whilei≥Ndo pause();
T[i] :=x; i:=i+1;
Un exemple plus r ´ealiste
Avec deux producteurs en parall`ele :
whilei≥Ndo pause();
whilei≥Ndo pause();
T[i] :=x1; i:=i+1; T[i] :=x2; 8
i:=i+1;
Risque d’acc`es hors borne dans le tableau (sii=N−1 initialement).
Un exemple plus r ´ealiste
Avec deux producteurs en parall`ele :
whilei≥Ndo pause();
whilei≥Ndo pause();
T[i] :=x1;
T[i] :=x2; i:=i+1; i:=i+1;
Une des deux donn´eesx1,x2est perdue.
L’entr´eeT[i−1]du tableau n’est pas initialis´ee.
Synchronisation par sections critiques
En Java : En C :
synchronized (obj) { pthread_mutex_lock(mut);
... ...
} pthread_mutex_unlock(mut);
Garantissent l’exclusion mutuelle: `a tout moment au plus un processus ex´ecute la section critique.
Exemple : un producteur bien synchronis´e.
synchronized (buff) {
while (buff.i >= N) buff.wait();
buff.T [ buff.i ] = x;
buff.i ++ ; }
Synchronisation et logiques de programmes
De nombreux m´ecanismes de synchronisation :
• exclusion mutuelle : s´emaphores, verrous, . . .
• barri`eres et vagues de calcul ;
• passage de messages ;
• instructions atomiques des processeurs ;
(→algorithmeslock-free)
Quelles logiques de programmes pourraisonner sur
l’interf´erenceetgarantir la bonne synchronisation, notamment l’absence de courses critiques?
Parall ´elisme sans partage de
ressources
Ex ´ecuter deux commandes en parall `ele
Commandes : c:=. . .
|c1kc2 ex´ecutec1etc2en parall`ele
S´emantique : unentrelacementdes r´eductions dec1etc2. (a1ka2)/h→0/h (ou toute combinaison dea1eta2)
(c1 kc2)/h→(c01kc2)/h0 sic1/h→c01/h0 (c1 kc2)/h→(c1kc02)/h0 sic2/h→c02/h0
(c1 kc2)/h→err sic1/h→errouc2/h→err
La r `egle de s ´eparation pour l’ex ´ecution parall `ele
{P1}c1{λ .Q1} {P2}c2{λ .Q2} {P1VP2}c1kc2{λ .Q1VQ2} Intuition :
• l’´etat m´emoire initialhse d´ecompose enh1]h2avech1 satisfaisantP1eth2satisfaisantP2;
• c1s’ex´ecute dansh1sans modifierh2;
• c2s’ex´ecute dansh2sans modifierh1;
• les ´etats finauxh01,h02satisfontQ1,Q2et sont disjoints.
La r `egle de s ´eparation pour l’ex ´ecution parall `ele
{P1}c1{λ .Q1} {P2}c2{λ .Q2} {P1VP2}c1kc2{λ .Q1VQ2} Autre intuition : la pr´econditionP1VP2garantit que les commandesc1etc2s’ex´ecutent sans interf´erences.
L’ex´ecution est donc s´emantiquement ´equivalente `a une ex´ecution s´equentiellec1;c2ouc2;c1.
{P1}c1{λ .Q1} {P1VP2}c1{λ .Q1VP2}
{P2}c2{λ .Q2} {Q1VP2}c2{λ .Q1VQ2} {P1VP2}c1;c2{λ .Q1VQ2}
Parall ´elisme s ´epar ´e entre sous-tableaux
Exemple : le tri Quicksort.
quicksort T l h= ifh−l≤20then
insertionsort T l h else
letm=partition T l hin
quicksort T l mkquicksort T(m+1)h quicksort T l hmodifie le sous-tableauT[l. . .h]deT.
Les deux appels r´ecursifs se font sur des sous-tableaux disjoints : T[l. . .m]etT[m+1. . .h].
On peut donc les faire soit en s´equence soit en parall`ele.
Parall ´elisme s ´epar ´e entre sous-arbres
tree(Leaf,p) =hp=NULLi
tree(Node(t1,x,t2),p) =∃p1,p2, p7→p1Vp+17→x Vp+27→p2 Vtree(t1,p1)Vtree(t2,p2) Le pr´edicat de repr´esentation garantit que les deux sous-arbres sont disjoints, et peuvent donc ˆetre parcourus et modifi´es en parall`ele.
incrtree tδ = ift6=NULL then
letl=get(t)andn=get(t+1)andr=get(t+2)in set(t+1,n+δ);
incrtree lδkincrtree rδ
Absence de courses critiques
On ajoute une r`egle `a la s´emantique par r´eductions qui signale une erreur pour toute situation de course :
(c1kc2)/h→err si Acc(c1)∩Acc(c2)6=∅
Acc(c)est l’ensemble des adresses m´emoires que la commandec peut lire ou ´ecrire `a la prochaine ´etape de r´eduction :
Acc(get(a)) =Acc(set(a,a0)) =Acc(free(a)) ={a} Acc(letx=c1inc2) =Acc(c1)
Acc(c1kc2) =Acc(c1)∪Acc(c2)
Absence de courses critiques
On montre facilement que
c/h6→err ⇒ Acc(c)⊆Dom(h)
Par cons´equent, sic1/h1 6→erretc2/h26→erreth1 ⊥h2, Acc(c1)∩Acc(c2)⊆Dom(h1)∩Dom(h2) =∅
et donc(c1kc2)/(h1]h2)ne peut pas se r´eduire enerr`a cause d’une course critique.
Le r´esultat de correction s´emantique (`a la fin de ce cours) formalise cette analyse et montre que si{P}c{Q}, la commandecs’ex´ecute sans courses critiques.
Parall ´elisme et partage de
ressources
L’ ´emergence de la logique de s ´eparation concurrente
O’Hearn, Reynolds, Yang (2001),Local Reasoning about Programs that Alter Data Structures. La pr´esentation moderne de la logique de s´eparation s´equentielle.
O’Hearn (2001–2002),Notes on separation logic for shared-variable concurrency, non publi´e.
Reynolds (2002),Separation Logic : A Logic for Shared Mutable Data Structures. Donne la r`egle de s´eparation pour le parall´elisme et mentionne les travaux en cours de O’Hearn.
O’Hearn (2004),Resources, Concurrency and Local Reasoning. Les id´ees cl´es + les principaux exemples.
Brookes (2004),A Semantics for Concurrent Separation Logic. Une s´emantique et une preuve de correction pour la logique de O’Hearn.
Les ressources partag ´ees
Une ressource se compose de
• une ou plusieurs cases m´emoire :
variables globales, objets allou´es dynamiquement ;
• un verrou (lock) ou autre dispositif d’exclusion mutuelle qui prot`ege les acc`es aux cases m´emoire.
Exemple (un compteur partag ´e) class Counter { int val; }
Exemple (une liste doublement chaˆın ´ee partag ´ee) class DList { DListCell first, last; }
class DListCell { Object data; DListCell prev, next; }
Ressources partag ´ees en logique de s ´eparation
Id´ee g´eniale de O’Hearn : une ressource partag´ee peut ˆetre d´ecrite par une assertionAde logique de s´eparation.
• L’empreinte m´emoire deAd´efinit l’ensemble des cases m´emoires appartenant `a la ressource.
• L’assertionAsp´ecifie aussi la structure de ces cases (liste doublement chaˆın´ee) et d’autres invariants.
Exemple (un compteur partag ´ep) p7→nVhn≥0i
Exemple (une liste doublement chaˆın ´eep,q)
∃x,y,w, p7→xVq7→yVdlist(w,x,y)
Sections critiques en logique de s ´eparation
L’acc`es `a une ressource partag´eerse fait uniquement dans une section critique
withrdoc
en exclusion mutuelle avec les autres processus.
NotantRIrl’assertion (l’invariant) associ´ee `a la ressourcer:
{RIr VP}c{RIr VQ} {P}withrdoc{Q}
`A l’entr´ee de la section critique, le processus acquiert la permission d’utiliser les cases m´emoire de la ressource, d´ecrites parRIr. Avant de sortir de la section critique, le processus doit r´etablir l’invariantRI car d’autres processus vont entrer en section critique.
Sections critiques conditionnelles en logique de s ´eparation
L’article original de O’Hearn consid`ere des sections critiques conditionnelles
withrwhenbdoc
o `ucest ex´ecut´e seulement lorsque la conditionbest vraie.
La r`egle pour les s.c.c. est :
{ hbiVRIr VP}c{RIr VQ} {P}withrwhenbdoc{Q}
Exemple : d ´ecr ´ementer un compteur partag ´e
L’invariant estRIr =∃n, p7→nVhn≥0i.{emp} withrdo
{ ∃n, p7→nVhn≥0i } letn=get(p)in
{p7→nVhn≥0i } ifn>0then set(p,n−1)
{ ∃n0, p7→n0 Vhn0 ≥0i } done
{emp}
Exemple : insertion dans une liste partag ´ee
L’invariant estRIr =∃q,w, p7→qVlist(w,q).{emp} withrdo
{ ∃q,w, p7→qVlist(w,q)} letq=get(p)in
{p7→qV∃w, list(w,q)} leta=cons(x,q)in
{a7→xVa+17→qVp7→qV∃w, list(w,q)} set(p,a)
{p7→aVa7→xVa+17→qV∃w, list(w,q)}
⇒{ ∃q,w, p7→qVlist(w,q)} done
{emp}
Formalisation simplifi ´ee : les sections atomiques
(Vafeiadis (2011))Commandes : c::=. . .
|c1kc2 ex´ecutec1etc2en parall`ele
|atomicc ex´ecutecenune ´etape ins´ecable Une sectionsuper-critique: pendant l’ex´ecution deatomicc, tous les autres processus sont bloqu´es et n’ex´ecutent rien.
Pertinence pratique :
• Si on fait du temps partag´e sur un unique processeur : section atomique≈bloquer temporairement la pr´eemption.
• Mod´elise desinstructions atomiquesdu processeur.
Mod ´elisation des instructions atomiques des processeurs
´Echange atomique (swap) et ses cas particuliers :
swap(p,n)def= atomic(letx=get(p)in set(p,n);x) test and set(p)def= swap(p,1)
read and clear(p)def= swap(p,0) Incr´ement / d´ecr´ement atomique :
fetch and add(p,d)def= atomic(letx=get(p)in set(p,x+d);x) Comparaison et ´echange (compare and swap) :
CAS(p,x,n)def= atomic(letc=get(p)in
ifc=xthen(set(p,n);1)else0)
S ´emantique op ´erationnelle des sections atomiques
(atomicc)/h→a/h0 sic/h→∗ a/h0 (atomicc)/h→err sic/h→∗ err
Note :atomicc1katomicc2est donc ´equivalent `ac1;c2ouc2;c1. Il n’y a pas d’entrelacement entre les ´etapes de r´eduction dec1et celles dec2.
Note : sic/hdiverge,(atomicc)/hest bloqu´ee. En pratique,cne contient pas de boucles et termine toujours.
Un
triplet
pour le parall ´elisme `a sections critiques
J ` { P } c { Q }
L’assertionJest un invariant sur la m´emoire partag´ee
(accessible uniquement dans des sections atomiquesatomicc).
La pr´econditionPet la postconditionQd´ecrivent la m´emoire propre `a la commandec.
Les r `egles pour les sections atomiques
Ex´ecution d’une section atomique :
emp` {PVJ}c{λv.Q v VJ} J` {P}atomicc{Q}
Partage d’une ressourceJ0: Encadrement sur l’invariant :
JVJ0` {P}c{Q} J` {PVJ0}c{λv.Q vVJ0}
J` {P}c{Q} JVJ0` {P}c{Q}
Les r `egles pour les structures de contrˆ ole (rappel)
P⇒Q[[a]]
J` {P}a{Q}
J` {P}c{R} ∀v, J` {R v}c0[x←v]{Q} J` {P}letx=cinc0{Q}
J` { hbiVP}c1{Q} J` { h¬biVP}c2{Q} {P}ifbthenc1elsec2{Q}
J` {P1}c1{λ .Q1} J` {P2}c2{λ .Q2} J` {P1VP2}c1kc2{λ .Q1VQ2}
Les
petites
r `egles pour les acc `es m ´emoire (rappel)
J` {emp}alloc(N) {λ`. `7→ V· · ·V`+N−17→ } J` {[[a]]7→x} get(a) {λv.hv=xiV[[a]]7→x}
J` {[[a]]7→ }set(a,a0) {λv.[[a]]7→[[a0]]} J` {[[a]]7→ } free(a) {λv.emp}
Les r `egles structurelles (attention ! pi `ege !)
J` {P}c{Q}
(encadrement)
J` {PVR}c{λv.Q v VR}
P⇒P0 J` {P0}c{Q0} ∀v, Q0v⇒Q v
(cons´equence)
J` {P}c{Q}
J` {P}c{Q} J` {P0}c{Q0}
(disjonction)
J` {P∨P0}c{λv.Q v∨Q0v} Jpr´ecise J` {P}c{Q} J` {P0}c{Q0}
(conjonction)
J` {P∧P0}c{λv.Q v∧Q0 v}
La r `egle de conjonction et le contre-exemple de Reynolds
PrenonsJ=true(l’assertionλh.>vraie de toutes les m´emoires).Soitone=17→ . On aoneVtrue⇒true, donc emp` {oneVtrue}0{λ .empVtrue} emp` {oneVtrue}0{λ .oneVtrue} et en appliquant la r`egleatomic,
J` {one}atomic0{λ .emp} J` {one}atomic0{λ .one}
Si la r`egle de conjonction ´etait vraie pour toutJ, on concluerait J` {one∧one}atomic0{λ .emp∧one}
or la postconditionemp∧oneest toujours fausse.
Les assertions pr ´ecises
Intuitivement : une assertionPestpr´ecisesi son empreinte m´emoire est d´efinie de mani`ere unique.
Formellement : siPd´ecoupe un sous-tash1dans un tashdonn´e, ce sous-tash1est d´etermin´e de mani`ere unique :
h=h1]h2=h01]h02 ∧ P h1 ∧ P h01 ⇒ h1=h01
Exemples d’assertions pr ´ecises ou non
Assertions pr´ecises Assertions non pr´ecises
emp true
`7→ ∃`, `7→
`7→v ∃`, `7→v
∃v, `7→vVR(v)
PVQ PVtrue
hbiVP∨ h¬biVQ emp∨`7→
(siP,Q,R(v)sont pr´ecises)
S ´emaphores binaires et applications
Codage des s ´emaphores binaires
Un s´emaphore binaire = une case m´emoirepqui contient 0 (signifiantnon disponible) ou 1 (signifiantdisponible).
Les op´erationsP(prendre) etV(relˆacher) : V(sem) =atomic(set(sem,1)) P(sem) =letx=swap(sem,0)in
ifx=1then0elseP(sem) avec
swap(p,n) =atomic(letx=get(p)in set(p,n);x)
Note :P(sem)fait une attente active, et peut ne pas terminer, mais la boucle est en dehors de la section atomique.
Les r `egles pour les s ´emaphores binaires
SoitRIl’assertion d´ecrivant les ressources associ´ees au s´emaphore. On suppose queRIest pr´ecise.
On prend comme invariant sur l’´etat partag´e
J(sem,RI) def= ∃n.sem7→nV(hn=0i ∨ hn=1iVRI) c’est-`a-diresi le s´emaphore est occup´e, les ressourcesRIsont dans la m´emoire partag´ee. On peut alors d´eriver :
J(sem,RI)` {RI}V(sem){emp} J(sem,RI)` {emp}P(sem){RI}
Autrement dit : donnerpc’est placerRIdans la m´emoire partag´ee, et prendrepc’est r´ecup´ererRIdepuis la m´emoire partag´ee.
Synchronisation avec un s ´emaphore
On prend l’assertionRI=∃n,x7→nVhnpremieri,
la variablexcontient un nombre premier. {sem7→0Vx 7→ } {x7→ }
set(x,53);
{x7→53}⇒{RI} V(sem) {emp}
{emp} P(sem);
{RI}
letn=get(x)in
{x7→nVhnpremieri } print(n)
LePet leVassurent que le processus droit ne lit pasxavant que le processus gauche ne l’ait initialis´e, et transf`erent la permission d’acc´eder `axdu processus gauche au processus droit.
Synchronisation et transfer de ressources avec un s ´emaphore
On prend l’assertionRI=∃p,x7→pVp7→la variablexpointe vers une adresse valide. {sem7→0Vx 7→ } {x 7→ }
letp=alloc(1)in {x 7→ Vp7→ }
set(x,p);
{x 7→pVp7→ }⇒{RI} V(sem)
{emp}
{emp} P(sem);
{RI}
letp=get(x)in {x7→pVp7→ } free(p)
{x7→ }
La m´emoire allou´ee par le processus gauche est transf´er´ee et d´esallou´ee sans risques par le processus droit.
D ´erivation de la r `egle pour
POn rappelle l’invariant sur l’´etat partag´e :
J(sem,RI) def= ∃n.sem7→nV(hn=0i ∨ hn=1iVRI) Pourswap(sem,0), on a le triplet
J(sem,RI)` {emp}swap(sem,0){λn.hn=0i ∨ hn=1iVRI} P(sem)it`ereswap(sem,0)jusqu’`a ce que le r´esultat soit 1, d’o `u
J(sem,RI)` {emp}P(sem){RI}
D ´erivation de la r `egle pour
VJ(sem,RI) def= ∃n.sem7→nV(hn=0i ∨ hn=1iVRI) Il suffit de montrer
emp` {RIVJ(sem,RI)}set(sem,1){sem7→1VRI} pour avoiremp` {RIVJ(sem,RI)}set(sem,1){J(sem,RI)} et doncJ(sem,RI)` {RI}V(sem){emp}.
Mais on ne connait pas l’´etat du s´emaphore (vide ou occup´e) : emp` {RIVsem7→0}set(sem,1){sem7→1VRI}(vide) emp` {RIVsem7→1VRI}set(sem,1){sem7→1VRI}(occup´e) Dans le 2ecas il fautRIVRI⇒RI, qui est vrai siRIest pr´ecise.
Codage des sections critiques
On peut utiliser un s´emaphore comme un verrou : Pprend le verrou,Vle rend.
D’o `u un codage simple des sections critiques : withrdoc def= P(r);c;V(r)
o `u chaque section critiquerest identifi´ee par l’adresse m´emoire d’un s´emaphore, initialis´e `a 1.
Codage des sections critiques
SiRIr est l’invariant de la ressourcer, l’invariant de m´emoire partag´ee s’obtient en prenant la conjonction des invariants des s´emaphores :
JR = r∈R
V
J(r,RIr)Ce codage valide la r`egle pour les sections critiques :
r∈ R JR\{r} ` {RIr VP}c{RIr VQ}
JR` {P}withrdoc{Q}
Codage des sections critiques conditionnelles
Dans notre langage PTR, la conditioncbd’une s.c.c. est n´ecessairement une commande qui s’´evalue en un bool´een.
withrwhencbdoc def= P(r); wait(r,cb); c; V(r) o `uwaitest la boucle suivante :
wait(r,cb) = letb=cbin
ifbthen0else(V(r); P(r); wait(r,cb)) On d´erive la r`egle suivante :
r∈ R
JR\{r}` {RIr VP}cb{λb.hbiVB∨ h¬biVRIr VP} JR\{r} ` {B}c{RIr VQ}
` { } { }
Le sch ´ema producteur/consommateur
Une g´en´eralisation de l’exemplesynchronisation et transfer de ressources, o `u plusieurs ressources sont transf´er´ees
successivement.
while true do calculerx; produce(x);
done
while true do
lety=consume()in utilisery
done
Les ressources produites mais pas encore consomm´ees sont stock´ees dans un tampon en m´emoire partag´ee.
Note : on peut avoir plusieurs processus producteurs et plusieurs processus consommateurs.
Une solution avec un tampon de taille 1 et deux s ´emaphores
Trois variables en m´emoire partag´ee :
• b: adresse du tampon (une case m´emoire)
• s1: un s´emaphore qui est `a 1 lorsque le tampon est plein (contient une donn´ee produite pas encore consomm´ee).
• s0 : un s´emaphore qui est `a 1 lorsque le tampon est vide (ne contient pas de donn´ee produite et pas encore consomm´ee)
Impl´ementation :
produce(b,s0,s1,x) = P(s0); set(b,x); V(s1)
consume(b,s0,s1) = P(s1); letx=get(b)inV(s0); x
Sp ´ecification et v ´erification du producteur/consommateur
On noteRI(x)l’invariant de ressources associ´e `a la donn´eex. Sp´ecification deproduceetconsume:J(b)` {RI(x)}produce(b,s0,s1,x){emp} J(b)` {emp}consume(b,s0,s1){λx.RI(x)}
La v´erificationpasseen prenant comme invariantJsur l’´etat partag´e
J(b) def= J(s0,b7→ )VJ(s1,∃x, b7→xVRI(x)) En d’autres termes : quand le s´emaphores0est `a 1,best valide (on peut ´ecrire dedans) ; quand le s´emaphores1est `a 1,
bcontient une donn´eexqui satisfaitRI(x).
Correction s ´emantique
Correction s ´emantique de la logique de s ´eparation concurrente
La d´emonstration originale de Brookes (2004) :
• S´emantique d´enotationnelle des commandes sous forme de traces d’actions.
• Une s´emantiquelocaledes actions et des traces qui met en
´evidence la possession des ressources et les transfers de ressources lors des sections critiques.
• Une hypoth`ese : tous les invariants de ressource sont pr´ecis.
La d´emonstration simplifi´ee de Vafeiadis (2011) :
• Raisonnement direct et ´el´ementaire sur les suites de r´eductions,
`a l’aide d’un pr´edicat compt´eSafenc h.
• Seule la r`egle de conjonction exige des invariants pr´ecis.
Quelques intuitions
J ` { P } c { Q }
Intuition d´eductive : c’est comme{PVJ}c{QVJ}
avec en plusJinvariant, c.`a.d. tous les triplets apparaissant dans la d´erivation sont de cette forme.
Intuition op´erationnelle : `a chaque ´etape de calcul, l’´etat m´emoire couranthse d´ecompose en trois parties disjointes :
h=h1]hj]hf h1est la m´emoire propre `ac.
hjest la m´emoire partag´ee accessible aux sections atomiques.
hf est la m´emoireencadrante, incluant les m´emoires propres des processus s’ex´ecutant en parall`ele avecc.
Un triplet s ´emantique faible avec comptage de pas
On d´efinit le triplet s´emantiqueJ|={{P}}c{{Q}}: J|={{P}}c{{Q}} def= ∀n,h, P h⇒Safenc h Q J Le pr´edicat inductifSafenc h Q Jsignifie que les ex´ecutions dec dans la m´emoire propreh
– ne font pas d’erreur dans lesnpremi`eres ´etapes d’ex´ecution ; – satisfontQsi elles terminent en au plusn ´etapes ;
– pr´eservent l’invariantJsur la m´emoire partag´ee.
Safe0c h Q J
Q[[a]]h Safen+1a h Q J
(∀a,c6=a) · · · Safen+1c h Q J
Un triplet s ´emantique faible avec comptage de pas
∀a,c6=a
∀hj,hf, J hj⇒c/h1]hj]hf 6→err
∀hj,hf,c0,h0, J hj∧c/h1]hj]hf →c0/h0 ⇒
∃h01,h0j, h0 =h01]h0j]hf∧J h0j∧Safenc0h01Q Safen+1c h1Q
Le cas r´ecursif :cdansh1est sˆure pourn+1 ´etapes si
• dans tout ´etathde la formeh1]hj]hf avechjsatisfaisantJ, c/hne fait pas d’erreurs, et . . .
• pour toute r´eductionc/h→c0/h0, l’´etath0se d´ecompose en h01]h0j]hf avech0jsatisfaisantJ,
et de plusc0dansh01est sˆure pourn ´etapes.
Un triplet s ´emantique faible avec comptage de pas
∀a,c6=a
∀hj,hf, J hj⇒c/h1]hj]hf 6→err
∀hj,hf,c0,h0, J hj∧c/h1]hj]hf →c0/h0 ⇒
∃h01,h0j, h0 =h01]h0j]hf∧J h0j∧Safenc0h01Q Safen+1c h1Q
Le cas r´ecursif :cdansh1est sˆure pourn+1 ´etapes si
• dans tout ´etathde la formeh1]hj]hf avechjsatisfaisantJ, c/hne fait pas d’erreurs, et . . .
• pour toute r´eductionc/h→c0/h0, l’´etath0se d´ecompose en h01]h0j]hf avech0jsatisfaisantJ,
et de plusc0dansh01est sˆure pourn ´etapes.
Un triplet s ´emantique faible avec comptage de pas
∀a,c6=a
∀hj,hf, J hj⇒c/h1]hj]hf 6→err
∀hj,hf,c0,h0, J hj∧c/h1]hj]hf →c0/h0 ⇒
∃h01,h0j, h0 =h01]h0j]hf∧J h0j∧Safenc0h01Q Safen+1c h1Q
Le cas r´ecursif :cdansh1est sˆure pourn+1 ´etapes si
• dans tout ´etathde la formeh1]hj]hf avechjsatisfaisantJ, c/hne fait pas d’erreurs, et . . .
• pour toute r´eductionc/h→c0/h0, l’´etath0se d´ecompose en h01]h0j]hf avech0jsatisfaisantJ,
et de plusc0dansh01est sˆure pourn ´etapes.
Correction s ´emantique et d ´ecompositions de l’ ´etat m ´emoire
On montre sans trop de peine que ce triplet s´emantique
J|={{P}}c{{Q}}satisfait les r`egles de la logique de s´eparation concurrente.
Voici une illustration de la d´ecompositionh=h1]hj]hf `a utiliser pour chacune des principales r`egles :
emp` {PVJ}c{QVJ} J` {P}atomicc{Q}
(h1]hj) ] ∅ ] hf h1 ] hj ] hf JVJ0 ` {P}c{Q}
J` {PVJ0}c{λv.Q vVJ0}
h1 ] (hj]h2) ] hf (h1]h2) ] hj ] hf
Correction s ´emantique et d ´ecompositions de l’ ´etat m ´emoire
J` {P1}c1{λ .Q1} J` {P2}c2{λ .Q2} J` {P1VP2}c1kc2{λ .Q1VQ2}
h1 ] hj ] (hf ]h2) ou h2 ] hj ] (hf ]h1) (h1]h2) ] hj ] hf
J` {P}c{Q} JVJ0` {P}c{Q}
h1 ] hj ] (hf ]h0j) h1 ] (hj]h0j) ] hf
J` {P}c{Q} J` {PVR}c{λv.Q vVR}
h1 ] hj ] (hf]h2) (h1]h2) ] hj ] hf
Absence de courses critiques
(c1kc2)/h→err si Acc(c1)∩Acc(c2)6=∅ Si on ajoute la r`egle d’erreur ci-dessus et que l’on prend
Acc(atomicc) =∅,
la d´emonstration de correction s´emantiquepasseencore, ce qui montre :
Toute commande c prouvable en logique de s ´eparation concurrente ne contient aucune course critique
entre acc `es m ´emoire non atomiques.
Note :atomic(set(p,1))katomic(set(p,2))est prouvable mais n’est pas consid´er´e comme une course critique.
Point d’ ´etape
Point d’ ´etape
Apr`es l’´eclair de la logique de s´eparation (2001), le coup de tonnerre de la logique de s´eparation concurrente (2004).
Par rapport aux logiques pr´ec´edentes (p.ex. Owiki & Gries, 1976), un ´enorme progr`es pour montrer des propri´et´es de sˆuret´e des calculs parall`eles :
• absence de courses critiques ;
• sˆuret´e de la m´emoire ;(pas d’acc`es apr`esfree, pas de doublefree)
• int´egrit´e des structures de donn´ees ;
• Transfers de donn´ees entre processus.
Encore du progr`es `a faire sur la correction fonctionnelle, p.ex.
{x=0}atomic(x:=x+1)katomic(x:=x+1){x=2}
Bibliographie
Bibliographie
Un livre de r´ef´erence sur le parall´elisme `a m´emoire partag´ee :
• M. Herlihy, N. Shavit.The Art of Multiprocessor Programming, Morgan Kaufman, 2012.
L’article fondateur de la logique de s´eparation concurrente (version r´evis´ee) :
• P. O’Hearn,Resources, Concurrency and Local Reasoning, Theor. Comp. Sci, 2007.
La d´emonstration simple de la correction s´emantique :
• V. Vafeiadis,Concurrent separation logic and operational semantics, MFPS 2011
M´ecanisations :
• Le d´eveloppement Coq correspondant `a ce cours :
https://github.com/xavierleroy/cdf-program-logics
• L’infrastructure Iris :