Sei sulla pagina 1di 10

ANDER CID (marq01) Arquitectura de computadores

>> ASPECTOS GENERALES DE LA PRCTICA

La prctica consiste en transformar el cdigo de tres problemas dados en serie (pi.c, tgrano.c y matvec.c, estando este ltimo incompleto) en un cdigo equivalente pero resuelto en paralelo, para as poder ejecutarlo con mltiples procesadores en un tiempo significativamente menor.

Para poder realizarla, ha sido necesario acceder a una mquina (va VPN) con las siguientes especificaciones tcnicas: Arquitectura SMP 4 procesadores Intel Xeon 2,60 GHz Doble ncleo 4 MB memoria cache

Toda la prctica ha sido llevada a cabo con Linux OS, editada utilizando Visual (Vi) y compilando con el Intel C++ Compiler (ICC). El acceso remoto ha sido gestionado a travs de Secure Shell (SSH).

1.- EJERCICIO pi.c (serie) / pipar.c (paralelo)

El ejercicio consiste en resolver

en paralelo, sabiendo que

el resultado de dicha integral es . En este caso, el programa devolver el valor de y, adems, nos dir el error cometido. Se deben hacer pruebas con 10.000.000 de iteraciones, y comparar los resultados de usar desde 1 hasta 8 threads.

El cdigo en paralelo es el siguiente:

() paso = 1.0 / (double) num_iter; #pragma omp parallel for private(i, x) firstprivate(paso) reduction(+:sum) for (i=0; i<num_iter; i++) {x = (i + 0.5) * paso; sum = sum + 4.0 / (1.0 + x*x); } pi = sum * paso; ()

Ejecutando el programa en serie, observamos que tarda alrededor de los 360 ms con muy poca dispersin en las 4 ejecuciones realizadas (360,285 // 360,631 // 360,002 // 360,191) En todas las ejecuciones del programa, el resultado ha sido siempre el siguiente:

Valor de PI con 10000000 sumas = 3.141592653590 Error = 49000001536.0000000 (x10a-9)

A continuacin, observamos los resultados de ejecutar el cdigo en paralelo con 1, 2, 4 y 8 threads. N threads 1 2 4 8 T1 361.068 181.089 93.000 114.902 T2 360.785 181.075 94.912 112.809 T3 360.857 181.171 96.065 115.911 T. Speed medio Up (~) 360.524 360.808 1 181.032 181.092 1.98 95.001 94.745 3.8 112.805 114.107 3.15 T4

Construimos la grfica a partir de esos datos:

Speed up
4 3,5 3 2,5 2 1,5 1 0,5 0 1 2 3 4 5 Speed up 6 7 8

Podemos apreciar que entre 1 y 4 threads, el factor de aceleracin crece prcticamente de forma lineal segn aumenta el nmero de hilos, mientras que con 8 threads el rendimiento disminuye ligeramente. Esto es debido a los overheads: hay ciertos factores (la comunicacin debida al reparto o recoleccin de datos, por ejemplo) que hacen que sea irrentable abrir una gran cantidad de threads. Cabe recordar que la mquina en la que se trabaja tiene 8 ncleos, que no resultan tan potentes como 8 procesadores ntegros a la hora de abrir 8 threads.

2.- EJERCICIO tgrano.c (serie) / tgranopar.c (paralelo)

El programa realiza una serie de operaciones sobre un vector. El ejercicio consiste en ejecutar el programa con el mismo reparto y nmero de threads (4), pero modificando el tamao del vector, y comparar los tiempos en serie y en paralelo.

El cdigo en paralelo quedara as:

() #pragma omp parallel for private(i,j) for (i=0; i<tam_vec; i++) {for (j=1; j<=1000; j++) A[i] = (A[i]*A[i] + 1) * (A[i]*A[i] - 1) + (j%2); } ()

Obtenemos la siguiente tabla a partir de las ejecuciones en serie: Tamao del vector 1 10 100 1.000 10.000 100.000 1.000.000 T1 0.027 0.262 2.627 26.268 254.789 2625.477 26182.898 T2 0.027 0.262 2.643 26.337 262.561 2625.557 26233.005 T3 0.027 0.262 2.718 26.341 262.590 2624.574 26221.943 T. medio 0.027 0.262 2.662 26.315 259.98 2625.203 26212.615

Repetimos el proceso, pero en paralelo (4 threads y reparto del bucle esttico consecutivo): Tamao del T1 T2 vector 1 2.827 2.927 10 3.963 2.879 100 4.581 4.597 1.000 10.429 10.495 10.000 72.567 72.410 100.000 661.117 662.237 1.000.000 6566.476 6568.542 T3 3.018 3.007 4.687 10.471 72.192 660.913 6567.999 T. Speed medio up (~) 2.924 0.008 3.283 0.008 4.622 0.576 10.465 2.515 72.390 3.591 661.422 3.969 6567.672 3.991

Construyendo sus respectivas grficas, obtenemos:

Comparativa de tiempos Ts y Tp
30000 25000 20000 15000 10000 5000 0 1 10 100 Ejecucin en serie 1000 10000 100000 1000000

Ejecucin en paralelo

Comparando los tiempos, el efecto del reparto de iteraciones se hace notable cuando el tamao del vector (y, por tanto, el nmero de operaciones a realizar) comienza a tomar valores altos. Aunque resulte insignificante, al realizar pocas operaciones es ms rentable hacerlo en serie que en paralelo (causado por los overheads anteriormente mencionados). En la siguiente grfica es ms fcil de apreciar:

Speed up
4,5 4 3,5 3 2,5 2 1,5 1 0,5 0 1 10 100 1000 Speed up 10000 100000 1000000

Para un tamao del vector reducido, el tiempo de overhead hace que no sea rentable paralelizar el cdigo (recordemos que los

valores del factor de aceleracin menores que 1 indican prdida de rendimiento). No obstante, al incrementar el tamao se puede observar que el speed up crece hasta rozar el ptimo, que significa un rendimiento muy cercano al 100% (para 4 threads, un factor de aceleracin prximo a 4).

3.- EJERCICIO matvec.c (serie) / matvecpar.c (paralelo)

Se trata de completar el cdigo en serie de un programa que hace unas determinadas operaciones sobre vectores y matrices, para luego paralelizarlo. Una vez hecho, se debe evaluar el comportamiento del speed up en funcin del tamao de los vectores y las matrices, adems del nmero de threads. El cdigo en serie quedara as:
// inicializar variables (cualquier valor) for(i=0; i<N; i++) {for(j=0; j<N; j++) {A[i][j] = (float) (N-i)*0.1/N;} B[i] = (float) i*0.05/N; C[i]=0.0; D[i]=0.0; } gettimeofday(&t0, 0); // calcular los vectores C, D y su producto escalar X for (i=0; i<N; i++) {for (j=0; j<N; j++) C[i]+=A[i][j]*B[j];
}

for (i=0; i<N; i++) {for (j=0; j<N; j++ D[i]+=A[i][j]*C[j];


}

for(i=0; i<N; i++) X+=C[i]*D[i];

// calcular la matriz A2 y la suma de su diagonal for (i=0; i<N; i++) {for (j=0; j<N; j++) {for (k=0; k<N; k++) A2[i][j]+=A[i][k]*A[k][j]; } } gettimeofday(&t1, 0);

Y paralelizndolo, obtenemos:

gettimeofday(&t0, 0); // calcular los vectores C, D y su producto escalar X #pragma omp parallel for private(i,j) firstprivate(N) for (i=0; i<N; i++) {for (j=0; j<N; j++) C[i]=A[i][j]*B[j]+C[i]; } #pragma omp parallel for private(i,j) firstprivate(N) for (i=0; i<N; i++) {for (j=0; j<N; j++ ) D[i]=A[i][j]*C[j]+D[i]; } #pragma omp parallel for reduction(+:X) private(i) firstprivate(N) for(i=0; i<N; i++) X=C[i]*D[i]+X;

// calcular la matriz A2 y la suma de su diagonal #pragma omp parallel for private(i,j,k) firstprivate(N) for (i=0; i<N; i++) {for (j=0; j<N; j++) {for (k=0; k<N; k++) A2[i][j]=A[i][k]*A[k][j]+A2[i][j]; } } #pragma omp parallel for private(i) firstprivate(N) reduction(+:diagonal) for (i=0; i<N; i++) diagonal = diagonal + A2[i][i]; gettimeofday(&t1, 0);

En cada etapa slo se ha paralelizado el bucle ms externo, es decir, que se opera sobre las matrices por filas (cada thread se queda con una fila y la recorre entera l slo). Por tanto, para exprimir el mximo de cada procesador el tamao mximo de filas y columnas debera ser mltiplo del nmero de threads a utilizar. Recogiendo los datos de las ejecuciones, obtenemos la siguiente tabla:

N Threads Serie

N T1 mx 10 0.115 100 16.441 1000 18433.0 10 0.777 100 9.233 1000 9313.79 10 2.206 100 5.812 1000 4645.81 10 10.025 100 15.602 1000 2356.7

T2 0.114 16.481 18583.6 0.756 9.193 9359.77 2.466 5.551 4621.03 10.436 15.111 2371.3

T3 0.115 16.404 18490.3 0.785 9.188 9299.51 2.222 6.029 4620.98 10.880 15.294 2333.9

T. Speed medio up (~) 0.115 16.442 18502.3 0.773 0.149 9.205 1.786 9324.36 1.984 2.298 0.050 5.797 2.836 4629.27 3.996 10.447 0.011 15.336 1.072 2353.9 7.860

El resultado ha sido siempre el mismo para cada tamao mximo, independientemente del nmero de threads. Para NMAX=10:
C0-C9 --> 0.02 0.02 0.02 0.02 0.01 0.01 0.01 0.01 0.00 D0-D9 --> 0.01 0.01 0.01 0.01 0.01 0.01 0.00 0.00 0.00 X = 0.001, diagonal de A2 = 0.303

Si NMAX=100:
C0-C9 --> 0.25 0.25 0.24 0.24 0.24 0.24 0.23 0.23 0.23 D0-D9 --> 1.25 1.24 1.22 1.21 1.20 1.19 1.17 1.16 1.15 X = 10.467, diagonal de A2 = 25.502

Y por ltimo, NMAX=1000:


C0-C9 --> 2.50 2.50 2.49 2.49 2.49 2.49 2.48 2.48 2.48 D0-D9 --> 125.00 124.87 124.75 124.62 124.50 124.37 124.25 124.12 124.00 X = 104218.535, diagonal de A2 = 2505.002

A partir de los datos obtenidos, se puede apreciar que los overheads tienen un peso considerable en el tiempo final para valores de NMAX entre 10 y 100 (paralelizando perdemos rendimiento). La mejora al paralelizar se hace notable al crecer NMAX, llegando a rozar el 100% de eficiencia usando 2, 4 y 8 threads. Lo vemos en las siguientes grfica

f(NMAX) = T. medio
10000 9000 8000 7000 6000 5000 4000 3000 2000 1000 0 10 2 Threads 100 4 Threads 8 Threads 1000

f(NMAX) = Speed up
9 8 7 6 5 4 3 2 1 0 10 2 Threads 100 4 Threads 8 Threads 1000

Potrebbero piacerti anche