Esempi di programmi paralleli

annuncio pubblicitario
Esempi di Applicazioni Parallele
e di Metodologie di parallelizzazione
Esempi Applicazioni Parallele
• Applicazioni embarassing parallel
Metodo di parallelizzazione
Es.. Calcolo del π
Task farm statico
• Applicazioni con computazioni regolari su ciascun elemento del dominio
Es., Prodotto di matrici dense
Decomposizione geometrica
Es., Metodi delle differenze finite per la soluzione di PDE
• Applicazioni con computazioni non regolari sugli elementi del dominio
Es., Fattorizzazione LU (domini densi)
Decomposizione a grana fine
Es., Simulazione di modelli oceanografici
• Applicazioni intrinsecamente dinamiche
Es. N-queen problem, problemi di ottimizzazione
Task farm dinamico
Es. Problemi di dinamica molecolare, N-body
Riconfigurazione dinamica
Michele Colajanni – Esempi programmi paralleli
2/51
1
Task farm statico: Calcolo del π
f(x) =
4
1+ x2
4
ð = ∫ f(x) dx
1
f
0
π = area under f(x)
π= a r e a s o t t e s a d a f ( x )
n
Rn(f) = h∑ f(xi )
i =1
h = 1/n
Regola del rettangolo
0
0
Ampiezza dell’intervallo
xi = h(i − 0.5 )
Punti intermedi
Michele Colajanni – Esempi programmi paralleli
3/51
Regola dei rettangoli
Michele Colajanni – Esempi programmi paralleli
4/51
2
Decomposizione per la regola dei rettangoli
In verde, i domini assegnati
al processo 0
0
1
2
3
0
1
2
3
0
1
2
3
0
1
2
3
0
1
2
3
5/51
Michele Colajanni – Esempi programmi paralleli
Calcolo del
π (versione sequenziale)
#include <math
<math.h>
.h>
main()
main()
{int n, i;
double PI25DT = 3.141592653598793238462643;
double h, sum,
sum, pi;
while (1)
{printf(“
printf(“Enter
Enter the number of intervals”);
intervals”);
scanf(“%d,
scanf(“%d, &n”);
if (n == 0) break;
else
{ h=1.0/(double) n;
sum=0.0;
for (i=1; i<=n; i++)
{ x=h*((double) ii-0.5);
sum=sum+(4.0/(1.0+x*x));
}
pi=h*sum;
printf(“pi
printf(“pi is approximately %.16f”, pi);
}
}
}
Michele Colajanni – Esempi programmi paralleli
6/51
3
Funzioni MPI utilizzate nel “Calcolo
π”
int M P I _ I n i t (int * argc, char**a r g v )
int M P I _ C o m m _ s i z e ( M P I _ C o m m c o m m , int *size)
int M P I _ C o m m _ r a n k ( M P I _ C o m m c o m m , int *rank)
int M P I _ B c a s t ( void * buf, int count, M P I _ D a t a t y p e d a t a t y p e , M P I _ O p o p , int root, MPI_C o m m c o m m )
int M P I _ F i n a l i z e ( void)
Funzioni di temporizzazione
double M P I _ W t i m e ( void) ~ secondi
double M P I _ W t i c k ( void) ~ tempo in secondi tra due tick del clock
Uso:
• Una chiamata all’inizio della parte computazionale
• Una chiamata alla fine della parte c o m p u t a z i o n a l e
• Evitare di considerare l’INPUT iniziale e l’OUTPUT finale per il calcolo dello SPEEDUP
Michele Colajanni – Esempi programmi paralleli
Calcolo del
7/51
π (versione parallela - MPI)
#include “mpi
“mpi.h”
.h”
#include <math
<math.h>
.h>
char *argc[];
argc[];
{int n, myid,
myid, numprocs,
numprocs, i, rc;
rc;
double PI25DT= 3.141592653598793238462643;
Task farm implementato come
double mypi,
mypi, pi, h, sum,
sum, x, a;
MPI_Init
MPI_Init(&
(&argc
argc,
, &argv
&argv);
);
Programma SPMD
MPI_Comm
MPI_Comm_
_size(MPI_COMM_WORLD,
size(MPI_COMM_WORLD, &numprocs
&numprocs);
);
MPI_Comm
MPI_Comm_
_rank(MPI_COMM_WORLD,
rank(MPI_COMM_WORLD, &myid
&myid);
);
while (1)
{if (myid == 0)
{printf(“
printf(“Enter
Enter the number of intervals:
intervals: (0 quits)
quits) “);
scanf(“%d”,
scanf(“%d”, &n);
}
MPI_Bcast
MPI_Bcast(&n,
(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);
if (n == 0) break;
else
{ h=1.0/(double
h=1.0/(double)
) n;
sum=0.0;
sum=0.0;
for (i=myid
(i=myid+1;
+1; i<=n; i+=numprocs
i+=numprocs)
)
{ x=h*((double
x=h*((double)
) ii-0.5);
sum+=(0.4/(1.0+x*x));
sum+=(0.4/(1.0+x*x));
}
mypi=h*
mypi=h*sum
sum;
;
MPI_Reduce(&myip
MPI_Reduce(&myip,
, &pi, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
if (myip == 0)
printf(“pi
printf(“pi is approximately %.16f, Error is %.16f\
%.16f\n”, pi, fabs(pi
fabs(pi-PI25DT));
}
}
MPI_Finalize
MPI_Finalize();
();
}
Michele Colajanni – Esempi programmi paralleli
8/51
4
D e c o m p o s i z i o n e a g r a n a f i n e : Fattorizzazione LU
Versione sequenziale
for k = 1 to n- 1 do
for s = k + 1 to n do
ls k = a s k / a kk
/*calcolo dei
moltiplicatori*/
f o r j = k + 1 t o n do
f o r i = k + 1 t o n do /*Aggiornamento della
a i j = a i j -l i k a kj
sottosotto-matrice Ak */
(k,k)
Ak
1 ° p r o b l e m a d e l l a parallelizzazione S P M D : C o m e d e c o m p o r r e l a m a t r i c e ?
9/51
Michele Colajanni – Esempi programmi paralleli
Decomposizione del dominio (row oriented)
Ak
Ak
BLOCK MAPPING
WRAP MAPPING
(CYCLIC)
Ak
REFLECTION MAPPING
Michele Colajanni – Esempi programmi paralleli
10/51
5
Fattorizzazione LU parallela (c o l u m n o r i e n t e d )
Ak
Algoritmo SPMD (column)
WRAP COLUMN MAPPING
for k=1 to n-1 do
if (k in mycolumns)
mycolumns) then
for i=k+1 to n do
lik=aik/akk
broadcast(
broadcast(columnk) ß lik
else
receive(
receive(columnk)
ß lik
for j=k+1 to n do
if (j in mycolumns)
mycolumns) then
for i=k+1 to n do
aij=aij-likakj
11/51
Michele Colajanni – Esempi programmi paralleli
Fattorizzazione LU parallela (r o w oriented)
for k=1 to n-1 do
for i=k+1 to n do
lik=aik/akk /*calcolo dei moltiplicatori*/
for i=k+1 to n do
for j=k+1 to n do
aij=aij-likakj /*aggiornamento elementi di A*/
(k,k)
Ak
La decomposizione a blocchi di righe
ha un problema evidente. Quale?
Algorimo SPMD (row)
for k=1 to n-1 do
if (k in mynode)
mynode)
then broadcast(
broadcast(rowk)
else receive(
receive(rowk)
for all (i>k in mynode)
mynode) do
iik=aik/akk
Si sceglie la decomposizione per
righe ciclica
Michele Colajanni – Esempi programmi paralleli
for all (i>k in mynode)
mynode) do
for j=k+i to n do
aij=aij-likakj
12/51
6
Fattorizzazione con Column Pivoting
for k=1 to n-1 do
/*column
/*column partial pivoting*/
pivoting*/
if (<I own columnk>) then <search for pivotk in mycolumnk>
if (manager=mynode
manager=mynode)
) then < send pivot index>
index>
else receive(pivot
receive(pivot index)
index)
if (k≠
(k≠pivot index)
index) then <swap(
swap(columnk, columnpivot)>
/*LU
/*LU Factorization*/
Factorization*/
if (<I own rowk>) then <send myrowk>
else receive(
receive(myrowk)
if (<I own columnk>) then <compute and send mymultiplyersk>
else receive(
receive(mymultiplyersk)
for all(<i
all(<i≥
≥k+1 in myrowi>) do
for all (<j≥
(<j≥k+1 in mycolumnj>) do
aij=aij-likakj
Michele Colajanni – Esempi programmi paralleli
13/51
Decomposizione geometrica
Dominio di
Ω 2: griglia N*N punti distribuita su griglia L*L:
Ad ogni passo
=
F
D o p o o g n i p a s s o s c a m b i o d i v a l o r i d e l l e a r e e d i overlap
T calc = ( N / L ) 2
T comm = N / L
T comm / T calc ≈ L / N
Michele Colajanni – Esempi programmi paralleli
14/51
7
Algoritmo di Jacobi
Si consideri un’equazione differenziale alle derivate parziali ellittica, per cui si vuole
determinare la soluzione allo stato stabile.
U n a n o t a t e c n i c a r i s o l u t i v a ( i t e r a t i v a ) è quella che utilizza il M e t o d o d i J a c o b i .
Dato come dominio una griglia di N*N punti, a ciascun
passo iterativo, ogni punto della griglia viene aggiornato
con una combinazione lineare dei punti della griglia
adiacenti (calcolati al passo precedente):
k +1
xi
=−
1
an
(
∑a
j ≠i
k
ij x j
− bi )
i =1, … , n
k =0, 1, …
Componente da aggiornare al passo k+1
Componenti aggiornate al passo k con cui si aggiorna l’elemento (i,j)
15/51
Michele Colajanni – Esempi programmi paralleli
Algoritmo JACOBI
int i, j;
Algoritmo sequenziale
double u[n][n], unew[n][n];
unew[n][n];
for (j=0; j++; j<n)
for (i=0; i++; i<n)
unew[i][j]=0.25*(u[i
unew[i][j]=0.25*(u[i-1][j])+u[i][j+1]+u[i][j1][j])+u[i][j+1]+u[i][j-1]+u[i+1][j])1]+u[i+1][j])-h*h*f(i,j)
Processo 2
i,j+1
Decomposizione del
dominio dei dati:
per blocchi di righe
Halo
i-1,j
i+1,j
Processo 1
i,j-1
Processo 0
Michele Colajanni – Esempi programmi paralleli
16/51
8
Jacobi: Algoritmo Parallelo MPI-Fortran
Get a new communicator for a decomposition of the domain and my position in it
call MPI_CART_CREATE(MPI_COMM_WORLD, 1, numprocs, .false., .true., comm1d, ierr)
call MPI_COMM_RANK(cimm1d, myid, ierr)
call MPI_CART_SHIFT(comm1d, 0, 1, nbrbottom, nbrtop, ierr)
compute the actual decomposition
call MPE_DECOMP1D(ny, numprocs, myid, s, e)
initialize the right-hand-side (f) and the initial solution guess (a)
call ONEDINIT(a, b, f, nx, s, e)
actually do the computation. Note the use of a collective operation to check for
convergence, and a do-loop to bound the number of iterations.
do 10 it=1, maxit
get ghost points
call EXCHNG1(a,
EXCHNG1
nx, s, e, comm1d, nbrbottom, nbrtop)
perform one Jacobi “sweep”
call SWEEP1D(a, f, nx, s, e, b)
repeat to get a solution back into array a
call EXCHNG1(b, nx, s, e, comm1d, nbrbottom, nbrtop)
call SWEEP1D(b, f, nx, s, e, a)
check for convergence
call MPI_ALLREDUCE(diffw, diffnorm, 1, MPI_DOUBLE_PRECISION, MPI_SUM, comm1d, ierr)
if (diffnorm .lt. 1.0e-5) goto 20
if (myid .eq. 0) print *, 2*it, ‘Difference is ‘, duffnorm
continue
if (myid .eq. 0) print ‘Failed to converge’
continue
if (myid .eq. 0) then
print *, ‘Converged after ‘, 2*it, ‘Iterations’
endif
Michele Colajanni – Esempi programmi paralleli
17/51
(1) Routine per Scambio Messaggi in Jacobi
subroutine exchng1(a, nx,
nx, s, e, comm1d, nbrbottom,
nbrbottom, nbrtop)
nbrtop)
include “mpif.h”
integer nx, s, e
double precision a(0:nx+1, s-1:e+1)
integer comm1d, nbrbottom, nbrtop
integer status(MPI_STATUS_SIZE), ierr
call MPI_SEND (a(1,e), nx, MPI_DOUBLE_PRECISION, nbr, 0, comm1d, ierr)
call MPI_RECV (a(1,s-1), nx, MPI_DOUBLE_PRECISION, nbrbottom,
0, comm1d, status, ierr)
call MPI_SEND (a(1,s), nx, MPI_DOUBLE_PRECISION, nbrbottom,
1, comm1d, ierr)
call MPI_RECV (a(1,e+1), nx, MPI_DOUBLE_PRECISION, nbrtop, 1,
comm1d, status, ierr)
return
end
Michele Colajanni – Esempi programmi paralleli
18/51
9
(2) Routine per Scambio Messaggi in Jacobi
(u s o d i c o p p i e d i S E N D / R E C E I V E )
subroutine exchng1(a, nx,
nx, s, e, comm1d, nbrbottm,
nbrbottm, nbrtop)
nbrtop)
include “mpif.h”
integer nx, s, e
double precision a(0:nx+1,s-1:e+1)
integer comm1d, nbrbottom, nbrtop, rank, coord
integer status(MPI_STATUS_SIZE), ierr
call MPI_COMM_RANK(comm1d, rank, ierr)
call MPI_CART_COORDS(comm1d, rank, 1, coord, ierr)
if (mod(coord, 2) .eq. 0) then
call MPI_SEND(a(1,e), nx, MPI_DOUBLE_PRECISION, nbrtop, 0, comm1d, ierr)
call MPI_RECV(a(1,s-1) nx, MPI_DOUBLE_PRECISION, nbrbottom, 0, comm1d, status, ierr)
call MPI_SEND(a(1,s), nx, MPI_DOUBLE_PRECISION, nbrbottom, 1, comm1d, ierr)
call MPI_RECV(a(1,e+1), nx, MPI_DOUBLE_PRECISION, nbrtop, 1, comm1d, status, ierr)
else
call MPI_RECV(a(1,s-1) nx, MPI_DOUBLE_PRECISION, nbrbottom, 0, comm1d, status, ierr)
call MPI_SEND(a(1,e), nx, MPI_DOUBLE_PRECISION, nbrtop, 0, comm1d, ierr)
call MPI_RECV(a(1,e+1), nx, MPI_DOUBLE_PRECISION, nbrtop, 1, comm1d, status, ierr)
call MPI_SEND(a(1,s), nx, MPI_DOUBLE_PRECISION, nbrbottom, 1, comm1d, ierr)
endif
return
( 3 ) R o u t i n e p e r S c a m b i o M e s s a g g i i n Jacobi
(uso di MPI_SENDRECEIVE)
Michele Colajanni – Esempi programmi paralleli
19/51
(4) Routine per Scambio Messaggi in Jacobi
(C o m u n i c a z i o n i N o n -Bloccanti)
subroutine exchng1(a, nx,
nx, s, e, comm1d, nbrbottom,
nbrbottom, nbrtop)
nbrtop)
include “mpif.h”
integer nx, s, e
double precision a(0:nx+1,s-1:e+1)
integer comm1d, nbrbottom, nbrtop
integer status_array(MPI_STATUS_SIZE, 4), ierr, req(4)
call MPI_IRECV(a(1,s-1), nx, MPI_DOUBLE_PRECISION, nbrbottom,
0, comm1d, req(1), ierr)
call MPI_IRECV(a(1,e+1), nx, MPI_DOUBLE_PRECISION, nbrtop, 1,
comm1d, req(2), ierr)
call MPI_ISEND(a(1,e), nx, MPI_DOUBLE_PRECISION, nbrtop, 0,
comm1d, req(3), ierr)
call MPI_ISEND(a(1,e), nx, MPI_DOUBLE_PRECISION, nbrbottom,
1, comm1d, req(4), ierr)
call MPI_WAITALL(4, req, status_array, ierr)
return
end
Michele Colajanni – Esempi programmi paralleli
20/51
10
M o t i v a z i o n e p e r C o m u n i c a z i o n i N o n -Bloccanti
for(iterations)
update all cells;
send boundary values to neighborours;
receive halo values from neighborours;
boundary
boundary
halo
halo
array
processo
for(iterations)
update boundary cells;
initiate sending o f b o u n d a r y v a l u e s t o n e i g h b o r o u r s ;
initiate receipt of h a l o v e l u e s f r o m n e i g h b o r o u r s ;
update non-boundaru cells;
w a i t f o r c o m p l e t i o n of s e n d i n g o f b o u n d a r y v a l u e s ;
w a i t f o r c o m p l e t i o n of r e c e i p t o f halo values;
Michele Colajanni – Esempi programmi paralleli
21/51
Modalità di Comunicazione Non Bloccanti
SEND
• Il processo mittente esegue la SEND ma non si blocca. Può continuare ad
eseguire tutte le operazioni che non alterano il buffer di SEND.
• Analoghe versioni delle comunicazioni bloccanti
1. M P I _ I S E N D
2. M P I _ I S S E N D
3. M P I _ I B S E N D
4. M P I _ I R S E N D
RECEIVE
• Il processo destinatario esegue la RECEIVE ma non si blocca. Può continuare ad
e s e g u i r e t u t t e l e o p e r a z i o n i c h e n o n a l t e r a n o i l b u f f e r d i R E C E I VE.
• RECEIVE non bloccanti possono anche essere combinate con S END bloccanti e
viceversa.
• MPI_IRECV
• Stessi parametri + uno molto importante: request
(serve per il testing sull’effettiva conclusione della comunicazione)
Michele Colajanni – Esempi programmi paralleli
22/51
11
Routine di testing per Comunicazioni Non Bloccanti
• Test singoli
1. M P I _ T E S T
2. M P I _ W A I T
• Test multipli
1. M P I _ T E S T A L L
2. M P I _ W A I T A L L
3. M P I _ T E S T S O M E
4. M P I _ W A I T S O M E
23/51
Michele Colajanni – Esempi programmi paralleli
Parallelizzazioni più complesse: Algoritmo Gauss-Seidel
L’algoritmo di J a c o b i è u n a t e c n i c a i t e r a t i v a c h e c o n v e r g e p i u t t o s t o l e n t a m e n t e ; p e r t a n t o s u
elaboratori sequenziali si preferiscono utilizzare altri algoritmi quali il m e t o d o d i G a u s s Seidel ed il S u c c e s s i v e O v e r R e l a x a t i o n m e t h o d ( S O R ) , c h e c o n v e r g o n o c o n u n a r a p i d i t à d i
c i r c a d u e v o l t e m a g g i o r e [ H a g e l 81].
I l m e t o d o d i J a c o b i aggiorna il vettore i iterazione utilizzando solo i valori ottenuti al passo
iterativo precedente. Il metodo SOR e di Gauss- Seidel accelerano il tasso di
c o n v e r g e n z a u t i l i z z a n d o , n e l l a v a l u t a z i o n e d i x k + 1 , n o n s o l o x k, m a a l c u n e d e l l e
c o m p o n e n t i a p p e n a c a l c o l a t e d e l l o s t e s s o xk+1.
Componente da aggiornare al passo k+1
Componenti aggiornate al passo k
Componenti aggiornate al passo k+1
Michele Colajanni – Esempi programmi paralleli
24/51
12
Parallelizzazione Algoritmo di Gauss-Seidel
P A R A L L E L I Z Z A Z I O N E : M o d e l l o D a t a - Parallel
= = = = = > Si decompone il dominio in strisce assegnando i punti di ciascuna striscia ad un diverso processore.
0
1
2
3
4
5
6
7
8
9
10
11
= = = = = > S i d e c o m p o n g a n o u l t e r i o r m e n t e i p u n t i d i discretizzazione in due sottoinsiemi disposti
come in una scacchiera: b l a c k / w h i t e (o r e d / b l a c k ).
= = = = = > P e r c i a s c u n p a s s o i t e r a t i v o s i i n d i v i d u a n o d u e s o t t o -livelli di iterazione:
1) nel primo si aggiornano i punti dell’insieme black, utilizzando i valori dell’insieme white;
2) nel secondo, analogamente, i punti white sono aggiunti utilizzando gli elementi
black al passo precedente.
Michele Colajanni – Esempi programmi paralleli
25/51
Simulazione di Modelli Oceanografici
Approccio di parallelizzazione: D e c o m p o s i z i o n e a g r a n a f i n e
d e l d o m i n i o ( + riconfigurazione dinamica)
Decomposizione del Dominio
Michele Colajanni – Esempi programmi paralleli
26/51
13
T a s k f a r m d i n a m i c o : Problema delle N Regine
Problema: Trovare tutte le soluzioni per posizionare N Regine su di una
scacchiera Nx N tale che nessuna Regina sia in grado di attaccarne un’altra.
U n a soluzione
27/51
Michele Colajanni – Esempi programmi paralleli
Problema delle N Regine (esempio N = 4 )
Q = Posizione della Regina (Q u e e n )
Ramo senza soluzioni
Ramo senza soluzioni
2 soluzioni
Michele Colajanni – Esempi programmi paralleli
28/51
14
Algoritmo risolutivo: ricerca esaustiva
• Si ha uno spazio di ricerca irregolare, con un dominio non definibile a priori
• Non è possibile effettuare una decomposizione del dominio
• Necessità di bilanciamento dinamico
Michele Colajanni – Esempi programmi paralleli
29/51
Soluzione parallela al problema delle N Regine
Approccio di parallelizzazione: T a s k f a r m d i n a m i c o
• Manager
- Costruisce e mantiene il livello superiore dell’albero di ricerca
(posizione iniziale della Regina)
- Usa i worker per costruire l’albero e risolve ogni foglia dell’albero
- Tiene traccia del numero totale di soluzioni trovate
• Worker
- Esegue due task principali
1. Suddivide il problema in sottoproblemi
2. Risolve i sottoproblemi
Michele Colajanni – Esempi programmi paralleli
30/51
15
Pattern di Comunicazione (prevalente) tra
processi paralleli
Un richiamo al problema dell’Embedding visto in precedenza
• Master/slave
• Task f a r m statico (es., Integrazione per
π)
• Task f a r m dinamico (es., Problema delle N regine)
• Near-neighbor
(es., Jacobi, metodi alle differenze finite per la soluzione di PDE)
• Multicast
(es., Fattorizzazione LU, Moltiplicazione di matrici)
• Irregolare
(es., Problemi di dinamica molecolare, fluidodinamica)
31/51
Michele Colajanni – Esempi programmi paralleli
Metriche di Valutazione
delle Prestazioni
nel Calcolo Parallelo
(c e n n i )
16
Speedup
Definizione 1 ( S p e e d u p Ideale )
Rapporto tra il tempo di esecuzione del migliore algoritmo sequenziale T*
ed il tempo di esecuzione del corrispondente algoritmo parallelo ottenuto
utilizzando p processori:
S =
*
p
T*
Tp
Definizione 2 ( Speedup Algoritmico )
Tipico andamento dello
speedup
Speedup
Rapporto tra il tempo di esecuzione dell’algoritmo su di un unico
processore ( T 1 ) ed il tempo di esecuzione dello stesso su p processori ( T p )
Numero processori
33/51
Michele Colajanni – Esempi programmi paralleli
Efficienza
Misura del grado di inutilizzo dell’elaboratore parallelo
Ep =
Sp
p
Per definizione, 0 <= E p <= 1
efficienza
Buona misura per la presentazione di più risultati in quanto, rispetto
allo speedup (espresso in funzione di p), “normalizza” i tempi di
esecuzione
1
Dati
Michele Colajanni – Esempi programmi paralleli
34/51
17
Legge di A m d h a l (1967)
Si assuma che in un determinato problema possa essere distinto in due
parti: una inerentemente sequenziale (sia f la percentuale di tale sezione
sul calcolo complessivo) ed una completamente parallelizzabile:
N
Tempo di esecuzione:
Tp = ( f +
Allora lo speedup è limitato da:
1− f
S
f
)T1
p
p
≤
f +
1
1 − f
p
per
p→∞
S p →1/ f
Conseguenza
Una piccola frazione di operazioni sequenziali può limitare fortemente
lo speedup ottenibile da un computer parallelo
Esempio
Se f=0.1 à S p
10, indipendentemente da quanti processori si hanno
Michele Colajanni – Esempi programmi paralleli
35/51
Legge di Barsis- Gustafson
Motivazioni
Diversi studi sperimentali condotti presso il Sandia National Laboratory hanno
dimostrato che per molti problemi era possibile ottenere speedup quasi lineari (circa
1000 con 1024 processori)
Ciò ha condotto ad una rivisitazione della legge di Amdhal:
Il difetto della legge di Amdhal è quello di considerare f e p scorrelati,
cioè dipendenti dalle proprietà statiche dell’algoritmo senza tener conto
della dimensione dello spazio computazionale
Scalando la dimensione del problema con il numero di processori usati,
si ha invece che:
• T 1 non è più indipendente dal numero di processi utilizzati
• T p risulta indipendente dal numero di processori
Ribaltamento del paradigma di Amdhal:
Amdhal : quanto sarà T p dato T 1
Barsis : quanto sarà T 1 dato T p
Michele Colajanni – Esempi programmi paralleli
36/51
18
Legge di Barsis- Gustafson (cont.)
Esecuzione parallela = Ts + Tw
s
w
s
pw
Esecuzione sequenziale = Ts + p Tw
Sia s la frazione di tempo che una macchina parallela spenderebbe nella
parte seriale del programma e w la frazione che la stessa macchina
parallela spenderebbe nelle parti parallelizzabili del programma medesimo.
S p ( scalato ) =
T s + pT w
T s + Tw
=
+
Ts
Ts + Tw
+p
Tw
Ts + Tw
= s + pw
Normalizzando anche in questo caso , cioè supponendo w+s=1, si ha:
= s + p (1 - s) = s + p – ps = p + ( 1 – p ) s
37/51
Michele Colajanni – Esempi programmi paralleli
E’ possibile avere s p e e d u p superlineare (?)
• Confronto “ disonesto”
(es.: Algoritmo sequenziale non buono)
• Caratteristiche HARDWARE
(Soprattutto dovuto a gerarchie di memoria: cache/disco)
• Anomalie ALGORITMICHE
(es.: algoritmi di ricerca)
T 1 =11 (tempo sequenziale con tradizionale
Soluzione
algoritmo di ricerca)
T 2 =4 (tempo parallelo con 2 processori)
Speedup = 11/4 = 2.75 !!
Max Speedup (lineare) = 2
Michele Colajanni – Esempi programmi paralleli
Spazio di ricerca
Assegnato al
Processore 1
Spazio di ricerca
Assegnato al
Processore 2
38/51
19
Cause di inefficienza delle
Applicazioni parallele
(e possibili rimedi)
Processo implementativo di un programma SPMD
Programma
Sequenziale
Decomposizione del
Dominio dei Dati
1
2
(Schema di
memorizzazione)
Primitive di
Comunicazione
Programma parallelo
(versione 1)
Strategia
di t u n i n g
Programma parallelo
(versione 2)
Michele Colajanni – Esempi programmi paralleli
40/51
20
Parametri che Influenzano le Prestazioni
• Bilanciamento del Carico
• Rapporto Comunicazioni/Computazioni
• Colli di Bottiglia
(sequenzializzazioni, sincronizazioni)
• “Tuning” dei Programmi
Michele Colajanni – Esempi programmi paralleli
41/51
P r o g r a m m a r e i multicomputers
•
Le macchine MIMD a memoria distribuita (muticomputers)
raggiungono buone prestazioni (speedup) soltanto se sono
programmate in maniera opportuna.
•
Sono molto più difficili da programmare rispetto alle SIMD o alle
MIMD a memoria condivisa.
•
In particolare, esiste una granularità ottima dei processi (dati) per
ciascun tipo di problema che deve essere risolto su di un particolare
mulicomputer.
•
Nel caso in cui l’insieme di processi abbia una granularità maggiore o
minore di quella ottima, in generale lo s p e e d u p non sarà né
lineare né proporzionale al numero di processi presenti.
Michele Colajanni – Esempi programmi paralleli
42/51
21
Bilanciamento del Carico
Obiettivo: A s s e g n a r e a t u t t i i p r o c e s s o r i u n a n a l o g o W O R K L O A D
===> Livelli di utilizzazione “simili” significano prestazioni più elevate
POSSIBILI TECNICHE DI MIGLIORAMENTO
• Diminuire la granularità
• Ridistribuzione dinamica di strutture dati o di task
• Ridistribuzione di strutture dati statiche
• Aumentare il livello di m u l t i p r o g r a m m a z i o n e (per ciascun nodo)
Michele Colajanni – Esempi programmi paralleli
43/51
Bilanciamento Dinamico (a Posteriori) dei Processi
Ottenuto mediante MIGRAZIONE DEI PROCESSI (o STRUTTURE DATI)
Vi sono tre metodi per controllare e gestire l’operazione (centralizzata) della
migrazione:
• Iniziativa del Destinatario
I processori con piccolo workload richiedono più processi
à (Adatto nel caso di sistemi molto carichi)
• Iniziativa del Mittente
I processori con eccessivo workload richiedono di poter cedere alcuni
processi ad altri processori
à (Adatto nel caso di sistemi poco carichi)
• Metodo Ibrido (adattativo)
Si passa dal primo al secondo metodo a seconda del livello di carico del
sistema.
Michele Colajanni – Esempi programmi paralleli
44/51
22
Pro e Contro del Bilanciamento Dinamico
+ Si ottiene, tipicamente, un utilizzo maggiore dei processori
± Bisogna evitare la cosiddetta “ migrazione circolare”, utilizzando algoritmi
opportuni e valori soglia
- Vi sono elevati costi aggiuntivi sia nel determinare il workload dei
processori che il workload totale
- L’operazione di migrazione di un processo è costosa e dovrebbe essere
effettuata solo per i processi con lunghi tempi di esecuzione
(informazione che spesso non è possibile determinare a priori)
- In genere, tutti i metodi di bilanciamento dinamico intervengono troppo
tardi (quando le prestazioni del sistema sono già degradate). Il
bilanciamento “f o r w a r d -l o o k i n g ” è possibile solo conoscendo i tempi
di run dei singoli processi.
- Nei sistemi eccessivamente carichi, tutti i metodi di bilanciamento
dinamico non hanno “punti di riferimento”. Per di più, i costi
introdotti dalla gestione del bilanciamento tendono a far peggiorare
ulteriormente le prestazioni del sistema.
Michele Colajanni – Esempi programmi paralleli
45/51
Bottleneck di Sequenzializzazione
Obiettivo: Evitare che tutti i processi si mettano in attesa di un singolo p r o c e s s o r e .
= = = > O g n i s e q u e n z i a l i z z a z i o n e f o r z a t a d e l c o d i c e i n f l u e n z a i n m o d o c o n s i d e r e v o l e l e p r e s t a z i o n i.
B o t t l e n e c k del
processore
Bottleneck
del codice
E s ., F a t t o r i z z a z i o n e L U ( d e c o m p o s i z i o n e p e r c o l o n n e )
POSSIBILE TECNICHE DI MIGLIORAMENTO
• Modificare o migliorare l’algoritmo in modo da sovrapporre il codice sequenziale
con altre computazioni
• Distribuire i workload di processori sovraccarichi (bottleneck) tra più processori
Michele Colajanni – Esempi programmi paralleli
46/51
23
Bottleneck di Sincronizzazione
O b i e t t i v o : L i m i t a r e i p u n t i i n c u i t u t t i i p r o c e s s o r i d e b b a n o s i n c r o n i z z a rsi.
===> L’ultimo processo ad arrivare al punto di sincronizzazione determina
il tempo di esecuzione globale.
L U factorization ( n o s e n d -a h e a d )
POSSIBILI TECNICHE DI MIGLIORAMENTO
• Inviare i valori necessari alle computazioni di altri processori non
appena sono disponibili (s e n d -a h e a d )
• Modificare o riorganizzare l’algoritmo in modo da eliminare i punti di
sincronizzazione dove non strettamente necessari
Michele Colajanni – Esempi programmi paralleli
47/51
Rapporto Comunicazioni/Computazioni
Obiettivo: Minimizzare il rapporto tempo di comunicazione tempo di computazioni
di un programma.
===> Rapporti COMUNICAZIONI/COMPUTAZIONI più bassi implicano prestazioni
più elevate
POSSIBILI TECNICHE DI MIGLIORAMENTO
• Aumentare la granularità
• Ristrutturare il programma in modo da avere meno messaggi, ciascuno
di dimensione maggiore
• Ristrutturare le comunicazioni in modo da combinare messaggi “logicamente multipli”
in messaggi singoli
Michele Colajanni – Esempi programmi paralleli
48/51
24
“T u n i n g ” dei Programmi
( A m b i t o : D a t a Parallelism con Allocazione Statica)
OBIETTIVO 1: MIGLIORARE IL BILANCIAMENTO DEL CARICO
E s e m p i o ( Fattorizzazione LU)
• Passare da una decomposizione geometrica ad una decomposizione
ciclica del dominio dei dati
Michele Colajanni – Esempi programmi paralleli
49/51
“T u n i n g ” dei Programmi
( A m b i t o : D a t a Parallelism con allocazione statica)
OBIETTIVO2: ELIMINARE LE SINCRONIZZAZIONI NON NECESSARIE
E s e m p i o ( Fattorizzazione LU)
(1) Algortimo naive ( d e c o m p o s i z i o n e p e r r i g h e )
for k=1 to n-1 do
if (k in mynode)
then broadcast(ak*)
else receive(ak*)
for all (i>k in mynode) do
lik=aik/akk
for j=k+1 to n do
aij=aij-likakj
(2) Algoritmo 1 - s e n d - a h e a d ( decomposizione per righe)
if (1 in mynode) then broadcast(ai*)
for k=1 to n-1 do
if not(k in mynode) then receive(ak*)
for all (i>k in mynode) do
lik=aik/akk
for j=k+1 to n do
{aij=aij-likakj
if ((i=k+1) ∧ (i≠n)) then broadcast(ai*) }
Michele Colajanni – Esempi programmi paralleli
50/51
25
“T u n i n g ” dei Programmi
( A m b i t o : D a t a Parallelism con Allocazione Dinamica)
S e b b e n e l o s c h e m a t a s k -f a r m d i n a m i c o p o s s a miglioriare c o n s i d e r e v o l m e n t e i l B i l a n c i a m e n t o
del Carico, è possibile effettuare ulteriori miglioramenti agendo sulla granularità d e i c o m p i t i e
dell’allocazione dei processi.
Esempio (N Regine)
• D e t e r m i n a i l n u m e r o m i g l i o r e ( d e l p u n t o d i v i s t a d e l b i l a n c i a m e n to) per ciò che
concerne i sottoproblemi da creare
[N u m e r o d i s o t t o p r o b l e m i e n u m e r o d i m e s s a g g i s o n o i n v e r s a m e n t e p r o p o r z i o n a l i ]
- - - > si tende a migliorare il bilanciamento del carico e il rapporto c o m u n i c . / c o m p u t .
• Invia due sottoproblemi per ciascuna comunicazione Manager- Worker
[I n t a l m o d o s i c o n s e n t e a l W o r k e r d i s o v r a p p o r r e u n a c o m p u t a z i o n e p e r o g n i
richiesta pendente al Manager]
- - - > si riduce il b o t t l e n e c k di s e q u e n z i a l i z z a z i o n e e si migliora il rapporto
comunicazione/computazione
• Se il manager risulta essere poco “carico”, sfrutta il multitasking: a g g i u n g i u n
processo Worker anche sul processore che esegue il processo Manager
• Se il Manager risulta essere troppo “carico”, suddividi il lavoro del Manager tra più
processori
Michele Colajanni – Esempi programmi paralleli
51/51
26
Scarica