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