Sunteți pe pagina 1din 14

Procesare distribuit

Aceste note de curs se bazeaza pe urmatoarele texte:



1. Distributed Computing , H. Attyia & J . Welch; McGraw-Hill 1998

2. Distributed Algorithms, N. Lynch; Morgan Kaufmann 1996

3. Introduction to Distributed Algorithms, G. Tel; Cambridge University Press 1994

1. Introducere

Un sistem (de calcul) distribuit este o colecie de dispozitive de calcul individuale care comunic ntre ele.
Spre deosebire de procesarea paralel, n care scopul principal este cooperarea dintre toate procesoarele n vederea realizrii unei lucrri, n procesarea distribuit
fiecare procesor are n general propria sa agend semi-independent, dar din diferite motive (partajarea resurselor, tolerana la erori etc.) procesoarele trebuie s-i coordoneze
aciunile

.
Principalele dificulti n proiectarea sistemelor distribuite sunt:
Asincronia

timpul absolut (sau chiar relativ) la care au loc evenimentele nu poate fi cunoscut precis;
Cunoaterea local

fiecare entitate de calcul poate dispune doar de informaia pe care o primete, are doar o imagine local asupra situaiei globale;
Cderea componentelor (failures)

entitile de calcul se pot defecta independent lasnd anumite componente operaionale iar altele nu.
Procesarea distibuit i propune s realizeze ceea ce Proiectarea i Analiza algoritmilor secveniali a fcut pentru calculatoarele secveniale: evidenierea unui
cadru general pentru specificarea algoritmilor i compararea performanelor pentru nelegerea limitrilor interne ale acestora.
Se dorete indentificarea de probleme fundamentale
prin mesaje;
, abstractizri ale celor ce apar n sisteme distribuite reale, enunarea acestor probleme n mod precis, proiectarea
i analiza unor algoritmi eficieni pentru ele.
Dificultatea principal const n faptul c nu exist un model de calcul unanim acceptat i probabil nici nu va fi. Exist diferene majore ntre sistemele distribuite
depinznd de:
Modul de comunicare
prin memorie partajat;
Tipul de informaie referitor la timp i comportarea sistemului n timp;
Tipul de cderi (ale componentelor) care sunt tolerate.

n sistemele distribuite exist noi tipuri de msuri de complexitate. Pe lng timpul de execuie i spaiul de lucru (ce trebuie definite n mod corespunztor) vom fi
interesai n complexitatea de comunicare i n numrul de componente defecte ce pot fi acceptate. Exist numeroase rezultate negative, margini inferioare i rezultate de
imposibilitate. Se poate demonstra c o problem particular nu poate fi rezolvat ntr-un tip particular de sistem distribuit, sau nu se poate rezolva sub o anumit cantitate
dintr-o anumit resurs. (Astfel de rezultate joac rolul celor de NP-completitudine din algoritmica secvenial.)

2. Legtura cu practica

Dac nu cel mai simplu, cu siguran cel mai vechi exemplu de sistem distribuit este un sistem de operare pentru calculatoare secveniale convenionale. Procesele
de pe acelai hard comunic utiliznd acelai soft sau prin schimburi de mesaje, sau printr-un spaiu comun de adresare. Partajarea unei singure CPU de ctre procese multiple
ridic probleme de concuren (virtual). Multe dintre problemele ridicate de un sistem de operare apar i n alte sisteme distribuite, ca de exemplu excluderea mutual,
detectarea i prevenirea dead-lockului.

Mainile MIMD cu memorie partajat sunt puternic interconectate (tightly coupled) i sunt numite uneori multiprocesoare. Acestea constau din componente hard
separate executnd un soft comun. Conectarea se face printr-un bus sau, mai puin frecvent, printr-o reea cu comutatori. Mainile MIMD pot fi i slab interconectate (loosley
coupled) i nu au memorie comun. Ele pot fi o colecie de staii de lucru dintr-o reea local sau o colecie de procesoare ntr-o reea cu comutatori.

Sistemele distribuite i mai puin interconectate pot fi constituite din gazde autonome ntr-o reea local (ca de exemplu Ethernet) sau chiar WAN (cum ar fi
Internet). n acest caz, avem componente hard separate executnd soft separat dei entitile interacioneaz prin interfee bine definite ca de exemplu TCP/IP, CORBA sau ale
groupware sau middleware.

Dup modul de comunicare i gradul de sincronizare vom considera trei modele principale:
1. Modelul asincron cu memorie partajat;
2.
este reprezentat de mainile puternic cuplate n situaia comun n care procesoarele nu-i iau semnalul de ceas de la
o singur surs;
Modelul asincron cu transmitere de mesaje;
3.
este reprezentat de mainile puin cuplate i WAN;
Modelul sincron cu transmitere de mesaje;
Modelele bizantine evideniaz preocuprile legate de posibilitatea de defeciune a anumitor componente.

este o idealizare a sistemelor bazate pe transmiterea mesajelor, n care se cunoate o anumit informaie referitoare
la timp (ca de exemplu o margine superioar pentru ntirzierea mesajelor). Se poate simula un astfel de model cu sisteme mai realiste, de exemplu prin
sincronizarea ceasurilor.
4. Algoritmi de baz n sisteme de tip transmitere de mesaje

ntr-un sistem distribuit de tip MP (message passing) procesoarele comunic prin transmiterea de mesaje prin canele de comunicaie, fiecare canal realiznd o conexiune
bidirecional ntre dou procesoare.
Mulimea canalelor de comunicaie formeaz topologia sistemului
outbufi(l) pstreaz mesajele pe care pi le-a trimis vecinului su corespunztor muchiei l i care nu au fost nc transmise;
care poate fi reprezentat printr-un graf (neorientat) n care nodurile sunt procesoarele iar muchiile
sunt canalele de comunicaie.
Sistemul fizic de interconectare reprezentat de topologia sistemului este referit i ca reea.

Un algoritm pentru un sistem distribuit de tip MP const dintr-un programlocal pentru fiecare procesor din reea. Programul local permite procesarea local precum i
transmiterea i recepionarea de mesaje de la fiecare din procesoarele vecine n topologia dat.

Un sistem distribuit de tip MP const din n procesoare: p0, p1, p2, , pn-1.
Fiecare procesor pi este modelat ca o main cu stri, cu mulimea strilor Qi (finit sau infinit).
Fiecare procesor va fi identificat cu un nod n reea. Muchiile incidente cu procesorul pi sunt numerotate 1, 2, ,v (v fiind gradul nodului pi).
Orice stare a procesorului pi are 2v componente speciale: outbufi(l) i inbufi(l) cu 1 l v . Aceste componene speciale sunt mulimi de mesaje:
inbufi(l) pstreaz mesajele care au fost transmise lui pi pe canalul numrul l incident cu pi (trimise deci de cellalt procesor ce formeaz acea muchie) i care n-au
fost nc prelucrate ntr-un pas de calcul intern.
Qi conine o submulime de stri iniiale. ntr-o stare iniial inbufi(l) este vid l (anumite componente din outbufi(l) pot fi nevide!).
Qi \ {inbufi(l) ; 1 l v } formeaz mulimea strilor accesibile.
Funcia de tranziie a procesorului pi este definit (acioneaz) pe aceast mulime a strilor accesibile. Rezultatul aplicrii funciei de tranziie asupra unei stri accesibile
va fi:
o nou stare accesibil n care inbufi(l) este vid l;
cel mult un mesaj pentru fiecare l{1, 2, , v}: mesajul ce va fi trimis
(Mesajele trimise n prealabil de pi care ateapt s fie expediate nu pot influena pasul curent al procesorului pi; fiecare pas proceseaz toate mesajele care i-au fost
expediate lui pi, rezultatul fiind o schimbare a strii i cel mult un mesaj pentru fiecare vecin.)
O
vecinului de la captul canalului numrul l ; acesta va fi depus n outbufi(l).
configuraie a sistemului este un vector C=(q0, q1, , qn-1) unde qiQi pentru i{0, 1, , n-1}. Strile din variabilele outbuf dintr-o configuraie reprezint mesajele
care sunt n tranzit pe canalele de comunicaie.
O configuraie iniial

este o configuraie n care fiecare qi este o stare iniial a lui pi.

Apariiile ce pot avea loc n sistem sunt modelate ca evenimente. Pentru sisteme de tip MP avem dou tipuri de evenimente:
evenimente de calcul

: comp(i) cu semnificaia c funcia de tranziie a lui pi se aplic strii accesibile curente;
evenimente de livrare

Comportarea sistemului n timp este modelat ca o
: del(i,j,m).
execuie: ir alternat de configuraii i evenimente. Acest ir trebuie s ndeplineasc anumite condiii depinznd de
tipul de sistem pe care l modelm: condiii de siguran (safety) i condiii de viabilitate (liveness).
O condiie de siguran este o condiie ce trebuie s aib loc pentru oricare prefix finit al irului (ce reprezint execuia). O astfel de condiie spune c nimic ru nu s-a
ntmplat nc.
O condiie de viabilitate este o condiie ce trebuie s aib loc de un anumit numr de ori, posibil de o infinitate de ori (odat i odat = eventually) ceva bun va avea loc.
Un ir care satisface condiiile de siguran va fi numit execuie.
O execuie care satisface condiiile de viabilitate va fi numit execuie admisibil
5. Sisteme MP asincrone
.


Nu exist o margine superioar asupra timpului necesar unui mesaj pentru a fi expediat sau asupra timpului dintre doi pai consecutivi ai unui procesor. Exemplu:
Internetul. Dei n practic se pot considera margini superioare pentru ntrzierea mesajelor i timpilor pailor procesorului, acestea sunt prea mari, se ating foarte rar i se
schimb n timp. Se prefer proiectarea unor algoritmi independeni de parametrii de timp: algoritmi asincroni.
Un segment de execuie
k=del(i,j,m) : livreaz mesajul m de la i la j. m este un element din outbufi(l) n Ck-1(l fiind eticheta canalului {pi pj} dat de procesorul pi). Singura schimbare de la
Ck-1 la Ck este c m este ters din outbufi(l) n Ck i este adugat n inbufi(h) unde h este eticheta canalului {pi pj} dat de pj. (Mesajul m este livrat numai dac este n
tranzit i singura schimbare este c este mutat din bufferul de ieire al trimitorului n bufferul de intrare al receptorului).
ntr-un sistem distribuit de tip MP asincron este un ir = C0, 0, C1, 1, C2, 2, .
unde Ck este o configuraie i k este un eveniment. Dac este finit, atunci irul se termin ntr-o configuraie.
Evenimentele k sunt de dou tipuri:
k=comp(i) singura schimbare de la Ck-1 la Ck este c starea lui pi din Ck-1 se modific aplicnd funcia de tranziie a lui pi pentru starea accesibil din Ck-1 i se
obine o nou stare n care mulimea mesajelor specificate de funcia de tranziie sunt adugate la variabilele outbufi n Ck. Mesajele sunt trimise

O
la acest eveniment
(pi i schimb starea i trimite mesaje conform programului local pe baza strii curente i a tuturor mesajelor ce i-au fost livrate). Dup acest eveniment inbufi sunt
vide.
execuie este un segment de execuie cu C0 configuraie iniial.

Cu fiecare execuie (segment de execuie) se poate asocia o planificare (segment de planificare) care este irul evenimentelor din execuie (segment de execuie). Este clar
c nu orice ir de evenimente este o planificare.

Dac programele locale sunt deterministe, atunci execuia este unic determinat de configuraia iniial i planificare, i se noteaz exec(C0, ) . ( =1, 2, )

O execuie este admisibil dac fiecare procesor are o infinitate de evenimente de calcul i orice mesaj este odat i odat livrat.
Cerina existenei unei infiniti de evenimente de calcul modeleaz faptul c procesoarele nu pic. Nu nseamn c avem bucle infinite. Terminarea se poate obine
impunnd ca funcia de tranziie s nu mai modifice starea procesorului dup un anumit punct.
O planificare e admisibil
6. Sisteme MP sincrone
dac e planificarea unei execuii admisibile.


n acest model o execuie este un ir de configuraii alternnd cu evenimente, partiionat n runde : segmente disjuncte ale irului. n fiecare rund trebuie s avem cte un
eveniment de livrare pentru orice mesaj din variabilele outbuf ale tuturor procesoarelor din starea precedent rundei i cte un eveniment de calcul pentru fiecare procesor.
O execuie este admisibil dac este infinit. (notm concordana cu definiia pentru sisteme asincrone).
Observaie: ntr-un sistem distribuit sincron fr cderi, dup fixarea algoritmului, singurul aspect relevant
7. Complexitate
al execuiilor care poate s difere este configuraia iniial.
ntr-un sistem distribuit asincron pot exista mai multe execuii diferite ale aceluiai algoritm cu aceeai configuraie iniial (i fr cderi) pentru c interleaving-ul
pailor procesoarelor i ntrzierile mesajelor nu sunt fixate.


Este necesar noiunea de terminare a unui algoritm. Fiecare procesor are o mulime de stri terminale pe care funcia de tranziie nu le mai modific.
Un algoritm se termin atunci cnd toate procesoarele se afl n stare final (Obs. : nu exist mesaje n tranzit).
MC complexitatea mesajelor
Pentru sisteme sincrone este numrul maxim de runde pn la terminare ntr-o execuie admisibil oarecare;
(complexitatea de comunicare) este numrul maxim de mesaje transmise pentru toate execuiile admisibile ale algoritmului. Aceast
definiie este valabil att pentru sisteme sincrone ct i pentru sisteme asincrone.

TC complexitatea timp:
Pentru sisteme asincrone se presupune c ntrzierea maxim a livrrii mesajelor necesit o unitate de timp i se calculeaz timpul pn la terminare.
Execuie n timp (timed execution): fiecrui eveniment i se asociaz un numr real 0 reprezantnd timpul la care apare; timpii ncep de la 0 i sunt cresctori
pentru fiecare procesor; dac execuia este infinit timpii tind la infinit. Evenimentele dintr-o execuie sunt ordonate conform timpilor la care apar; pot exista mai
multe evenimente care apar la acelai moment de timp (dac nu afecteaz aceleai procesoare; comp(i) afecteaz procesorul pi, del(i,j,m) este un eveniment asociat
i procesorului pi i procesorului pj la acelai moment de timp).
ntrzierea unui mesaj este diferena dintre timpii asociai evenimentului de calcul (de tip comp) i de livrare (de tip del) referitori la acelai mesaj.
Complexitatea timp
8. Convenii de pseudocod
este timpul maxim pn la terminare pentru toate execuiile n timp posibile, n care orice ntrziere de mesaj este cel mult 1.


n loc s prezentm tranziia strilor i s inventm un mecanism de control al interleave-ului vomprezenta algoritmii:
n proz;
folosind un pseudocod.
Algoritmii asincroni vor fi descrii ntr-o manier interrupt-driven pentru fiecare procesor.
n modelul formal mesajele care ateapt n variabilele inbuf sunt prelucrate toate n acelai timp. Vom descrie prelucrarea lor unul dup altul ntr-o ordine oarecare. Dac
ntr-un acelai recipient sunt generate mai multe mesaje, aceasta nu contravine modelului formal pentru c pot fi considerate un mesaj mare.
Vom evidenia i aciunea procesorului cnd nu exist mesaje.
Evenimentele care nu genereaz schimbri de stare i transmisii de mesaje nu vor fi listate.
Un algoritm asincron va putea fi executat i ntr-un sistem sincron dar pentru claritate algoritmii sincroni vor fi descrii n termenii rundelor pentru fiecare procesor.
Pentru fiecare rund se vor descrie aciuni i mesajele trimise pe baza mesajelor tocmai primite.
Mesajele ce trebuie trimise n prima rund sunt cele din variabilele outbuf.
Terminarea va fi implicit indicat prin faptul c nu mai urmeaz o rund nou.
Variabilele locale unui procesor p
i nu vor primi indicii i; n discuii i demonstraii vor fi necesari aceti indici.
Pentru algoritmi asincroni se va folosi cuvntul rezervat terminate
9. Broadcast
indicnd faptul c procesorul intr ntr-o stare terminal.




n reea se cunoate un arbore parial cu o rdcin specificat pr. Acest procesor difuzeaz un mesaj M tuturor celorlalte procesoare.

Copii ale mesajului vor fi trimise pe muchiile arborelui parial tuturor procesoarelor.
Fiecare procesor are un canal care trimite la printele su parent i o mulime de canale care conduc la copiii si din arbore children.
Exemplu:




Descrierea algoritmului n proz:
rdcina pr trimite mesajul M pe canalele ce conduc la copii;
cnd un proces primete mesajul M de la printe, trimite M pe canalele ce conduc la copii.
Descrierea algoritmului n pseudocod:
Algoritm broadcast bazat pe un arbore parial
Iniial M este n tranzit de la pr la toi copiii si n arbore.
Codul pentru pr:
1: la primirea nici unui mesaj //primul eveniment de calcul pentru pr
2: terminate
Codul pentru pi 0 i n-1, ir
la primirea mesajului M de la parent
3: send M tuturor children
4: terminate

Descrierea algoritmului la nivelul tranziiilor.

starea procesorului p
i conine:
o variabil parenti, care pstreaz un indice de procesor sau nil;
o variabil childreni, care pstreaz o mulime de indici;
o variabil boolean terminatedi care indic dac pi este n stare terminal.
Iniial, valorile variabilelor parent i children sunt astfel nct formeaz un arbore parial al reelei cu rdcina n pr; toate variabilele terminated sunt false.
Iniial, outbufr(j) pstreaz M pentru fiecare j din childrenr(atenie la indici: aici numerotarea e fcut dup indicii vecinilor pentru uurina expunerii).
Rezultatul lui comp(i) este: dac M este n inbufi(k) pentru un anumit k, atunci M este plasat n outbufi(j) pentru fiecare j din children i pi intr n starea terminal
punnd terminatedi pe true. Daca i = r i terminatedr este false, atunci terminatedr este pus pe true.

Algoritmul este corect indiferent dac sistemul este sincron sau asincron. Chiar mai mult, TC i MC vor fi aceleai.
MC: numrul de mesaje transmise este clar n-1 = numrul de muchii din arborele parial deci MC=n-1.
TC: mai dificil.
Lema1: n orice execuie admisibil a algoritmului de broadcast n modelul sincron, orice procesor aflat la distana t de pr n arborele parial primete mesajul M n runda
t.
Demonstraie: Prin inducie dup t.
t=1 Conform descrierii algoritmului (i conveniilor de la descrierea rundelor) n runda 1 fiecare copil al lui pr primete mesajul M.
Pasul inductiv: Presupunem c orice procesor aflat la distana t-1 1de pr primete mesajul M n runda t-1.
Trebuie s demonstrm c n runda urmtoare, t, orice procesor aflat la distana t primete M. Fie pi aflat la distana t. Printele lui pi, pj, este la distana t-1. Conform
ipotezei iductive pj primete mesajul M n runda t-1. Din descrierea algoritmului pj trimite M lui pi n runda urmtoare, t.

Teorema 1: Exist un algoritm sincron de broadcast cu MC egal cu n-1 i TC egal cu d atunci cnd se cunoate un arbore parial de adncime d.

Schimbnd n lema precedent doar semnificaia timpului ntr-un sistem asincron se obine urmtoarea teorem: (lucrm cu timpi din pentru a face demonstraii
inductive)
Teorema 1
10. Convergecast
: Exist un algoritm asincron de broadcast cu MC egal cu n-1 si TC egal cu d atunci cnd se cunoate un arbore parial de adncime d.


Este problema invers broadcastului: colectarea informaiilor din noduri n rdcin (din nou se presupune existena unui arbore parial al reelei).
P
2
P
1
1 2 1 2
Considerm o variant specific a acestei probleme:
Dac pi este frunz (nu are copii) starteaz algoritmul prin trimiterea valorii xi printelui su.
Iniial, fiecare procesor deine o valoare real xi.Se dorete ca la terminarea algoritmului n rdcin s se afle valoarea maxim din reea.

Descrierea algoritmului n proz:
Dac pj nu este frunz, are k copii i ateapt s primeasc mesaje coninnd vi1, vi2, ..., vik de la copiii si pi1, pi2, ..., pik. Calculeaz
vj=max(vj, vi1, vi2, ..., vik) i trimie vj printelui su.
Teorema2
11. Inundarea (Flooding) i
: Exist un algoritm asincron convergent cu CM egal cu n-1 i CT egal cu d atunci cnd se cunoate un arbore p cu rdcina de adncime d.
Construirea unui arbore parial

Este similar broadcastului fr s se cunoasc n prealabil un arbore parial
pr trimite M la toi vecinii;
. Se dorete difuzarea unui mesaj M dintr-un procesor pr la toate celelalte.

pr starteaz algoritmul i trimite M tuturor vecinilor. Cnd un procesor pi primete M pentru prima dat de la un vecin pj, pi trimite M la toi ceilali cu excepia lui
pj.

CM: Mesajul M este trimis de cel mult dou ori pe fiecare canal, cu excepia aceluia pe care M este trimis prima dat, pe care e trimis o singur dat. Deci CM=2m-
n+1 (sunt posibile execuii pentru care avem dou trimiteri pentru fiecare canal, cu excepia acelui din arborele impicit construit). Deci CM=O(n
2
).
Este posibil ca un procesor s primesc M de la mai multi vecini odat. Evenimentul comp(i) prelucreaz toate mesajele primite ntre timp de la precedentele
evenimente comp. Atunci se va alege doar unul dintre canale ca fiind n arbore.
Algoritmul de inundare poate fi explicit modificat pentru a evidenia acest arbori cu rdcina n pr:
atunci cnd pi primete mesajul M de la mai muli vecini alege unul pj i i trimite un mesaj <parent>. Pentru toate celelalte procesoare precum i pentru toate
de la care va primi M mai trziu trimite mesajul <reject>;
cei care rspund cu mesaje <parent> vor deveni copii lui pi;
pi i termin activitatea atunci cnd tuturor mesajelor M trimise, li se rspunde cu <parent> sau <reject>.

Pseudocodul algoritmului flooding modificat pentru construirea unui arbore parial
6: la primirea nici unui mesaj:
(codul pentru pI )

Iniial parent este nil, children i other sunt mulimi vide.
6: if i=r and (parent is nil) then //rdcina nu a trimis nc M
3: send M to all neighbors
4: parent :=i

5: la primirea mesajului M de la vecinul pj:
6: if parent is nil then //pi nu a primit mesajul M mai nainte
7: parent :=j
8: send parent to pj
9: send M to all neighbors except pj
10: else send <reject>to pj

11: la primirea mesajului <parent>de la vecinul pj:
12: add j to children
13: if children other = toi vecinii parent then terminate

14: la primirea mesajului <reject>de la vecinul pj:
15: add j to other
16: if children other = toi vecinii parent then terminate

Reeaua fiind conex fiecare nod este accesat din pr la sfritul algoritmului (se poate demonstra inductiv). Un nod este accesat din pr dac i numai dac i fixeaz
variabila parent. Inexistena circuitelor se datoreaz modului de fixare a variabilei parent.

Teorema3: Exist un algoritm asincron pentru determinarea unui arbore parial ntr-o reea cu m muchii i diametrul D, dintr-un nod fixat cu CM=O(m) i
CT=O(D).

Observaie: algoritmul funcioneaz i n modelul sincron. De data aceasta ns arborele construit este garantat a fi de tip BFS (demonstraia este evident prin
inducie dup numrul de runde).
n modelul asincron pentru orice arbore parial cu rdcina n pr se poate construi o execuie admisibil care s-l construiasc (aici intervine interleaving-ul, prin
alegerea unei planificri admisibile corespunztoare).
12. Alegerea liderului n inele

Inel: Sistem distribuit cu topologia dat de graful circuit Cn, n2.
Inelele corespund sistemelor de comunicaie reale, de ex. token rings.
Alegerea liderului (leader election) este o paradigm simpl i interesant pentru a evidenia elemente de complexitate a comunicatiei n sisteme distribuite, dar i pentru a
transforma un sistemdistribuit descentralizat n unul centralizat.
Exemplu: Cnd ntr-un sistem distribuit apare un interblocaj se formeaz un circuit n care procesoarele se ateapt unele pe altele; atunci se alege unul din ele ca lider i este
scos din circuit.

Problema:
- strile terminale sunt partiionate n ales i neales. Odat ce un procesor intr ntr-o stare terminal de un anumit tip rmne n acel tip.
Fiecare procesor trebuie s decid dac este sau nu lider cu condiia c exact unul va decide c este lider.

Un algoritm rezolv problema alegerii liderului dac satisface:
- n orice execuie admisibil exact un procesor (liderul) intr ntr-o stare terminal de tip ales, celelalte intr ntr-o stare de tip neales.

Inelul: muchii ntre pi i pi+1 i, 0in-1 (adunarea mod n).
Inelul orientat: i canalul lui pi ctre pi+1 este etichetat cu 1 (stnga, sensul acelor de ceasornic); canalul lui pi ctre pi-1 este etichetat 2 (dreapta, sensul invers al acelor de
ceasornic).




P
0
Inele anonime: procesoarele nu au un identificator unic care s fie folosit de algoritm (oricare procesor este reprezentat de aceeai main cu stri).
n descrierea algoritmului recipienii mesajelor pot fi specificai numai n termenii etichetrii canalelor: vecinul din stnga, vecinul din dreapta.

Dac n=numrul procesoarelor din inel nu este cunoscut de procesoare atunci avem algoritmi uniformi: algoritmul este acelai pentru orice valoare a lui n. Altfel, algoritmi
neuniformi: acelai algoritm pentru fiecare procesor dar care poate fi diferit pentru diferite valori ale lui n.
Vom demonstra inexistena unui algoritm de alegere a leaderului ntr-un inel anonim, sincron i neuniform (adic n cele mai tari condiii; cu att mai mult va
rezulta pentru cazul uniform; ca att mai mult va rezulta pentru cazul asincron).

Teorema. Nu exist algoritmi neuniformi anonimi pentru alegerea liderului n inele sincrone.
Demonstraie.Fie un inel oarecare de dimensiune n>1. Presupunem c exist a algoritm anonim de alegere a liderului. Cum inelul este sincron i exist doar o singur
configuraie iniial rezult c exist o unic execuie admisibil a lui A pe R. Pentru orice rund k o execuie admisibil a lui A pe R, starea oricrui proces este aceeai la
sfritul rundei k (inductie evident).

13. Inele asincrone

Fiecare procesor are un identificator unic, ntreg nenegativ oarecare (starea procesorului pi are o component idi iniializat cu identificatorul lui pi). Un algoritm(neanonim)
este uniform dac pentru orice identificator exist o main cu stri i indiferent de dimensiunea inelului algoritmul este corect (atunci cnd procesorul asociat mainii cu stri
corespunde identificatorului su) (exist doar un program local pentru un procesor cu un identificator dat, indiferent de numrul procesoarelor).
Un algoritm(neanonim) este neuniform dac pentru n i pentru identificator exist o main cu stri.

Un algoritm cu MC=O(n
2
)
Funcioneaz chiar dac inelul este unidirectional.
- Fiecare procesor trimite un mesaj cu identificatorul su, vecinului din stnga i ateapt mesaj de la vecinul din dreapta.
- La primirea unui mesaj (de la vecinul din dreapta) compar identificatorul primit cu al su. Dac cel primit este mai mare l trimite mai departe vecinului din stnga.
Altfel, l nghite i nu-l mai trimite mai departe.
- Dac un procesor primete un mesaj cu identificatorul egal cu cel pe care l are atunci se declar lider i trimite un mesaj de terminare vecinului din stnga si i termin
activitatea, ca lider.
- Un procesor care primete un mesaj de terminare l trimite la stnga i termin ca nelider.

Nici un procesor nu trimite mai multede n+1 mesaje ntr-o execuie admisibil. Deci, MC=O(n
2
). Considerm inelul cu identif:
Mesajul proces cu identificatorul i este trimis exact de i+1 ori. Numrul total de mesaje (+ cele de terminare) este
) n ( ) 1 i ( n
2
1 n
0 i
= + +

=
.










Un algoritm cu MC=O(nlog n)
Aceeai idee: mesajul procesorului cu identificatorul maxim traverseaz
inelul i se ntoarce la acest procesor, care se declar lider.
k-vecintatea procesorului
- n faz 0, fiecare procesor trimite un mesaj <probe> coninnd identificatorul su n 1-vecintatea sa, adic la cei 2 vecini. Dac un procesor primete un mesaj <probe>
compar identificatorul primit cu al su i numai dac cel primit este mai mare rspunde cu un mesaj <reply>. Un procesor ce primete ambele rspunsuri devine lider
temporar i trece la faza 1.
pi este mulimea procesoarelor aflate la distan
mai mic sau egal cu k de pi pe inel (la stnga i la dreapta). k-vecintatea unui
procesor are 2k+1 procesoare.
Algoritmul lucreaz n dou faze. n faza l un procesor ncearc s devin lider temporar n 2
l
-vecintatea sa. Liderii (temporari) din faza l continu faz l+1.
- n faza l un procesor pi, devenit lider temporar, n faza precedent trimite mesaje probe la stnga i la dreapta n 2
l
-vecintatea sa secvenial.Fiecare din cele dou mesaje
traverseaza 2
l
-vecintatea ntr-o directie; dac nu-i cumva nghiit n aceast traversare, ajunge la capt. Acest ultim procesor trimite un mesaj <reply> lui pi. Dac pi
primete reply din ambele direcii, devine lider temporar pentru faza l i trece la faza l+1.

Pentru implementare, mesajele <probe> au trei cmpuri: identificator, numr de faz, numr de hopuri. Numrul de hopuri este iniializat cu 0 i incrementat cu 1 ori de cte
ori este transmis mai departe. Un procesor este ultimul dintr-o 2
l
vecintate dac primete un mesaj cu numrul de hopuri egal cu 2
l
.

Algoritm asincron de alegere a liderului.
Iniial asleep=true
1: la primirea niciunui mesaj:
2: if asleep then
3: asleep:=false
4: send <probe, id, 0,0> la stnga i la dreapta

5: la primirea unui mesaj <probe, j,l,d>din stnga (respectiv dreapta):
6: if j=id then terminate as the leader
7: if j>id and d<2
l
then //transmite mesajul
8: send <probe, j, l, d+1>la dreapta (respectiv stnga)
9: if j>id and d =2
l
then
10: send <reply, j, l> la stnga (respectiv dreapta)

11: la primirea unui mesaj <reply, j, l>din stnga (respectiv dreapta)
12: if j id then send <reply, j, l>la dreapta (respectiv stnga)
13: else
14: if a primit deja <reply, j, l>din dreapta (respectiv stnga) then
15: send <probe, id, l+1,0>la stnga i la dreapta //lider temporar i
ncepe o nou faz

Observaie
Numrul de mesaje iniiate de un lider temporar n faza l este de
l
2 4 .
y
x
p
i
p
j
p
1
p
2

q
1
q
2

p
1
p
2

q
1
q
2

Ci lideri temporari avemntr-o faz l?

Lema 1: Pentru 1 k numrul procesoarelor care devin lideri temporari la sfritul fazei k este
1 2
n
k
+
.
Demonstraie.

Dac pi i pj vor fi ambii lideri temporari distana dintre ei trebuie s fie mai mare sau egal cu 2
k
+1 (altfel unul dintre ei va fi nghiit de cellalt). Lema este acum evident.
n particular, n faza logn-1 va exista un singur lider temporar. Numrul total de mesaje este deci mai mic sau egal cu

=

+
+
+
1 n log
1 l
1 l
l
0 faza
n log n 8 n
1 2
n
2 4 n 4
Teorema 2 Exist un algoritm asincron de alegere a liderului ntr-un inel neanonim astfel nct MC=O(nlogn).


O margine inferioar de ) n log n (

Demonstrm c algoritmul prezentat este asimptotic optimal: orice algoritm ce alege liderul ntr-un inel asincron trimite cel puin ) n log n ( mesaje. Marginea
inferioar este pentru algoritmi uniformi.
Presupunem c avem un algoritm uniform A care rezolv problema alegerii liderului (procesorul cu identificatorul maxim se declar lider i transmite identificatorul su
tuturor celorlali care vor fi nealei).
Demonstrm c exist o execuie admisibil a lui A n care se trimit ) n log n ( mesaje.
Ideea: se consider o execuie a algoritmului pe inele de dimensiune
n /2 si se combina doua astfel de executii pe un inel de dimensiune n obinut din cele dou inele mici. De fapt vom lucra cu planificri pentru c n execuii avem configuraii,
n care sunt evideniate strile tuturor celor n procesoare.

Definiie. O planificare a lui A pentru un inel este deschis dac exist o muchie e n inel astfel nct n nu este trimis nici un mesaj pe muchia e (indiferent de direcie); e
este muchia deschis a lui .
Observaie .
1. Nu este obligatoriu ca o planificare deschis s fie admisibil; ea poate fi finit i procesoarele s nu fi terminat.
2. Vom presupune c n este o putere a lui 2 pentru evitarea unor detalii tehnice.

Teorema 3 Pentru orice n i orice mulime de n identificatori exist un inel ce folosete ac identif care are o planificare deschis pentru A n care se primesc cel puin M(n)
mesaje, unde M(2)=1 i
|
.
|

\
|
+ = 1
2
n
2
1
)
2
n
( M 2 ) n ( M , n>2.
Observaie Rezolvarea recurentei pentru M(n) conduce la M(n)=(nlog n )
Demonstraie Prin inducie dupa n.
Baza n=2
Presupunem


x identificatorul lui po si y identificatorul lui p1.
Fie o execuie admisibil a lui A pe acest inel. Cum A este corect, odat i odat p1 va scrie x n . Cel puin un mesaj este primit n .
Fie cel mai scurt prefix al planificrii cu proprietatea c p1 primete un mesaj de la p0:
va fi o planificare deschis cu muchia deschis cealalt dect cea pe care se primete mesajul.

Pasul inductiv Fie S o mulime de n identificatori. Partiionm S n S1 i S2 de dimensiunea n/2. Din ipoteza inductiv rezult c exist Ri inel ce folosete identificatorii din Si,
care are o planificare deschis i a lui A n care se primesc cel puin M(n/2) mesaje (i=1,2). Fie ei muchia deschis a lui Ri. ei=piqi. Considerm inelul R obinut astfel






1 urmat de 2 este o planificare pentru A n R. (Se consider apariia evenimentului din 1 ncepnd cu o configuraie iniial a lui R; cum
procesoarele din R1 nu pot distinge n timpul acestor evenimente dac R1 este un inel independent sau subinel al lui R, ele execut 1 exact ca i cum R1 ar fi fost independent.
n continuare se execut 2). Deci 12 este o planificare pentru R cu cel puin 2M
|
.
|

\
|
2
n
mesaje primite.
Form n continuare algoritmul s primeasc
|
.
|

\
|
1
2
n
2
1
mesaje suplimentare blocnd sau ep sau eq, dar nu amndou.
p
o
p
1
R
1

R
2
R
1
R
2
R
e
q

P
Q
e
p

Considerm orice planificare finit de forma 123 n care ep i eq rmnd deschise. Dac exist una cu cel puin
|
.
|

\
|
1
2
n
2
1
mesaje primite 3, lema este demonstrat.
Dac nu exist o astfel de planificare exist o planificare 123care va rezulta o execuie ce ajunge ntr-o stare mut: nu exist nici un ir de evenimente de calcul din acea
stare, care s nu mai transmit vreun mesaj. Procesoarele nu vor trimite nici un mesaj pn nu vor mai primi unul. O configuraie este mut n raport cu ep sau eq, dac nu
exist mesaje n tranzit cu excepia muchiilor deschise ep i eq i orice procesor este ntr-o stare mut.
Presupunem c procesorul cu identificator maxim este n R1. Cumnici un mesaj nu-i livrat din R1 lui R2, procesoarele din R2 nu cunosc identificatorul liderului i nici un
procesor din R2 nu poate termina la sfritul lui 123. n orice execuie admisibil extinznd 123orice procesor din R2 trebuie s primeasc un mesaj adiional nainte de
terminare (pentru a afla identificatorul liderului). Deci pe R trebuie s fie primite
|
.
|

\
|

2
n
mesaje adiionale.
Putem demonstra c este suficient s deblocm doar una din ep sau eq i nc s form primirea a
|
.
|

\
|

2
n
mesaje.
Exist un segment finit de planificare 4 n care
|
.
|

\
|
1
2
n
2
1
mesaje sunt primite i astfel nct 1234 este o planificare n care ep sau eq este deschis.
Fie 4

astfel nct 1234

este o planificare admisibil. Toate mesajele sunt livrate pe ep sau eq i toate procesele se termin. Cel puin
2
n
mesaje sunt primite n 4

pn
A se termin. Fie 4

cel mai scurt prefix al 4

n care sunt primite 1


2
n
mesaje. Considerm toate procesoarele din R care primesc mesaje n 4

. Cums-a plecat dintr-o


stare mut, cu mesaje n tranzit doar pe ep sau eq, aceste procesoare formeaz dou mulimi consecutive de procesoare P i Q. P conine procesoarele trezite de deblocarea lui ep
i deci P conine p1 sau p2. Similar Q conine q1 sau q2. Cum fiecare din aceste mulimi conine cel mult 1
2
n
procesoare i cum sunt consecutive ele sunt disjuncte.








Numrul mesajelor primite de proccesoarele uneia din cele dou mulimi este mai mare sau egal cu
|
.
|

\
|
1
2
n
2
1
. Presupunem c P. Fie 4 subirul lui 4

care conine
numai evenimente referitoare la procesoarele lui P. Cumn 4

nu exist comunicare ntre procesoarele din P i Q rezult c 1234 este o planificare. n aceast planificare
sunt primite cel puin
|
.
|

\
|
1
2
n
2
1
mesaje n 4 i n plus din construcie nici un mesaj nu este trimis pe eq. Deci 1234este planificarea deschis cerut.


14. Inele sincrone.
Demonstratia c marginea inferioar de ( ) n log n pentru alegerea liderului n inele asincrone s-a bazat pe ntrzierea mesajelor pentru perioade arbitrar de mari.
n modelul sincron ntrzierea mesajelor e fixat i deci se pot obine rezultate mai bune. Mai mult, n acest model se poate obine informatie nu numai din primirea
mesajelor dar i din neprimirea lor ntr-o anumit rund.

Un algoritm neuniform
Liderul =procesorul cu identificator minim.
Algoritmul lucreaz n faze, fiecare format din n runde (n = numrul procesoarelor din inel).
n faza i (i0) dac exist un procesor cu identificatorul i, el este ales ca lider i algoritmul se termin.
(faza i are rundele ni+1, ni+2, , ni+n; la nceputul fazei i dac un identificator al unui procesor este i i acest procesor nu s-a terminat, el trimite un mesaj de-a lungul
inelului i termin ca lider. Dac identificatorul procesorului nu este i i primete un mesaj n faza i, trimite un mesaj mai departe i se termin ca nelider).

Exact n mesaje sunt trimise (n faza n care liderul este gsit). Numrul de runde depinde de identificatorul minim din inel: dac acesta este i atunci avemn(i+1) runde.

Observaie.
Inelul poate fi si unidirecional; algoritmul presupune cunoaterea lui n, iar startul este sincron.

Un algoritm uniform.

Nu va fi necesara dimensiunea inelului. n plus vom avea o versiune puin mai general pentru un sistem sincron: nu-i necesar ca procesoarele s nceap alg simultan. Un
procesor sau se activeaz spontan ntr-o rund oarecare sau la primirea unui mesaj.
Problema: O mulime de procesoare se activeaz spontan i devin candidai. Dintre ele, cel cu identificatorul minimeste ales lider.
Celelalte proc vor fi activate la primirea primului mesaj, dar ele nu vor participa la procesul de alegere: sunt pasive!
In soluia pe care o dm apar doua idei noi:
- mesajele ce pornesc de la diferite procesoare sunt transmise mai departe cu viteze diferite. Dac un mesaj provine de la un procesor cu identificatorul egal cu i el este
ntrziat 2
i
-1 runde la fiecare procesor care l primete, nainte de a fi transmis mai departe n sensul acelor de ceasornic.
-pentru depistarea startului nesincronizat se adaug o faz preliminar de deteptare. n aceast faz un procesor care se activeaz spontan trimite un mesaj de trezire pe
inel; acest mesaj este transmis fr ntrziere.
Deci un mesaj poate fi n prima faz pn ntlnete un procesor activ (n acest timp parcurge inelul cu viteza 1); dup ntlnirea primului procesor activ mesajul intr n faza
a II a n care este transmis mai departe cu viteza 2
i
(fiecare procesor activ l ntrzie cu 2
i
-1 runde).
Dup n runde de la activarea primului procesor vor rmne numai mesaje n faza a II a i liderul este ales dintre procesoarele participante.

Algoritm sincron de alegere a liderului n inele
Iniial waiting este vid i asleep este true
1: Fie R mulimea mesajelor primite n ac. ev. de calc
2: S:=0 //mesajele cer vor fi trimise
3: If asleep then
4: asleep:=false
5: if R is empty then
6: min:=id //participant la alegere
7: adaug <id>la S
8: else min:=
9: for each<m>in R do
10: if m<min then
11: devine neales
12: adaug <m> la waiting i ine minte cnd <m> a fost adugat
13: min:=m
14: if m=id then devine ales //dac m>min, m va fi nghiit
15: for each <m>in waiting do
16: if (<m>a fost primit 2
m
-1 runde mai nainte) then
17: scoate <m> din waiting i adaug-l la S
18: send S n reea.

Notm idi identificatorul procesorului pi; <idi>mesajul transmis de pi.

Lema. Numai procesorul cu cel mai mic identificator printre participanii la alegere i primete napoi mesajul.
Demonstraie: Fie pi participantul la alegere cu identificatorul minim. (Trebuie s fie mcar unul). Nici un procesor nu-l va nghii pe <idi>. Cumfiecare procesor va ntrzia
<idi>cel mult
i
id
2 runde, pi va primi odat i odat mesajul napoi.
Dac ar mai exista pj cu j i care primete napoi mesajul <idj>, acesta trebuie s treac pe la toate pe la toate inclusiv pe la pi, care nu-l va transmite. Contradicie.

Numrul de mesaje trimis ntr-o execuie admisibil a algoritmului.
Un mesaj este:
a. n prima faz.
b. n faza 2
a
trimis nainte ca mesajul viitorului lider s intre n faza a 2
a
.
c. n faza 2
a
trimis dup ce mesajul viitorului lider a intrat n faza 2
a
.

Lema 1 Numrul mesajelor din categoria a) este cel mult n.
Demonstraie Orice procesor transmite mai departe cel mult un mesaj n prima faz. Presupunem c pi transmite mai departe dou mesaje n prima faz <idj> i <idk>de la pj
respectiv pk. Presupunem c n sensul acelor de ceas avem pk-pj-pi. <idk>trece de pj nainte de a ajunge la pi. Dac <idk>ajunge n pj dup ce acesta s-a trezit i a trimis <idj>
atunci <idk>va continua ca un mesaj n faza 2
a
la viteza
k
id
2 ; altfel, pj nu particip la alegere i <idj>nu este trimis. Deci sau <idk>ajunge n pi n faza 2
a
sau <idj>nu este
trimis. Contradicie.

Fie r prima rund n care se trezesc un grup de procesoare i fie pi unul dintre ele. Urmtoarea lem arat c n runde dup ce primul procesor starteaz execuia algoritmului,
toate mesajele sunt n faza a II a.

Lema 2 Dac pj este la distana k (n sensul acelor de ceas) de pi, atunci pj primete un mesaj n faza I
a
cel trziu n runda r+k.
Demonstraie: Inducie dup k.
Baza: k=1 Evident: vecinul lui pi primete mesaj n runda r+1
Pas inductiv: Procesorul ce precede pi este la distana k-1 n rund r+k-1 a primit deja un mesaj n faza I
a
. Dac este deja treaz a trimis mesajul de trezire lui pi, altfel n runda
urmtoare pi va primi mesajul de la acesta.

Lema 3 Numrul mesajelor din categoria b) este cel mult n.
Demonstraie Dup runda r+n nu mai avem mesaje de categoria I
a
(conform lemei 1). Conform lemei 2 mesajul viitorului lider intr n faza 2
a
cel mult dup n runde dup
primul mesaj trimis de algoritm. Mesajele din categoria b) sunt trimise numai n cele n runde ce urmeaz rundei cnd primul s-a trezit. Mesajul <i>n faza a 2
a
e ntrziat 2
i
-1
runde nainte de a fi transmis mai departe. Deci i este trimis cel mult de
i
2
n
ori n aceast categorie. Cum mesajele cu identificatori mici sunt transmise cu viteza mai mare,
numrul maxim de mesaje se obine cnd toate procesoarele particip la alegere i cnd identificatorii sunt ct mai mici cu putin: 0,1,,n-1.
Mesajele viitorului lider (n cazul nostru 0). Deci numrul mesajelor din categoria b) este n
2
n
1 n
1 i
i

=
.

Fie pi procesorul cu identificator minim; nici un procesor nu va mai transmite mai departe un mesaj dup ce trimite mai departe <idi>.

Lema 4
Nici un mesaj nu este trimis mai departe dup ce <idi>se ntoarce la pi.

Lema 5
Numrul mesajelor din categoria c) este cel mult 2n.
Demonstraie Fie pi viitorul lider i pj alt procesor participant la alegeri. Conform lemei precedente nu exist mesaje n inel dup ce pi i primete mesajul napoi. Cum<idi>
este ntrziat cel mult
i
id
2 runde la fiecare procesor, cel mult
i
id
2 n runde sunt necesare pentru ca <idi> s se ntoarc la pi. Deci mesajele din categoria c) sunt trimise
numai n timpul a cel mult
i
id
2 n runde. n aceste runde <idj>este retransmis de cel mult
j i
i
j
id id
id
id
2 n 2 n
2
1
= ori.
Numrul total de mesaje din aceast categorie este

1 n
0 j
id id
i j
2
n

Ca n demonstraia lemei 3 acesta este n 2
2
n
1 n
0 k
k

=




Teorema 4
MC a algoritmului precedent este n 4 .
TC=O(n2
i
), i =identificatorul liderului.

O margine inferior de (nlogn) pentru algoritmi neuniformi sincroni care folosesc identificatorii numai pentru comparaii.

Algoritmii cu MC=O(n) au folosit id. pentru a decide ct de mult poate fi ntrziat un mesaj. Numrul de runde depinde de mrimea identificatorului care poate fi imens in
comparaie cu n.

Vomspecifica inelul R prin lista identificatorilor n ordinea parcurgerii inelului n sensul acelor de ceasornic, ncepnd cu identificatorul cel mai mic.
exec(R) va reprezenta execuia admisibil a unui algoritm pe inelul R (ntruct configuraia iniial este fixat chiar de listarea identificatorilor).
Date dou inele R
1 si R2 pi procesor n R1 si pj procesor n R2; pi si pj sunt cuplate dac ocup aceeai poziie n respectiva specificare a fiecrui inel (sunt la aceeai distan
fa de procesorul cu identificator minim; distana se consider pe inel, n sensul acelor de ceas).
Intuitiv, un algoritm este bazat pe comparaii dac se comport la fel pe inele care au acelai pattern de ordine a identificatorilor.
Dou inele Xo, X1,...,Xn-1 si Y0,Y1,...,Yn-1 sunt echivalente din punct de vedere al ordinii dac oricare ar fi i, j Xi<Xj <=>Yi<Yj. Aceast noiune se poate extinde la K-
vecinti.
Fie R1 si R2 dou inele, pi din R1, pj din R2 si dou execuii 1si 2 ale algoritmului A pe R1 respectiv R2.
Comportarea lui pi n 1este similar n runda k cu comportarea lui pj n 2 (n aceeai rund) dac:
- pi trimite un mesaj vecin din stnga (dreapta) n runda k n 1 <=>pj trimite un mesaj vecin stnga (dreapta) n runda k n 2.
- pi termin ca lider n runda k a lui 1 <=> pj termin ca lider n runda k a lui 2 .
pi are comportare n 1 similar comportarii lui pj n 2 <=> ele sunt similare n oricare rund k 0 .
Un algoritmeste bazat pe comparaii dac pentru orice pereche de inele echivalente din punct de vedere al ordinii R1 i R2, orice pereche de procesoare cuplate au
comportri similare n exec(R1) i exec(R2).
Inexistena unui mesaj ntr-o anumit rund r este folositoare pentru procesorul pi numai dac ar fi putut primi un mesaj n ac rund ntr-un inel diferit dar echivalent
din punct de vedere al ordinii.
O rund r este activ n o execuie pe un inel R dac mcar un procesor trimite un mesaj n runda r a execuiei. Pentru inelul R vom nota cu rk indicele celei dea k
a

runde active.
Observaii.
1. Dac R1 i R2 sunt echivalente din punct de vedere al ordinii, o rund este activ n exec(R1) <=> e activ n exec(R2).
2. n k runde un mesaj poate traversa k procesoare pe inel; rezult c starea unui procesor dup k runde depinde numai de k-vecintatea sa. Aceast proprietate se extinde n

Lema 6
Fie R1 i R2 dou inele echivalente din punct de vedere al ordinii i pi n R1 i pj n R2 dou procesoare cu k-vecinti identice. Atunci irul de tranziii urmat de pi n rundele 1
-- rk ale lui R1 este acelai cu cel urmat de pj n rundele 1 -- rk ale lui R2.
Demonstraie Informal, trebuie artat c dup k runde active un procesor poate afla doar informaia despre procesoarele aflate la distana cel mult k de el. Formal, inducie
dup k (k=0, au acelai identificator i deci sunt n aceeai stare, pasul inductiv evident).

Proprietatea de poate extinde la procesoare cu k-vecinti echivalente din punct de vedere al ordinii, cu condiia ca inelul s fie spaiat: un inel de dimensiune n este spaiat
dac oricare ar fi x un identificator al su, identificatorii x-1, x-2, , x-n nu apar n inel.

Lema 7. Fie R spaiat i pi i pj dou procesoare cu k-vecinti echivalente din punct de vedere al ordinii. Atunci pi i pj au comportamente similare n rundele 1,, rk ale lui
exec(R).
Demonstraie Construim un inel R (R se poate construi pentru c R este spaiat) care satisface:
- R echivalent din punct de vedere al ordinii cu R
- pj din R este cuplat cu pi din R
- k-vecintatea lui pj n R este identic cu k-vecintatea lui pi din R
- identificatorii lui R sunt unici
Aplicm Lema 6 i faptul c algoritmul este bazat pe comparaii.

Teorema 5
8 n putere a lui 2, exist un inel Sn de dimensiune n astfel nct pentru orice algoritm sincron bazat pe comparaii pentru alegerea liderului A, n orice execuie
admisibil a lui A sunt trimise (nlogn) mesaje.
Demonstraie Fie A un algoritm sincron bazat pe comparaii pentru alegerea liderului. Construim ] 1 n .. 0 [ i R
rev
n
, idi al lui pi este rev(i)=ntregul cu
reprezentare binar folosind log n bii egal cu inversa repezentrii binare a lui i.
n=8















Considerm orice partiie a lui
rev
n
R n segmente de lg j, j putere a lui 2. Se poate arta c toate aceste segmente sunt
echivalente din punct de vedere al ordinii.
P
0
000
2
=0
P
1
100
2
=4
P
7
111
2
=7
P
6
011
2
=3
P
5
101
2
=5
P
4
001
2
=1
P
3
110
2
=6
P
2
010
2
=2
Sn este o versiune spaiat a lui
rev
n
R : nmulim fiecare identificator cu n+1 i adunm n. Aceste schimbri nu afecteaz echivalena din punct de vedere al ordinii
segmentelor.
8
n
k< i oricare ar fi N o k-vecintate a lui Sn, exist mai mult de
) 1 k 2 ( 2
n
+
k-vecinti ale lui Sn care sunt echivalente din punct de vedere al ordinii cu N.
Numrul rundelor active n exec(Sn) este
8
n
(altfel, se demonstreaz c pe lng lider mai este ales i alt procesor).
Cel puin
) 1 k 2 ( 2
n
+
mesaje sunt trimise n cea de-a k
a
rund activ a lui exec(Sn),
8
n
k 1 , k
MC n Sn este

= =
=
+

8 n
1 k
8 n
1 k
) n log n (
8
n
ln
6
n
6
n
) 1 k 2 ( 2
n
.














15. Sisteme distribuite cu memorie partajat.
Problema excluderii mutuale.



ntr-un sistem distribuit cu memorie partajat, procesoarele comunic via o zon de memorie comun care conine o mulime de variabile partajate numite i
regitri. Vomconsidera numai sisteme asincrone. Cazul sincron este studiat n modelele PRAM ale calculului paralel.
Sistemul conine n procesoare p0, p1, ..., pn-1 i m regitri R0, R1, ..., Rm-1. Fiecare registru are un tip care specific: valorile ce pot fi luate de registru, operaiile ce pot
fi executate, valorile returnate de fiecare operaie i noua valoare a registrului care rezult dup fiecare operaie. Pentru fiecare registru poate fi specificat o valoare iniial.
O configuraie este un vector C =(q0, ..., qn-1, 0, ..., m-1) unde qi este o stare a lui pi, iar j este o valoare a registrului Rj.
Folosim notaia mem (C) = (0, ..., m-1).
Configuraie iniial: procesoarele sunt n stare iniial i regitrii conin valori iniiale.
Evenimente: pai de calcul ai procesoarelor specificai prin indexul procesorului.
n fiecare pas al procesorului pi se execut:
1. pi alege o variabil partajat pentru a o accesa cu ajutorul unei operaii specifice, pe baza strii sale curente;
2. se execut operaia asupra variabilei partajate
3. pi i schimb starea conform funciei de tranziie pe baza strii curente i a valorii returnate de operaia de la 2.
Segment de execuie: C0, 1, C2, 2, ..., Ck-1, k, Ck, ...
cu Ck configuratie i k eveiment. Seminificaie:
Dac k=i, atunci Ck se obine din Ck-1 prin modificarea unei singure variabile partajate Rj determinat de pi pe baza strii sale din Ck-1 i, de asemenea, Ck difer de Ck-1 prin
starea procesorului pi, care se obine cu ajutorul funciei de tranziie din starea lui pi din Ck-1 i valoarea returnat de operaii asupra lui Rj.
Executie: segment de execuie ce ncepe cu o configuraie iniial.
Executie adminisibil: fiecare procesor are un numr infinit de pai de calcul.
Planificare: ir de indici de procesoare.
P-planificare: P o mulime de procesoare P {p0, ..., pn-1}; irul de indici se refer numai la procesoarele din P.
Stri terminale ca la sistemele distribuite de tip MP. Un procesor aflat ntr-o stare terminal nu va face nici o modificare a variabilelor partajate.
Algoritmul se termin cnd toate procesoarele sunt n stare terminal
Dac C este o configuratie si =i1, i2, .... o planificare, ele determina
Exec (C, ).
C' este accesibil din C dac exist o planificare finit astfel nct C' =(C), unde (C) este configuratia final a lui Exec (C, ).
C este similar lui C' n raport cu mulimea de procesoare P,
'
~C C
P
dac fiecare procesor din P are aceeai stare i n C i n C' i mem(C) = mem(C').


Msuri de complexitate
C.Timp ?
C. Spaiu Cantitatea de memorie partajat necesar pentru a rezolva problema. Se poate considera
a) Numarul de variabile partajate sau
b) Cantitatea de spaiu partajat (=nr de bii= numrul de valori distincte) necesar.

Problema excluderii mutuale

Aceast problem se refer la un grup de procesoare care, ocazional, necesit accesul la o resurs ce nu poate fi folosit de mai mult de un singur procesor.
10
95
93
94
92
75
91
90
60
30
20
40
40
90
75
100
Fiecare procesor dorete s execute un segment de cod numit seciunea critic astfel nct la orice moment de timp cel mult un procesor se afl n seciunea critic
(excludere mutual) i dac unul sau mai multe procesoare ncearc s intre n seciunea critic atunci unul din ele o va face (odat i odat) atta timp ct nici un procesor
nu rmne la nesfrit n seciunea critic (lipsa interblocajului = no deadlock).
O proprietate mai puternic dect n lipsa interblocajului este: dac un procesor dorete s intre n seciunea critic, atunci el va reui atta timp ct nu exist nici un
procesor care s rmn la nesfrit n seciunea critic (no lockout =no starvation).
Se pot impune i condiii mai puternice: nici un procesor nu va ncerca mai mult de un numr fixat de ori ca s intre n seciunea critic.
Problema este uzual n proiectarea S.O., n programarea concurent i soluia obinuit necesit primitive de sincronizare speciale (monitoare, semafoare). Vom
prezenta soluii distribuite.
Vom presupune c programul fiecrui procesor e mprit n urmtoarele seciuni:

Entry (trying): codul ce se execut pentru pregtirea intrrii n seciunea
critic.
Critical: codul ce trebuie protejat de execuii concurente.
Exit: codul ce se execut dup prsirea seciunii critice.
Remainder: restul codului.

Fiecare procesor cicleaz: (remainder, entry, critical i exit ).
Un algoritm pentru problema excluderii mutuale const din cod pentru entry i exit.
Ipoteze:
- nici un procesor nu rmne n seciunea critic la nesfrit.
- variabilele locale sau partajate accesate n seciunea entry i exit nu sunt accesate n seciunile critical i remainder.
- un pas al procesoruui din seciunea remainder e urmat de un pas n
seciunea entry.
- un pas al procesorului din seciunea critical e urmat de un pas n seciunea
exit.

O execuie este admisibil dac pentru oricare procesor p
i, pi executa o infinitate de pai sau se termin n seciunea remainder.
Un algoritm pentru un sistem cu memorie partajat rezolv problema excluderii mutuale fr deadlock (sau fr lockout) dac
Excludere mutual: n orice configuraie a oricrei execuii cel mult un procesor se afl n seciunea critic.
No deadlock: n oriceexecuie adminisibil dac un procesor se afl n seciunea entry ntr-o configuraie exist o configuraie ulterioar n care un procesor este
n seciunea critic.
No lockout: n oriceexecuie admisibil dac un procesor se afl n seciunea entry ntr-o configuraie exist o configuraie ulterioar n care acel procesor este
n seciunea critic.

Obs: Seciunile exit vor fi coduri fr bucle i deci nu va exista posibilitatea ca un procesor s rmn n seciunea de ieire la nesfrit. Prin urmare nu vomimpune
condiii speciale.


Excludere mutual folosind primitive puternice

Registri binari Test & Set
O variabil test & set este o variabil binar care suport dou operaii atomice: test&set i reset.
test&set (V:memory adress) ntoarce valoare binar;
temp:=V
V:=1 // citete i actualiz.variab., atomic
Return (temp)
Reset (V:memory adress)
V:=0 // este n fapt un write.


Algoritm de excludere mutual folosind registru test&set:
(codul pentru orice procesor)
Initial V este 0
<Entry>:
1: wait until test&set (V) =0
<Critical section>
<Exit>:
2: reset (V)
<Remainder>.

n seciunea entry procesorul p
i testeaz repetat V pn obine 0; ultimul test asigneaz lui V valoarea 1 cauznd obinerea lui 1 pentru orice test urmtor i interzicnd
altui procesor intrarea n seciunea critic. n seciunea exit procesorul pi reseteaz pe V la valoarea 0 i unul din procesoarele care ateapt n seciunea de intrare va
putea intra n seciunea critic.
Algoritmul asigur excluderea mutual (demonstraia este imediat prin reducere la absurd).
Algoritmul asigur inexistena deadlock-ului (cum excluderea mutual are loc, se poate demonstra prin inducie c V=0 nici un procesor nu se afl n seciunea
critic).

Concluzie:
Teorema. Algoritmul asigur excluderea mutual fr deadlock foloind un singur registru test&set.

Observaie: Nu e asigurat no lockout.


Registri R-M-W

RMW (V memory address, f: function) ntoarce o valoare;
temp: =V
V: =f (V)
return (temp)

Un registru read-modify-write V este o variabil care permite procesorului s citeasc valoarea curent a variabilei, calculeaz o nou valoare ca o funcie de
valoarea curent i scrie noua valoare n variabil. Toate acestea formeaz o instruciune atomic.
Obs: 1. tipul i dim lui V nu-s relevante i nu s-au trecut
2. Operaia test&set e un caz particular al operaiei RMW, cu f (V) = 1, V.

Alg de exclud mutual folosind un registru RMW
(codul pentru orice procesor)
Initial V =<0,0>
<Entry>:
1: position =RMW (V, <V.first, V.last+1>)
2: repeat
3: queue: =RMW (V,V)
4: until (queue.first =position.last)
<critical section>
<Exit>
5 RMW (V, <V.first+1, V.last>)
<Remainder>


Algoritmul organizeaz procesoarele ntr-o coad, permind procesorului din capul cozii s intre n seciunea critic. Fiecare procesor are dou variabile locale position i
queue. Variabila RMW are dou cmpuri, first i last coninnd "tichete " ale primului, respectiv ultimului procesor din coad. La intrarea n seciunea <entry> un procesor
"citete" valoarea lui V i mrete V.last cu o unitate ntr-o operaie atomic. Valoarea lui V.last servete ca tichetul su: ateapt pn cnd V.first este egal cu tichetul su.
Atunci procesorul intr n seciunea critic. Dup prsirea seciunii critice, procesorul iese din coad mrind V.first, permind urmtorului procesor din coad s intre n
seciunea critic.


Numai procesorul din capul cozii poate intra n seciunea critic i el rmne n capul cozii pn ce prsete seciunea critic. Algoritmul asigur, deci, excluderea
mutual. n plus, disciplina cozii i ipoteza c procesoarele nu stau la nesfrit n seciunea critic, asigur proprietatea no lockout, care implic no deadlock.
Nu pot exista mai mult de n procesoare n coad n acest timp. Deci toate calculele se pot face mod n i valoarea maxim a ambelor cmpuri V.first i V.last este n-
1. Deci V necesit 2|log n| bii.

Teorema 2. Algoritmul asigur excluderea mutual fr lockout folosind un registru RMW cu 2|log
2 n| bii.

O margine inferioar asupra numrului de stri de memorie.

n soluia precedent numrul stri de memorie este O (n). Vom arta c dac algoritmul nu permite ca un procesor s tot fie ales ca s intre n seciunea critic de
un numr nemrginit de ori n defavoarea altuia atunci sunt necesare cel puin n stri de memorie.

Definiie. Un algoritm de excludere mutual asigur k-mrginirea dac n orice executie nu exist un procesor care s accead seciunea critic mai mult de k ori n timp ce
altul ateapt n seciunea entry.
(proprietatea de k-mrginire + proprietatea de neexisten a deadlock-ului asigura inexistena lockout-ului).

Teorema3: Dac un algoritm rezolv excluderea mutual fr deadlock i cu k-mrg (pentru un anumit k), atunci algoritmul folosete cel puin n stri de memorie
distincte .
Demonstraie. Vom numi o configuratie linitit, dac toate procesoarele sunt n seciunea remainder.
Fie C configuraia iniiala (deci, ea este linitit). Fie
0' o p0 - planificare infinit. Cum exec (C, 0') este admisibil i nu exist deadlock exist 0 un prefix finit
al lui 0' astfel nct p0 este n seciunea critic n C0 =0(C). Inductiv, construimpentru i 1 i n-1 o planificare i astfel nct pi este n seciunea entry n Ci =i (Ci-1). Deci
p0 e n seciunea critic i p1, ..., pn-1 sunt n seciunea entry n Cn-1=01...n-1(C).
Presupunemprin reducere la absurd c exista mai putin de n stri de memorie partajata distincte. Rezulta ca Ci, Cj 0< i< j n cu stri de memorie partajata
identice: mem(Ci) =mem(Cj). Din constructie, p0, ..., pi nu executa nici un pas n i+1,...j i deci Ci si Cj sunt {p0, ..., pi}-similare. Deci n Ci i Cj p0 e n seciunea critic i p1,
..., pi sunt n seciunea entry. Aplicm o {p0, ..., pi}- planificare infinit ' lui Ci. Exec (Ci , ') este admisibil, deci din faptul c algoritmul este fr deadlock, rezult c
l, 0 l i a.. pl intr n seciunea critic de o infinitate de ori. Fie un prefix finit al lui ' n care pl intr de k+1 ori n seciunea critic. Cum Ci si Cj sunt {p0, ..., pi}-similare
i este un {p0, ..., pi} - segment rezult c pl intr n seciunea critic de k+1 ori n exec(Cj, ). Cumpj este n seciunea entry n Cj i pl intr n seciunea critic de k+1 ori, se
violeaz condiia de k-mrginire.


Excludere mutual folosind regitri read/write

Algoritmul brutriei.
Structuri de date partajate:
- Number: tablou de n ntregi; componenta i pstreaza numrul
(de ordine) al lui pi
- Choosing: tablou boolean de dimensiune n; componenta i este true n timpul n care pi este n procesul de obinere a numrului su (de ordine).

Fiecare procesor pi care dorete s intre n seciunea critic, ncearc s-i aleag cel mai mic numr mai mare dect numerele celorlalte procesoare i-l scrie n
Number |i|. Este posibil ca mai multe procesoare s-i aleag acelai numr, datorit citirii concurente a variabilei Number. Pentru a avea o ordine total se foloseste ca tichet
perechea (Number |i|, i) i se consider ordinea lexicografic.
Dup alegerea unui numar, procesorul pi ateapt pn ce tichetul su devine cel mai mic. Compararea se face dup ce procesoarele i aleg numerele.
Algoritmul brutriei
Iniial Number |i| = 0 i Choosing |i| =false i
<Entry>:
1: Choosing |i|: =true
2: Number |i|: =max (Number |0|, ..., Number |n-1|) +1
3: Choosing |i|: =false
4: for j:=1 to n (ji) do
5: wait until Choosing |j|: =false
6: wait until Number |j| =0 or (Number|j|, j) >(Number|i|, i)
<Critical Section>
<Exit>:
7: Number |i|: =0
<Remainder>

Fie o executie fixat a algoritmului.
Lema 1: n orice config C a lui , dac procesorul pi este n seciunea critic i pentru k i Number |k| 0, atunci (Number |k|, k) >(Number |i|, i).
Lema 2: Dac pi e n seciunea critic atunci Number |i| >0.
Din lema 1 i lema 2 rezula:
Teorema 4: Algoritmul brutriei asigur excluderea mutual.
Teorema 5: Algoritmul brutriei este fr lockout.
Demonstraie: Un procesor nu poate fi blocat n timp ce i alege numrul su. Fie pi procesorul cu cel mai mic ticket (Number |i|, i) care este inut la nesfrit n afara
seciunii critice.
Toate procesoarele ce i aleg numrul dup ce pi i l-a ales, nu vor mai putea s intre n seciunea critic naintea lui pi. Din algoritmul lui pi, toate procesoarele cu
tickete mai mici vor intra n seciunea critic odat i odat. n acest moment pi vor trece toate testele de intrare n seciunea critic.
Obs: Pentru sistemele reale implementarea algoritmului trebuie s rezolve problema c numerele pot crete orict de mult.

Excluderea mutual cu variabile R/W mrginite.



A. Cazul a dou procesoare

Un algoritm de excludere mutual cu variabile mrginite pentru dou procesoare (care permite lockout)
Initial Want |i| =0 , i =0, 1

codul pentru p
0 codul pentru p1

<Entry>: <Entry>:
1: Want |1|: =0
2: wait until (Want |0| =0)
3: Want |0|: =1 3: Want |1|: =1
4: if (Want |0|: =1) then goto 1;
5: wait until (Want |1|: =0)
<Critical section> <Critical section>
<Exit>: <Exit>:
6: Want |0|: =0 6: Want |1|: =0
<Remainder> <Remainder>

Clar, n orice configuraie a unei execuii, dac pi este dup linia 3 i naintea liniei 6 (inclusiv n seciunea critic) atunci Want |i|: =1.
pi ridic steagul (Want |i|: = 1) i inspecteaz steagul celuilalt (citete Want |1-i|).
Cnd un procesor vede c steagul celuilalt e ridicat, atunci nu intr n seciunea critic.
Soluia e asimetric: p1 e totdeauna politicos; cedeaz intrarea lui p0; este posibil apariia lockoutului pentru p1.
Modificam algoritmul a.. fiecare procesor s dea prioritate celuilalt dup prsirea seciunii critice (e rndul tu acum).



Algoritmul de excludere mutual cu variabile mrginite pentru dou procesoare fr lockout
Iniial Want |i|: = 0 (i = 0,1) i Priority = 0
codul pentru pi (i = 0,1 )
<Entry>:
1: Want |i|: =0
2: wait until (Want |1-i|: =0 or Priority =i)
3: Want |i|: =1
4: if Priority =1-i then
5: if Want |1-i|: =1 then goto 1:
6: else wait until Want (1-i) =0
<Critical Section>
<Exit>:
7: Priority: =1-i
8: Want (i) =0
<Remainder>

Obs: Procesorul priority joac rolul lui p
0 din algoritmul precedent.
Teorema 5. Algoritmul asigur excluderea mutual fr lockout.
Dem: Se arat succesiv asigurarea excluderii mutuale, inexistena deadlockului i apoi a lockoutului.
Un algoritm de excludere mutual cu variabile R/W mrginite pentru n procesoare.

Procesoarele : p0, p1, ..., pn.

Fie
(
1 log = n k Consideramarborele binar complet cu 2
k
frunze (i 2
k+1
-1 noduri). Numerotare: rdcina 1; copilul stng al lui v este 2v i copilul drept 2v+1.
Frunzele arborelui 2
k
, 2
k
+1, ..., 2
k+1
-1 :











Nodului v ii asociem( | | 0
v
ant
W , | | 1
v
ant
W , Priority
v
) cu valorile iniiale 0.

Pentru a ncepe competiia pentru seciunea critic procesorul pi execut

( ) 2 mod , 2 / 2 i i Node
k
+ (starteaz recursia).

Algoritmul de excludere mutual pentru n procesoare

Procedure Node(v:integer; side:0..1)
1: Want
v
[side]:=0;
2: wait until (Want
v
[1-side]=0 or Priority
v
=side)
3: Want
v
[side]:=1;
4: if (Prority
v
=1-side) then
5: if (Want
v
[1-side]=1) then goto 1:
6: else wait until (Want
v
[1-side]=0)
7: if (v=1) then
1
2
3
4 5 6 7
p
0
p
1
p
2
p
3
p
4
p
5
p
6
p
7
8: <Critical Section>
9: else Node(

2 / v , v mod 2)
10: Priority
v
:=1-side
11: Want
v
[side]:=0
end procedure

Fiecrui nod i se asociaz o "seciune critic": (liniile 7 - 9) care include codul pentru entry (liniile 1 - 6) executat la toate nodurile de pe drumul de la printele nodului la
rdcin, seciunea critic real i codul exit (liniile 10 - 11) executat la toate nodurile de pe drumul de la rdcin la printele nodului.
Excludere mutual rapid

Algoritmul brutriei i algoritmul precedent au defectul c numarul de pai pe care un procesor l execut cnd ncearc s intre n seciunea critic depinde de n
chiar n absena competiiei pentru accesarea seciunii critice.
n sistemele reale este de ateptat ca n cazul competiiei pentru seciunea critic (accesul la un dispozitiv partajat de i/0, de ex) numarul competitorilor s fie relativ
mic n comparaie cu n.
Un algoritm de excludere mutual este rapid dac orice procesor intr n seciunea critic ntr-un numr constant de pai n cazul cnd el este singurul care ncearc
s intre n seciunea critic.

Algoritm de excludere mutual rapid
Initial Fast-lock i Slow-lock sunt 0 i Want |i| este false i {0, 1, ..., n-1}
(codul pentru proc. pi)
<Entry>:
1: Want |i|: =true
2: Fast-lock : =i
3: if Slow-lock 0 then
4: Want |i|: =false
5: wait until Slow-lock =0
6: goto 1
7: Slow-lock: =i
8: if Fast-lock i then // altfel, intr pe calea rapida
9: Want |i|: =false
10: for j, wait until Want |j|: =false
11: if Slow-lock i then // altfel, intr pe calea lent
12: wait until Slow-lock =0
13: goto 1
<Critical Section>
<Exit>:
14: Slow-lock : =0
15: Want |i|: =false
<Remainder>.

Un algoritm rapid necesit folosirea variabilelor partajate cu scriere multipl; dac fiecare variabil ar fi scris numai de un singur procesor, atunci un procesor care
ar dori s intre n seciunea critic trebuie s verifice cel puin n variabile pentru posibila competiie.
Algoritmul combin dou mecanisme: unul pentru a obine intrare rapid n seciunea critic cnd numai un singur procesor dorete s accead seciunea critic i
altul pentru a asigura inexistena deadlockului cnd exist competiie.
Un procesor poate intra n seciunea critic sau gsind Fast-lock = i (linia 8) sau gsind Slow-lock =i (linia 11).
Dac nici un procesor nu este n seciunea critic sau n seciunea entry, slow-lock = 0 i Want este false pentru toate componentele. Atunci cnd doar un singur
procesor p
i trece n seciunea entry, pune Want |i| pe true i Fast-lock pe i. Apoi verif Slow-lck care este 0. Apoi verif Fast-lock i cum nici un procesor nu-i n seciunea
critic, l gsete i i deci pi intr n seciunea critic pe calea rapid executnd 3 write i 2 read.
Nici un alt procesor nu poate intra n seciunea critic pe calea rapid pn pi nu iese din seciunea critic i reseteaz Slow-lock (linia 14).
Dac Fast-lock i atunci pi ateapt pn ce toate steagurile Want sunt coborte. Dup ce un procesor execut bucla for din linia 10, valoarea lui Slow-lock rmne
neschimbat pn ce un anumit procesor prsete seciunea critic i-l reseteaz. Deci cel mult un singur procesor pj poate gsi Slow-lock = j i acest procesor intr n
seciunea critic pe drumul lent.
Se poate verifica uor c dac un procesor pi intr n seciunea critic pe calea rapid, nici un alt proceosr py nu poate intra n seciunea critic pe o cale lent.

Observatii 1. Algoritmul nu garanteaz lipsa lockout-ului.
2. Se poate arta c orice algoritm pentru excluderea mutual care asigur lipsa deadlockului folosind variabilele R/W trebuie s foloseasc cel puin n variable partajate
indiferent de mrimea lor. Evident, se permite ca variabilele partajate s fie cu multi-write (altfel, marginea inferioar anunat e evident).

S-ar putea să vă placă și