Вы находитесь на странице: 1из 9

Estos son los ejercicios a trabajar:

Ejercicio 1.A

pi.c

El programa calcula el valor de la integral de 4 / (1+x 2) entre 0 y 1, que da como resultado , mediante la suma del rea de una serie de trapecios que cubren el rea bajo la curva. El resultado se aproxima ms al valor de cuantos ms trapecios se sumen, que es un parmetro que pide el programa. El objetivo es medir el tiempo de ejecucin del programa en funcin del nmero de threads utilizados, de 1 a 8. Utiliza, por ejemplo, 10.000.000 de iteraciones (sumas). El reparto del bucle es esttico consecutivo.

Ejercicio 1.B

tgrano.c

En este caso hay que obtener los tiempos de ejecucin del programa en paralelo y en serie, en funcin del tamao del vector que se procesa (lo pide el programa), por ejemplo para tamaos 1, 10, 100, 1.000, 10.000, 100.000, 1.000.000. Hay que trabajar con 4 threads y scheduling esttico

Ejercicio 1.C

matriz.c

Se trata de un bucle de tres dimensiones para multiplicar dos matrices. Paraleliza cada uno de los bucles y mide en cada caso el tiempo de ejecucin obtenido usando 4 threads y scheduling esttico. Explica los resultados.

Ejercicio 2

e2.c

El programa e2.c contiene un grupo de bucles y funciones que trabajan con matrices y vectores, sin que representen una aplicacin en concreto. El objetivo del ejercicio es aplicar diferentes tcnicas de paralelizacin de bucles para conseguir ejecutar el programa en el menor tiempo posible, es decir, obtener el mayor speed-up posible. La metodologa que recomendamos aplicar es la siguiente: -- Mide el tiempo de ejecucin de cada bucle y/o funcin del programa serie (sin considerar la inicializacin y la impresin de resultados). De esta manera se obtiene un perfil aproximado de qu puntos del programa son los ms adecuados para paralelizar. Esta funcin, que viene con el programa, imprime el tiempo transcurrido entre t0 y t1:
TrazaTiempo("T1",&t0,&t1);

En todo caso, puedes usar cualquier otra funcin y de la manera que te resulte ms cmoda. -- Intenta paralelizar los bucles y funciones, uno a uno, y mide el speed-up que vayas consiguiendo en cada trozo. Probablemente habr que aplicar estrategias diferentes en funcin del bucle, las dependencias, el reparto de datos, etc. -- Comprueba que los resultados obtenidos son coherentes con la ejecucin serie del programa. Para ello, al finalizar el programa se imprimen los resultados del mismo (primeros y ltimos 10 elementos de los vectores y de la matriz, productos escalares, histograma, etc.). Una manera sencilla de comprobar resultados es, por ejemplo, dejar los resultados de la ejecucin en un fichero (xxx > datos), y comparar luego ambos casos, serie y paralelo,.

Ejercicio 1.A: pi.c


/**********************************************************************************

Calculo de PI

(programa serie)

integral de 1/(1+ x*x) de 0 a 1 = arctg x = pi/4 Pide el numero de intervalos para sumar la integral **********************************************************************************/ #include <stdio.h> #include <sys/time.h> #define PI25D 3.141592653589793238462643

main () { struct timeval double int double

t0, t1; tej;

i, num_iter, nthr=0; paso, x, sum = 0.0, pi = 0.0; ");

printf("\n Numero de iteraciones? scanf("%d", &num_iter); #ifdef _OPENMP #pragma omp parallel { nthr = omp_get_num_threads(); } #endif gettimeofday(&t0, 0); paso = 1.0 / (double) num_iter; for (i=0; i<num_iter; i++) { x = (i + 0.5) * paso; sum = sum + 4.0 / (1.0 + x*x); } pi = sum * paso; gettimeofday(&t1, 0);

printf("\n Valor de PI con %d sumas = %1.12f", num_iter, pi); printf("\n Error = %.7f (x10a-9)\n", fabs(pi - PI25D)*1000000000); tej = (t1.tv_sec t0.tv_sec) + (t1.tv_usec t0.tv_usec) / 1e6; printf("\n Tej. (%d threads) = %1.3f ms\n\n", nthr, tej*1000); }

Ejercicio 1.B: tgrano.c


/**********************************************************************************

tgrano.c
Ejemplo para ver el efecto del tamaino de las tareas (grano) en el tiempo de ejecucion **********************************************************************************/ #include <stdio.h> #include <sys/time.h> #define N 10000000 float A[N]; main () { struct timeval double int // tamaino maximo del vector

t0, t1; tej;

i, j, tam_vec, nthr=0; ");

printf("\n Tamaino del vector a procesar ---> scanf("%d", &tam_vec); for (i=0; i<tam_vec; i++) A[i] = 1; #ifdef _OPENMP #pragma omp parallel { nthr = omp_get_num_threads(); } #endif gettimeofday(&t0, 0);

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); } gettimeofday(&t1, 0); tej = (t1.tv_sec t0.tv_sec)+ (t1.tv_usec t0.tv_usec) / 1e6; printf("\n\n Tej.(%d threads) = %f ms\n\n", nthr, tej*1000); }

Ejercicio 1.C: matriz.c


/*********************************************************************************

matriz.c
Ejemplo para analizar las alternativas de paralelizacion de bucles anidados Producto de dos matrices C = A * B *********************************************************************************/ #include <omp.h> #include <stdio.h> #include <sys/time.h> #define N 200 main () { struct timeval double

t0, t1; tej;

int nthr=0; int i, j, k; float A[N][N], B[N][N], C[N][N], temp; #ifdef _OPENMP #pragma omp parallel { nthr = omp_get_num_threads(); } #endif for (i=0; i<N; i++) for (j=0; j<N; j++) { A[i][j] = 1.0; B[i][j] = 1.0; } gettimeofday(&t0i, 0); for (i=0; i<N; i++) for (j=0; j<N; j++) { temp = 0.0; for (k=0; k<N; k++) { temp = temp + A[i][k] * B[k][j]; } C[i][j] = temp; } gettimeofday(&t1, 0); tej = (t1.tv_sec t0.tv_sec) + (t1.tv_usec t0.tv_usec) / 1e6; printf("\n Tej. (%d threads) = %1.3f ms \n", nthr, tej*1000); printf("\n Test del producto } C(20,65) = %1.3f\n\n", C[20][65]); // valores inciales cualesquiera

Ejercicio 2: e2.c
/**********************************************************************************

e2.c
Ejercicio de paralelizacion OMP --- por hacer --**********************************************************************************/ #include <omp.h> #include <stdio.h> #include <sys/time.h> // Declaracion de constantes y variables #define #define #define #define #define #define #define #define N1 900000 N2 4000 N3 2000 N4 5000 N5 5000 N6 2000000 N7 2000000 PIXMAX 10

struct timeval t0, t1; int i, j, k; double sum, x, pe1, pe2, pe3; int double double double double histo[PIXMAX], imagen[N4][N5]; A[N1], B[N1], C[N1], E[N1]; D[N2][N3]; H[N6], J[N6], N[N6]; M[N7], P[N7], R[N7];

// RUTINAS AUXILIARES // Procedimiento que saca por pantalla el tiempo (en milisegundos): pt1-pt0 // junto con el string pasado por parametro: pTexto void TrazaTiempo(char * pTexto, struct timeval *pt0, struct timeval *pt1) { double tej; tej = (pt1->tv_sec pt0->tv_sec) + (pt1->tv_usec pt0->tv_usec) / 1e6; printf("%s = %10.3f\n",pTexto, tej*1000); } // Funcion que calcula el producto escalar de dos vectores del tamaino // especificado double ProductoEscalar (double *V1, double *V2, int lvec) { int i; double pe = 0.0; for(i=0; i<lvec; i++) { pe = pe + V1[i] * V2[i]; } return(pe); }

// Tres procedimientos que sacan por pantalla el contenido de las variables // globales correspondientes void SacarImagen() { //Variable global imagen[N4][N5] int i, j; for(i=0; i<10; i++) { for(j=0; j<10; j++) { printf("%1d",imagen[i][j]); } printf("\n"); } printf("\n"); } void SacarVector(double *V, int L1, int L2) { int i; for (i=L1; i<L2; i++) { if(i%5==0) printf("\n"); printf("%12.2f ",V[i]); } printf("\n"); } void SacarMatrizD() { //Variable global D[N2][N3] int i, j; for (i=0; i<10; i++) { for (j=0; j<10; j++) { if(j%5==0) printf("\n "); printf("%12.2f ",D[i][j]); } printf("\n"); } printf("\n\n"); }

// PROGRAMA PRINCIPAL

main () { //Inicializacion de vectores for(i=0; { A[i] = B[i] = C[i] = E[i] = } i<N1; i++) 0.0; (double)(N1-i+2); 1 / 10.0; 0.0;

for(i=0; i<N2; i++) for(j=0; j<N3; j++) { D[i][j] = 6.0; } for(i=0; i<N4; i++) for(j=0; j<N5; j++) { if(i%3) imagen[i][j] = (i+j) % PIXMAX; else imagen[i][j]= (i+i*j) % PIXMAX; } for(i=0; { H[i] = J[i] = N[i] = } for(i=0; { M[i] = P[i] = R[i] = } i<N6; i++) 1.0; 6.0; 3.0;

i<N7; i++) 3.0; 4.0; 5.0;

//Comienza la ejecucin // bucle 1 for(i=1; i<(N1-1); i++) { x = B[i] / (B[i] + 1.0]; A[i] = (x + B[i] + 1.0) / 1000.0; C[i] = (A[i] + C[i-1] + C[i+1]) / 3.0; E[i] = x * x / (x * x + 1.7); } // bucle 2 sum = 0.0; for(i=3; i<N2; i++) for(j=0; j<N3; j++) { D[i][j] = D[i-3][j] / 3.0 + x + E[i]; if (D[i][j] < 6.5) sum = sum + D[i][j]/100.0; } // bucle 3 for(i=0; i<PIXMAX; i++) histo[i] = 0; for(i=0; i<N4; i++) for(j=0; j<N5; j++) { histo[imagen[i][j]] = histo[imagen[i][j]] + 1; } // bucle 4 for(i=2; { H[i] = N[i] = J[i] = } // bucle 5 for(i=4; { M[i] = R[i] = P[i] = } i<N7; i++) M[i] * 1.7 - P[i-4]; M[i-4] * 0.9 + R[i]; (R[i] - P[i]) / 2.0; i<N6; i++) 3.5 / (7.0/N[i-1] + 2.0/H[i]); N[i] / (N[i]+2.5) + 3.5 / N[i]; (H[i-1]/N[i-2] + 3.5/H[i-1]) / (H[i-1] + N[i-2]);

// 3 funciones pe1 = ProductoEscalar(C,E,N1); pe2 = ProductoEscalar(H,J,N6); pe3 = ProductoEscalar(P,R,N7);

// resultados finales: se imprimen los primeros y los ultimos 10 elementos // de cada vector, el histograma de la imagen y los valores de x, sum, // y los productos escalares. printf("A-> SacarVector SacarVector printf("C-> SacarVector SacarVector printf("E-> SacarVector SacarVector printf("H-> SacarVector SacarVector printf("J-> SacarVector SacarVector printf("N-> SacarVector SacarVector printf("M-> SacarVector SacarVector printf("P-> SacarVector SacarVector printf("R-> SacarVector SacarVector "); (A, (A, "); (C, (C, "); (E, (E, "); (H, (H, "); (J, (J, "); (N, (N, "); (M, (M, "); (P, (P, "); (R, (R,

0, 10); N1-10, N1); 0, 10); N1-10, N1); 0, 10); N1-10, N1); 0, 10); N6-10, N6); 0, 10); N6-10, N6); 0, 10); N6-10, N6); 0, 10); N7-10, N7); 0, 10); N7-10, N7); 0, 10); N7-10, N7);

printf("D->\n"); SacarMatrizD(); printf("El histograma de la imagen es:\n"); for (k=0; k<PIXMAX; k++) printf("%9d", k); printf("\n"); for (k=0; k<PIXMAX; k++) printf("%9d", histo[k]); printf("\n\n"); printf("X printf("SUM printf("C*E printf("H*J printf("P*R } = = = = = %18.2f\n", %18.2f\n", %18.2f\n", %18.2f\n", %18.2f\n", x); sum); pe1); pe2); pe3);

Вам также может понравиться