Documente Academic
Documente Profesional
Documente Cultură
Aceste caracteristici sunt subliniate prin notaţia specifică PRAM, care a fost
prezentată în capitolul 2 al lucrării.
Număr de procesoare
61
Algoritmul nu trebuie să depindă de un număr fix de procesoare.
Timp de execuţie
Cost
În cele ce urmează, c(n) este costul algoritmului c(n) = t(n) * p(n). Condiţiile sunt
următoarele:
- c(n) să fie minim
deci algoritmul să fie cost-optimal.
Exemplu
Algoritmul de selecţie a unei valori din secvenţa S = {s1, ..., sn}, prezentat mai
departe în acest capitol, se execută pe o maşină EREW SM SIMD cu N procesoare,
unde N<n. Algoritmul are proprietăţile formulate mai înainte.
(i) Algoritmul foloseşte p(n) = n1-x procesoare, cu 0<x<1, unde valoarea lui x se
obţine din formula N = n1-x. Deci, p(n) este subliniar şi adaptiv.
(ii) Algoritmul se execută în t(n) = O(nx), cu x obţinut ca mai sus. Deci, timpul de
execuţie este mai scurt decât cel al unui algoritm secvenţial. Totodată, algoritmul este
adaptiv: cu cât este mai mare p(n), cu atât este mai mic t(n).
(iii) Costul este c(n) = n1-x * O(nx) = O(n), ceea ce reprezintă un optim.
Observaţii
i) Satisfacerea cerinţelor menţionate este dificilă, uneori imposibilă.
ii) In practică, pentru valorile c(n), p(n), t(n) se consideră valorile rotunjite obţinute
printr-o estimare pesimistă.
62
4.2. Două proceduri utile
Două operaţii tipice apar în execuţia algoritmilor paraleli în sisteme EREW SIMD:
- fiecare procesor trebuie să citească conţinutul unei celule din memoria comună
(difuzarea unei valori);
- fiecare procesor trebuie să calculeze valoarea unei funcţii dependente de datele
deţinute de celelalte procesoare (calcule prefix).
Fie D celula din memoria comună ce trebuie difuzată celor N procesoare ale unui
sistem EREW SIMD. Algoritmul BROADCAST presupune folosirea unui tablou
A[1:N]. Acţiunile de citire şi de scriere sunt explicitate distinct şi explicit în
descrierea algoritmului. Acest tratament este specific sistemelor PRAM.
Pas 1: Procesorul P1
1.1. citeşte valoarea din D
1.2. o memoreaza în propria memorie
1.3. o scrie în A[1]
Pas 2: fa i := 0 to (log N -1) ->
fa j := 2i+1 to 2i+1 do in parallel
Procesor Pj
2.1. citeşte valoarea din A[j-2i]
2.2. o memorează în propria memorie
2.3. o scrie în A[j]
af
af
end
Observaţii
- Deoarece numărul de procesoare care deţin valoarea din D se dublează la fiecare
iteraţie, timpul de execuţie este O(log N).
- Dimensiunea tabloului A poate fi redusă la N/2, valorile memorate în ultimul pas
fiind inutile.
- Utilizare tipică: difuzarea lui n, în cazul algoritmilor adaptivi.
63
Calculul sumelor prefix
fa j = 0 to log N - 1 ->
fa i = 2j+1 to N do in parallel
Procesor P(i)
1. obţine A[i-2j] de la P(i-2j), prin memoria comună
2. A[i] := A[i-2j] + A[i]
af
af
end
Observaţie
- Deoarece numărul procesoarelor care termină de calculat suma parţială se dublează
la fiecare pas, calculul se face în O(log N) paşi folosind O(N) procesoare.
În cele ce urmează, prezentăm soluţia unei probleme de căutare a unei valori x într-o
secvenţă ordonată S de n valori, pentru o maşină SM SIMD. Pentru simplitate,
considerăm că elementele secvenţei sunt toate distincte între ele, adică:
s[1] < s[2] < ... < s[n].
Să considerăm mai întâi cazul unui sistem EREW format din N procesoare,
1<=N<=n. Pentru a face cunoscută valoarea x tuturor procesoarelor, se poate folosi un
algoritm de difuzare (broadcast) care are complexitatea O(log N). Secvenţa S este
divizată în N subsecvenţe de lungime n/N, fiecare subsecvenţă fiind atribuită unui
procesor. Folosind o procedură de căutare binară pe secvenţa atribuită, un procesor
găseşte rezultatul în O(log(n/N)) în cazul cel mai defavorabil. Timpul total cerut este
64
deci de ordinul O(log N) + O(log(n/N)) adică O(log n), acelaşi cu timpul necesar
căutării binare pe un procesor secvenţial.
În cazul unui sistem CREW, difuzarea valorii lui x se poate face într-un singur pas.
Mai mult, se poate adopta o politică de căutare diferită, obţinându-se o performanţă
mai bună pentru timpul de execuţie.
P1 P2 Pi Pi+1 PN
+-----------------------------------------------------------------+
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | S
+-----------------------------------------------------------------+
^ ^
g g
indici elemente ..... i(N+1) -1 (i+1)(N+1) -1 ....
|<----->|
g-1
dimensiune subinterval (N+1) -1
Figura 4.1
Fie g cel mai mic întreg astfel că n <= (N+1)g-1. Cu alte cuvinte, g =
sup(log(n+1)/log(N+1)). Se poate arăta prin inducţie că algoritmul are cel mult g
etape. Astfel, afirmaţia este banală pentru g=0.
Fie relaţia adevărată pentru (N+1)g-1-1.
Pentru a inspecta o secvenţă de lungime (N+1)g-1, procesorul Pi compară x cu s[j],
unde j = i(N+1)g-1, aşa cum se arată în figura 4.1. În urma comparaţiei, se reţine o
subsecvenţă de dimensiune (N+1)g-1-1, care (conform ipotezei de inducţie) se poate
inspecta în g-1 etape.
65
un sistem cu N procesoare poate acoperi în doi paşi o secvenţă de lungime cel mult
n2 = (N+1)2 -1 (vezi figura 4.2).
P1 P2 PN
+---------+
| | | | | | n1 = N
+---------+
P1 P2 PN
+---------+ +-++---------++-++---------+ +-++---------+
| | | | | | | || | | | | || || | | | | | | || | | | | |
+---------+ +-++---------++-++---------+ +-++---------+
|<--N+1 ---->|
|<-----------------------(N+1)(N+1) - 1 ---------------------->|
Figura 4.2
Exemplul 1
Pentru exemplificarea execuţiei algoritmului, fie secvenţa de numere dată în figura
4.3a şi x=45, N=3. Deoarece n=15, g este cel mai mic număr care satisface relaţia
(N+1)g >= n+1, adică 4g >= 16. Rezultă g=2. Lungimea unei subsecvenţe în primul
pas este egală cu 3. Rezolvarea este schiţată în figura 4.3.
P1 P2 P3
+--------------------------------------------+
| 1| 4| 6| 9|10|11|13|14|15|18|20|25|32|45|51| (a)
+--------------------------------------------+
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Figura 4.3a
66
P1 P2 P3
+--------+
|32|45|51| (b)
+--------+
13 14 15
Figura 4.3b
Exemplul 2
Să considerăm o a doua execuţie, cu N=2, x=21. Deci, din relaţia (N+1)g>=n+1
rezultă 3g>=16, deci g=3. Lungimea unei subsecvenţe în primul pas este egală cu 8.
Rezolvarea este schiţată în figura 4.4.
P1 P2
+-----------------+
|18|20|25|32|45|51| (b)
+-----------------+
10 11 12 13 14 15
P1 P2
+-----+
|18|20| (c)
+-----+
10 11
Figura 4.4
Pentru a determina subintervalul care rămane în fiecare etapă, fiecare proces Pi,
1<=i<=N utilizează o variabilă c[i] care ia una din valorile stg sau dr, după cum
trebuie reţinută partea din stanga, respectiv cea din dreapta. În plus, se folosesc
c[0]=dr şi c[N+1]=stg. Iniţial limitele subsecvenţei de căutare sunt q=1 şi r=n. De
asemenea, g are iniţial valoarea numărului maxim de etape
g = sup(log(n+1)/log(N+1))
şi scade cu o unitate la fiecare iteraţie.
Algoritmul calculează valorile c[i] şi găseşte i pentru care c[i-1]<>c[i]. Pe baza lui se
determină următorul subinterval [q,r] de căutare. Mai precis,
67
q := q+(i-1)(N+1)g-1+1, iar
r := q+i(N+1)g-1 -1.
Un singur procesor calculează noile valori pentru q şi r, celelalte având acces la
aceste valori în timp constant.
În descrierea ce urmează sunt marcate cele trei etape ale algoritmului, precum şi paşii
care-i compun.
Observaţie
Operaţiile paralele din algoritm se execută în acelaşi timp în toate procesoarele.
Operaţiile secvenţiale sunt executate de un singur procesor.
P1 P2 P3
+--------------------------------------------+
| 1| 4| 6| 9|10|11|13|14|15|18|20|25|32|45|51| (a)
+--------------------------------------------+
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
P1 P2 P3
+--------+
|32|45|51| (b)
+--------+
13 14 15
Figura 4.5
P1 P2
+-----+
|18|20| (c)
+-----+
10 11
Figura 4.6b,c
În a treia iteraţie, j1 este 10, P1 calculand c[1] = dr, deoarece 21>18. Similar, P2
calculează c[2] = dr, deoarece 21>20. Ca urmare q capătă valoarea 12, mai mare
decât valoarea lui r provocând astfel ieşirea din ciclu cu k=0.
Observaţii
Deoarece pasul 3 al algoritmului precedent se execută de cel mult g ori, rezultă că
algoritmul are complexitatea t(n) = O(logN+1(n+1)). Lucrul efectuat de algoritm
este O(N logN+1(n+1)), deci algoritmul nu este cost-optimal. Cu toate acestea, se
poate arăta că el este optim din punct de vedere al timpului de calcul. Pentru a arăta
acest lucru, să observăm că, folosind N procesoare, algoritmul poate compara x cu
cel mult N valori s[i], la un moment dat. După aceste comparaţii şi după
eliminarea din secvenţă a elementelor despre care se ştie că nu sunt egale cu x,
lungimea subsecvenţei rămase este de cel puţin:
sup((n-N)/(N+1)) >= (n-N)/(N+1) = [(n+1)/(N+1)]-1.
După g repetiţii, secvenţa rămasă este de lungime
[(n+1)/(N+1)g]-1.
Deci, numărul de iteraţii cerute de orice algoritm paralel trebuie să fie mai mare de
cel mai mic g pentru care avem:
[(n+1)/(N+1)g]-1 <=0, adică
g = sup(log(n+1)/log(N+1)).
În cazul în care N=n problema este rezolvată în timp constant.
70
În privinţa cerinţei ca toate elementele secvenţei S să fie distincte, ea poate fi
înlăturată dacă actualizarea lui k la găsirea unei coincidenţe este realizată printr-o
procedură specială care evită conflictele de acces simultan (modelele folosite până
acum sunt cu scriere exclusivă). Această procedură ia un timp O(log N), mărind
astfel timpul de execuţie al algoritmului la:
t(n) = O(log(n+1)/log(N+1)) + O(log N).
Putem aprecia importanţa acestui timp suplimentar dacă luăm cazul N=n, în care nu
se realizează nici o îmbunătăţire faţă de algoritmul secvenţial.
Menţinerea eficienţei algoritmului în cazul în care în şir pot exista valori egale se
poate realiza prin folosirea unui model CRCW. În acest caz, este posibil ca la un
conflict (mai multe elemente egale cu x se află în secvenţa S), doar cea mai mică
valoare a indicilor elementelor respective să fie dată lui k.
Consideraţii
(1) Se dau:
- o secvenţă de numere întregi, S = {s1,...,sn} şi
- un intreg k, 1<=k<=n.
Se cere:
- cel de al k-lea număr în ordine crescătoare.
Limita de complexitate
Secvenţa se consideră neordonată, selecţia făcându-se fără ordonarea ei prealabilă.
Pentru selecţie, fiecare valoare a şirului trebuie inspectată cel puţin o dată. Aceasta
stabileşte limita inferioară a complexităţii algoritmului secvenţial la OMEGA(n),
care este totodată limita inferioara pentru costul algoritmului paralel.
71
Se împarte S în subsecvenţe de câte 5 elemente (se va arăta mai departe de ce 5!). Se
află medianele grupurilor de 5 elemente:
M: 14 22 9 14 25 32
Se calculează mediana medianelor, m = 14.
Se împarte secvenţa S în trei subsecvenţe, S1, S2 şi S3, cu elemente mai mici, egale
şi mai mari decat m, respectiv.
S1: 3 8 12 1 4 9 10 5 13 7 2
S2: 14 14 14
S3: 16 20 31 22 33 24 26 18 34 25 27 32 35 33
Deoarece |S1|=11 şi |S2|=3, al 21-lea element se află în S3. Se reţine S3 în care se
caută al 21-14= 7-lea element.
Analiza complexitătţi este făcută considerând paşii algoritmului, unul după altul.
Pas 1. Deoarece Q este constantă, sortarea lui S când |S|<Q ia un timp constant.
Altfel, împărţirea lui S ia timpul c1*n (c1 constanta).
Pas 2. Fiecare subsecvenţă de Q elemente poate fi sortată în timp constant. Deci etapa
durează c2*n (c2 constanta).
Pas 4. O trecere prin S creează subsecvenţele S1, S2, S3. Deci pasul durează un timp
c3*n (c3 constanta).
Pas 5. Deoarece m este mediana a |S|/Q elemente, există |S|/(2Q) elemente mai mari
sau egale cu ea. Fiecare din cele |S|/Q elemente este la rândul său mediana unui set
de Q elemente, deci are Q/2 elemente mai mari sau egale cu el. Rezultă că
(|S|/(2Q))*(Q/2)=|S|/4 elemente ale lui S sunt mai mari sau egale cu m. Ca urmare,
|S1|<=3|S|/4. Printr-un raţionament similar, |S3|<=3|S|/4. Ca urmare, un apel
recursiv în acest pas al procedurii SEQUENTIAL_SELECT cere un timp t(3n/4).
Din analiza precedentă avem
t(n) = c4n + t(n/Q) + t(3n/4), cu c4 = c1+c2+c3.
Valoarea celui de al k-lea element este întoarsă fie în S[1], fie într-un argument
suplimentar al procedurii, în cazul de faţă elk.
74
Exemplu
Analiza complexităţii.
Considerăm, pe rând, fiecare pas al procedurii.
Pas 5. Dimensiunea lui L necesară în acest pas a fost obţinută în pasul 4 prin
calculul lui z[n1-x]. La fel pentru dimensiunile lui E si G. Acum trebuie să
determinăm cât timp ia fiecare din cei doi paşi recursivi. Deoarece m este mediana
lui M, cu siguranţă n1-x/2 elemente din S sunt mai mari decât m. Mai mult, fiecare
element din M este mai mic decât cel putin nx/2 elemente din S. Astfel, |L| <= 3n/4.
Similar, |G| <= 3n/4. Ca urmare, pasul 5 cere cel mult un timp t(3n/4).
76
Costul este deci optimal. De notat că nx este asimptotic mai mare decat log n, pentru
orice x. Deoarece N = n1-x si n/nx < n/log n, rezultă că PARALLEL_SELECT
este optimal cu condiţia ca N < n/log n.
Observaţie
Algoritmul precedent a fost obţinut prin paralelizarea unui algoritm secvenţial.
Nu întotdeauna acest procedeu conduce la rezultate optime, uneori fiind necesar
ca proiectantul să ignore soluţia secvenţială şi să exploateze paralelismul inerent al
problemei. Aceasta abordare poate conduce la îmbunătăţirea celei mai bune soluţii
secvenţiale cunoscute.
77