Lezione n°4
Algoritmi Avanzati
a.a.2015/2016
Prof.ssa Rossella Petreschi
Simulazione della scrittura concorrente:
stessa informazione
Sia dato un algoritmo per PRAM CW con scrittura concorrente di valori identici. L’operazione compiuta da tutti
i processori di scrivere nella stessa locazione R viene simulata su PRAM EW dal solo processore P0, dopo aver
controllato che tutti i valori ai scritti dai rispettivi Pi siano uguali*. Questo controllo si effettua usando un vettore
A con tutti i valori da scrivere e un vettore di booleani utilizzato per riportare le eventuali diversità nei valori di
A:
for j = 0 to n-1 pardo
Pj:
A[ j ] = aj; B[ j ] = true
for i = 1 to log n do
for j = 0 to (n/2i -1) pardo
Pj:
if A[ j ]  A[ j+ n/2i ] or not B[ j ] or not B[ j+ n/2i ] then
B[ j ] = false
P0: if B[ 0 ] then R = A[ 0 ]
Il tempo parallelo richiesto è O(log n)
* Questo controllo su PRAM CW si suppone effettuato a livello hardware
Simulazione della scrittura concorrente:
funzione dei valori
La simulazione di PRAM CW con scrittura del massimo valore (o della
somma o di qualsiasi altra funzione commutativa f dei valori) viene eseguita su
PRAM EW semplicemente utilizzando la tecnica della metà per il computo di f
su un vettore A:
for j = 0 to n-1 pardo
Pj:
A[ j ] = aj
for i = 1 to log n do
for j = 0 to (n/2i -1) pardo
Pj:
A[ j ] = f ( A[ j ], A[ j+ n/2i ] )
P0: R = A[ 0 ]
Con lo stesso schema si può simulare anche la scrittura concorrente basata su
priorità (ad esempio in funzione dell’indice del processore che vuole scrivere).
In entrambi i casi la simulazione richiede tempo parallelo logaritmico.
Simulazione della scrittura concorrente
(caso generale)
Problema: N processori P1, P2, …, Pn vogliono scrivere i valori d1, d2, …, dn in K diverse celle di
memoria di una P-RAM di tipo EREW, in generale K<N . I valori d1, d2, …, dn sono contenuti in
un vettore D dato in input.
Sivuole simulare la concorrenza con priorità (scrive il processore di indice minore).
Algoritmo:
Idea analoga a quello visto per il caso generale di lettura concorrente
Passo 1: si costruisca M, vettore di coppie del tipo (Pi, Lj), ciascuna indicante che il processore iesimo vuole scrivere nella j-esima locazione di memoria (i=0…N-1, j=1…K) il dato memorizzato
nel vettore D (i-esima locazione). Questo vettore viene ordinato in modo stabile, rispetto ai valori
di Lj.
Passo 2: si raggruppino i processori rispetto alla comune locazione di memoria a cui vogliono
accedere e si individuino gli inizializzatori di ogni blocco.
Passo 3: in ogni blocco, il processore di indice minore (il primo del blocco) scrive la sua
informazione nella locazione di memoria caratterizzante il blocco.
Esempio di scrittura concorrente
Passo 1:
analogo
Passo 2:
P0: iniz[ 0 ] = true
for i = 1 to n-1 pardo
Pi:
if M[ i ].loc  M[ i-1 ].loc then iniz[ i ] = true
else iniz[ i ] = false
Passo 3:
for i = 0 to n-1 pardo
Pi:
if iniz[ i ] then
scrivi D[ M[ i ].proc ] in M[ i ].loc
D
x
y
z
P0
Memoria
a
b
1
2
3
5
1
2
3
4
5
Loc
8
3
3
9
8
3
D
x
x
z
a
b
c
Proc
1
2
5
0
4
3
Loc
3
3
3
8
8
9
iniz
T
F
F
T
F
T
P5
P3
x
4
0
c
y
0
Proc
6
7
8
a
9
Rete combinatoria
Una rete combinatoria C può essere vista come un grafo diretto aciclico GC
avente un nodo per ciascun elemento combinatorio c e un arco diretto (c',c") se
l’output di c' è input di c".
La dimensione di una rete combinatoria è il numero di nodi del grafo e la
profondità è il diametro del grafo.
Il fan-in di un elemento c è il grado entrante del nodo c in GC e corrisponde al
numero di input dell’elemento.
Il fan-out di un elemento c è il grado uscente del nodo c in GC.
È da notare che non necessariamente il numero di output di un elemento
combinatorio è uguale al suo fan-out, infatti un elemento combinatorio con un
solo filo di output può “servire” un numero qualunque di altri elementi.
Elemento combinatorio
Def: Un elemento combinatorio è un qualunque elemento di
circuito che abbia un numero costante di input e output e che
esegua una funzione ben precisa.
Esempi:
– Porte logiche
– Comparatore
– ecc…
not
x
y
and
comp
or
min{x, y}
max{x, y}
Più elementi combinatori possono essere collegati tra di loro
formando una rete combinatoria dove l'output di un elemento
può essere l'input di uno o più altri elementi.
Teorema di Brent
Teorema (CREW): ogni algoritmo che lavora su una
rete combinatoria di profondità d e dimensione n che
sia a fan-in limitato, può essere simulato da un
algoritmo che lavora su una PRAM CREW con p
processori in O(n/p+d) tempo.
Teorema (EREW): ogni algoritmo che lavora su una
rete combinatoria di profondità d e dimensione n che
sia a fan-in e fan-out limitato, può essere simulato da
un algoritmo che lavora su una PRAM EREW con p
processori in O(n/p+d) tempo.
Teorema di Brent - Esempio
Profondità: d = 5
Dimensione: n = 22
Processori: p = 3
Dimostrazione del teorema di Brent
•Modelli di calcolo:
- PRAM-EW con p processori p0, p1, …, pp-1.
- Rete combinatoria C di profondità d e dimensione n = ∑ni , i=1..d, con ni
numero di elementi al livello i.
L’input del circuito combinatorio si considera disponibile nella memoria
condivisa. Il fan-in limitato evita che la memoria condivisa non sia sufficiente a
memorizzare i risultati intermedi del calcolo.
•Idea della dimostrazione: Ogni processore simula un componente del primo
livello della rete e fornisce l’output che può essere immagazzinato nella memoria
condivisa. Si ripete l’operazione per un numero di volte pari alla profondità del
circuito utilizzando l’output di ogni livello come input del livello successivo. Nel
caso in cui p sia minore del massimo numero di elementi combinatori presenti in
uno stesso livello, si dovrà effettuare un numero di passi seriali proporzionale al
rapporto tra il numero di elementi del livello i e p.
Modelli CREW ed EREW nel Teorema di Brent
• La complessità tiene conto della profondità del circuito e dei passi seriali necessari a
simulare un livello.
• Tp = ∑ ⎡ni /p⎤ ≤ ∑ (ni /p +1) = n / p + d
con i=1..d
• Abbiamo detto che il processore che simula l’elemento combinatorio fornisce l’output
che può essere immagazzinato nella memoria condivisa. Se più processori richiedono
in input quello stesso valore si deve accettare che la P-RAM sia a lettura concorrente.
Se si accetta l’ipotesi che anche il il fan-out sia limitato, si può considerare che in
tempo costante l’output del circuito combinatorio sia direttamente copiato nell’input
dei circuiti che lo richiedono. Questa limitazione permetterebbe la simulazione su una
P-RAM a lettura esclusiva.
Trasportabilità fra P-RAM con diverso numero
di processori
Teorema (p' < p): ogni algoritmo A che lavora in tempo parallelo O(t) su
una PRAM con p processori può essere simulato da un algoritmo A' che
lavora su una PRAM con p' processori (p' < p) in tempo O(t p / p').
Dimostrazione: durante ognuno dei t passi dell’esecuzione di A, i p
processori lavorano parallelamente in tempo O(1). Durante ogni passo
della esecuzione di A', ciascuno dei p'<p processori eseguirà un blocco
seriale di p/p' operazioni in tempo O(p/p'). Pertanto il tempo parallelo
relativo alla esecuzione di A' sarà O(tp/p').
Il costo dei due algoritmi A e A' rimane pari a O(tp).
Circuiti di ordinamento
Utilizziamo il comparatore, ossia un circuito di confronto con due ingressi e due
uscite il cui valore è la coppia di valori in input ordinati in modo ascendente.
x
min(x,y)
y
max(x,y)
I circuiti formati da comparatori, se opportunamente combinati, costituiscono
un'architettura in grado di ordinare n valori di input.
9
5
2
2
5
9
7
5
5
2
2
5
7
7
7
7
9
9
Insertion Sort
Due architetture per implementare l'insertion sort (tra 8 valori in input):
Questa macchina utilizza una
versione seriale dell'algoritmo di
complessità O(n2) (indicata dalla
profondità del circuito, ossia il
numero di porte che vengono
attraversate in tempi differenti).
È
possibile
ottenere
una
complessità O(n) ottimizzando lo
scheduling dei comparatori e
parallelizzando l'algoritmo.
Sulla monotonicità
Se un circuito di ordinamento trasforma la sequenza di input a = (a1, a2,
…, an) nella sequenza di output b = (b1, b2, …, bn), allora per ogni
funzione monotona crescente f, il circuito trasforma la sequenza di input
f(a) = (f(a1), f(a2), …, f(an)) nella sequenza di output f(b)=(f(b1), f(b2), …,
f(bn)).
Tale proprietà è facilmente verificata da un singolo comparatore e per
induzione la si può provare per un intero circuito di ordinamento.
x
min(x,y)
f(x)
min(f(x), f(y))) = f(min(x,y))
y
max(x,y)
f(y)
max(f(x), f(y))) = f(max(x,y))
Principio 0/1
Teorema (principio 0/1): se un circuito combinatorio di ordinamento lavora
correttamente per qualunque input costruito sull'alfabeto {0,1} allora lavora
correttamente per qualunque input costruito su di un qualsiasi alfabeto finito A.
Dim: supponiamo per assurdo che il circuito ordini tutte le sequenze costruite
sull'alfabeto {0,1} correttamente, ma che esista una sequenza di input di
numeri arbitrari a = (a1, a2, …, an) contenente elementi ai e aj tali che ai < aj
mentre il circuito pone aj prima di ai nella sequenza di output. Definiamo una
funzione f monotona crescente come:
•f(x) = 0 se x <= ai
•f(x) = 1 se x > ai
dal lemma precedente segue che il circuito sistema f(aj) prima di f(ai) nella
sequenza di output quando f(a) è l'input. Ma poiché f(aj) = 1 mentre f(ai) = 0,
neghiamo l'ipotesi giungendo ad un assurdo.
Sequenze bitoniche
Una Sequenza Bitonica è una sequenza che può essere divisa in due sottosequenze
monotone, una crescente e l'altra decrescente o viceversa.
Sono bitoniche le due sequenze:
•m(S) = (min{s1,sn+1}, min{s2,sn+2}, …, min{sn,s2n})
•M(S) = (max{s1,sn+1}, max{s2,sn+2}, …, max{sn,s2n})
ottenute dalla sequenza bitonica S = s1, s2, …, s2n
Sfruttando la definizione di m(S) ed M(S) e le relative proprietà si può ottenere una
definizione ricorsiva per le sequenze bitoniche che ci permette di realizzare un primo
algoritmo di ordinamento che opera ricorsivamente secondo lo schema:
S=13896554
S1 = m(S) = 1 3 5 4
S2 = M(S) = 6 5 8 9
S3 = m(S1) = 1 3 S4 = M(S1) = 5 4
S5 = m(S2) = 6 5 S6 = M(S2) = 8 9
13
45
56
89
Complessità O(log(n)).