Simulazione di lettura e scrittura concorrente
Tecnica dell’accelerated cascading
Lezione n°3
Algoritmi Avanzati
a.a.2011/2012
Prof.ssa Rossella Petreschi
Simulazione della lettura concorrente
(caso generale)
Problema: N processori P1, P2, …, Pn vogliono leggere il contenuto di K celle di memoria
(in generale K<N e non tutti i processori vogliono leggere dalla stessa locazione di memoria)
su una P-RAM di tipo EREW.
Algoritmo:
Passo 1: si costruisca M, vettore di coppie del tipo (Pi, Lj), ciascuna indicante che il
processore i-esimo vuole leggere la j-esima locazione di memoria (i=0…N-1, j=1…K).
Questo vettore viene ordinato in modo stabile, rispetto ai valori Lj (la stabilità garantisce
l’ordinamento delle coppie).
Passo 2: si raggruppino i processori rispetto alla comune locazione di memoria a cui
vogliono accedere, si individuino gli inizializzatori di ogni blocco e si conti il numero di
elementi in ogni blocco.
Passo 3: il primo processore di ogni blocco legge la locazione corrispondente e poi attiva
un’operazione di broadcast sul blocco.
Passo 4: tutti i processori in parallelo leggono l’informazione richiesta.
AA 2011-2012
2
PASSI 1 e 2
Passo 1:
for i = 0 to n-1 pardo
Pi:
M[ i ] = (i, Lj)
sort(M, loc);
// coppie (proc, loc)
Passo 2:
P0: iniz[ 0 ] = true; B[ 0 ] = 1
for i = 1 to n-1 pardo
Pi:
if M[ i ].loc  M[ i-1 ].loc then
iniz[ i ] = true; B[ i ] = 1
else
iniz[ i ] = false; B[ i ] = 0
PrefixSum(B, n)
Proc
0
1
2
3
4
5
Loc
8
3
3
9
8
3
Proc
1
2
5
0
4
3
Loc
3
3
3
8
8
9
iniz
T
F
F
T
F
T
B
1
0
0
1
0
1
B
1
1
1
2
2
3
Il vettore B è utilizzato per identificare il blocco di appartenenza di ogni processore
AA 2011-2012
3
PASSO 3
Invece di eseguire K broadcast differenti (uno per blocco) si esegue un
unico broadcast multiplo che tiene conto della separazione in blocchi
Passo 3: // Broadcast multiplo
for i = 0 to n-1 pardo
Pi:
if iniz[ i ] then
D[ i ] = contenuto di M[ i ].loc
iniz T
F
D x
B 1
for j = 0 to log n -1 do
D x
for i = 0 to n-1 pardo
Pi:
if iniz[ i ] and i+2j<n and B[ i ] = B[ i+2j ] then
D[ i+2j ] = D[ i ]
D x
iniz[ i+2j ] = true
D x
AA 2011-2012
F
T
F
y
1
1
x
T
z
2
2
3
y
y
z
x
x
y
y
z
x
x
y
y
z
4
PASSO 4
Passo 4:
for i = 0 to n-1 pardo
P i:
// chi aveva richiesto l’i-esimo dato
R[ M[ i ].proc ] = D[ i ]
// nel registro del proc i-esimo
// si carica il dato voluto
Ri = R[ i ]
Proc
1
2
5
0
4
3
Loc
3
3
3
8
8
9
D
x
x
x
y
y
z
R
y
x
x
z
y
x
Al termine ogni processore i avrà nel suo registro R il dato contenuto alla
locazione Lj inizialmente specificata.
Tempo Parallelo:
Passo 1: Tsort
Passo 2: Tprefixsum
Passo 3: logaritmico
Passo 4: costante
AA 2011-2012
5
Simulazione della scrittura concorrente
(caso generale)
Problema: N processori P1, P2, …, Pn vogliono scrivere i valori a1, a2, …, an
rispettivamente, in K diverse celle di memoria di una P-RAM di tipo EREW. In generale
K<N e si vuole 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 i-esimo 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.
AA 2011-2012
6
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
Proc
0
1
2
3
4
5
Loc
8
3
3
9
8
3
D
x
y
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
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
c
P5
P3
y
0
1
2
3
x
4
5
AA 2011-2012
6
7
8
a
9
7
Tecniche algoritmiche parallele di base
• Tecnica della prima metà: ad ogni passo si dimezza il numero di
elementi su cui si esegue la computazione. Si lavora nella prima metà
del vettore che da dimensione n si riduce progressivamente a
dimensione n/2, n/4, … fino a raggiungere la soluzione in O(log2n)
passi. (es. somma di n elementi, ricerca del massimo)
• Tecnica del salto del puntatore: in O(log2n) passi si ottiene la
soluzione raddoppiando ad ogni passo la distanza fra le coppie di
elementi su cui si opera.
(es. somme prefisse)
• Tecnica dell’accelerated cascading
• Tecnica del tour di eulero
AA 2011-2012
8
La tecnica del
Accelerated Cascading
Dato un problema P di dimensione n, siano A1 e A2 due algoritmi per
risolvere il problema P che operano rispettivamente in tempo T1e T2 (T1>
T2), si costruisce un nuovo algoritmo A nel seguente modo:
1.
si applica a P l’algoritmo A1(A1lavora per fasi) fintanto che l’output
delle fasi non produca una istanza P’ di P di dimensione minore di
una soglia prefissata;
2.
si applica a P’ l’algoritmo A2
E’ da notare che invece di un solo algoritmo di riduzione A1 si potrebbe
avere una catena di algoritmi di questo tipo. In tal caso si considera la
catena di algoritmi di riduzione ordinata dall’algoritmo più lento al più
veloce e si costruisce il nuovo algoritmo sostituendo il passo1 con
l’applicazione a P della catena così ordinata.
AA 2011-2012
9
Somma con la tecnica
dell’accelerated cascading
L’algoritmo di somma parallelo con la tecnica della prima metà non è ottimo
perché costa O(n log n) (ovvero n processori per log n tempo),mentre il miglior
algoritmo sequenziale richiede tempo O(n). La tecnica dell’accelerated cascading
ci permette di ridurre il costo dell’algoritmo parallelo a O(n) e quindi a
raggiungere valore dell’efficienza uguale ad 1.
La tecnica consiste nel dividere l’algoritmo in due fasi:
1° fase: si applica l’algoritmo sequenziale su k sotto-istanze del problema di
piccola dimensione h in modo da ridurre la dimensione totale dello intero
problema. Tempo parallelo O(h).
2° fase: si applica l’algoritmo parallelo con p processori sui k risultati del passo
precedente. Tempo parallelo O(log k)
Costo = O(p (h + log k))
AA 2011-2012
10
Algoritmo per la somma con la tecnica
dell’Accelerated Cascading
Si adoperano p processori
SommaAC(A, n)
begin
k=p
h = n/k
for i = 0 to k-1 pardo
Pi: bi = i * h
for j = 1 to h -1 do
if bi + j < n then A[ bi ] = A[ bi ] + A[ bi + j ]
B[ i ] = A[ bi ]
Somma(B, k)
end
// algoritmo di somma parallela standard
Tempo parallelo O(h + log k)
AA 2011-2012
11
Esempio di somma con la tecnica
dell’Accelerated Cascading
n = 12
P=4
P1
P0
24
1° fase
sequenziale
2° fase
parallela
32
size = 3
10
11
7
P2
16
9
45
P3
2
19
31
24
11
9
19
56
18
54
50
66
34
56
55
122
89
5
211
AA 2011-2012
12
Analisi dell’algoritmo SommaAC
Per ottenere costo Cp=O(n) e quindi Eff=1, dobbiamo scegliere O(n/log n)
processori, assegnando a ciascuno O(log n) elementi da sommare
sequenzialmente.
La 1° fase pertanto richiede tempo paralello O(log n) per generare
O(n/log n) elementi. Con O(n/log n) processori si opera con l’algoritmo di
somma parallelo su gli O(n/log n) elementi, impiegando un tempo
parallelo pari a:
log (n/log n) = log n – log log n = O(log n)
Costo totale = O(n/log n (log n + log n)) = O(n)
AA 2011-2012
13
Somme prefisse con
Accellerated Cascading
Si adoperano k processori
Per semplicità assumiamo n multiplo di k: n = h·k
begin
for i = 0 to k-1 pardo
Pi:
bi = i * h
// inizio blocco i-esimo
for j = 1 to h -1 do
A[ bi + j ] = A[ bi + j ] + A[ bi + j-1 ]
B[ i ] = A[ bi + h-1 ]
// l’ultimo del blocco
PrefixSum(B, k)
for i = 1 to k-1 pardo
Pi:
for j = 0 to h -1 do
A[ bi + j ] = A[ bi + j ] + B[ i-1 ]
end
Tempo parallelo O(h + log k)
AA 2011-2012
14