Master SIA 2012/13. Programación de Sistemas Paralelos. OpenMP: Ejercicios prácticos. Facultad de Informática. Ejercicio 1.A. pi.c

Documentos relacionados
Laboratorio de Paralelismo

Master SIA. Programación de Sistemas Paralelos. MPI: Ejercicios prácticos. Ejercicio 1. Facultad de Informática

Laboratorio de Paralelismo OpenMP: ejemplos y ejercicios

Introducción a los sistemas de cómputo paralelo Olatz Arbelaitz Gallego José Ignacio Martín Aramburu Javier Muguerza Rivero Cuaderno del estudiante

1 Primitivas básicas de OpenMP

Javier Ibáñez González

SISTEMAS PARALELOS Y DISTRIBUIDOS. 3º GRADO EN ING. INFORMÁTICA. ING. COMPUTADORES PRÁCTICA 8: INTRODUCCIÓN A OPENMP.

Laboratorio de Paralelismo Prácticas MPI

Cómputo paralelo con openmp y C

ARQUITECTURA DE SISTEMAS PARALELOS 2. 4º INGENIERÍA INFORMÁTICA. PRÁCTICA 4. PROGRAMACION PARALELA CON openmp.

identificador: Es el nombre que le damos a la variable matriz y por el cual la referenciaremos en nuestro programa.

Programación (PRG) PRACTICA 4. Elementos de programación: estructuras de control.

SESIÓN DE EJERCICIOS E1

SESIÓN DE EJERCICIOS E1

1. Cuestiones. Ejercicios resueltos de C. Diego Rodríguez-Losada 1. //a) #include <stdio.h> main( ) { int x = 0, y = 0; //b) #include <stdio.

#include <stdio.h> float cubica(float numero) { float cubica; cubica = numero * numero * numero; return cubica; }

Tema 3. Estructuras de control

Operadores aritméticos

Escuela Politécnica Superior de Elche

Programación. Test Autoevaluación Tema 6

Programación en Memoria Compartida: OpenMP

TEMA 4. ESTRUCTURAS DE CONTROL

Actividad Algoritmos, Estructura y Programación I. FOR, DO-WHILE

Multiprocesamiento en lenguaje C Introducción a Open Multiprocessing (OpenMP)

Práctica 3. Generación de números primos

Algoritmos y Estructuras de Datos Ingeniería en Informática, Curso 2º SEMINARIO DE C Sesión 1

Algoritmo, Estructuras y Programación I Ing. Marglorie Colina

Dobles: Es el caso de la instrucción if-else (punto 1.2).

E s c u e l a P o l i t é c n i c a S u p e r i o r d e E l c h e

Introducción general al Lenguaje C (2010/2011)

1. Que rellene un array con los 100 primeros números enteros y los muestre en pantalla en orden ascendente.

Informática. Prueba de conjunto (0.25 puntos) Considerar el siguiente fragmento de código:

EJERCICIOS CON FUNCIONES EN C. EJEMPLO CALCULAR SERIES NUMÉRICAS. REFACTORIZAR. (CU00552F)

Computación Matricial y Paralela

Escuela Politécnica Superior de Elche

OpenMP. Qué es OpenMP?

Operadores de comparación

Introducción a la Programación de Memoria Compartida.. con OpenMP

BENEMERITA UNIVERSIDADD AUTONOMA DE PUEBLA FACULTAD DE CIENCIAS DE LA COMPUTACIÓN LICENCIATURA EN CIENCIAS DE LA COMPUTACIÓN

TEMA 5. CONTROL DE FLUJO DEL PROGRAMA. Sentencia Instrucción Expresión Operadores + Operandos Sintaxis: Sentencia ;

for(i = 0; i <= 45; i+=5) { x = (i*3.1416)/180; printf( seno(%d) = %f\n,i,seno(x));

Examen Fundamentos de Programación 15 de enero de 2016 Curso 2015/16

Es una API (Aplication Program Interface) que se usa para paralelismo basado en hilos múltiples en entornos de memoria compartida

Programación I Teoría III.

Examen de Programación I

Algoritmos y Estructuras de Datos Ingeniería en Informática, Curso 2º SEMINARIO DE C Sesión 2

Realizar el ejercicio anterior utilizando Punteros

Prácticas de Programación Resueltas: Máquinas de Turing

Titulo: Calculo de PI

Lección 3 Sentencias de control

Prác%ca 1 Sesión 3 1

Programación. Grupo 1B. Tema 2: Elementos de Programación (Parte B)

Fundamentos de programación

Definición. Procesamiento de Arreglos. Paso de Parámetro a funciones. Arreglos multidimensionales 8/28/2013. Arreglos Unidad 0 Programación AVANZADA

1. Escribe cuál es la salida del siguiente programa: 2. Escribe cuál es la salida del siguiente programa:

PARTE II PROGRAMACION CON THREADS EN C

Arquitectura de Computadores: Exámenes y Controles

Lenguaje de Programación: C++ Directivas al preprocesador

Punteros. Programación en C 1

Lenguaje de Programación: C++ Estructuras de control:for

Introducción al lenguaje C

Programación I Tipos de datos y operadores básicos

Sistemas Complejos en Máquinas Paralelas

Enunciado 3 Buscar palabras de estructura similar

Si un número es múltiplo de otro, u dicho de forma, comprobar si un número es divisor de otro.

Enunciado 2 Descifrar claves cifradas con crypt

TEMA 5: PARALELISMO A NIVEL DE HILOS, TAREAS Y PETICIONES (TLP, RLP) (primera parte).

APELLIDOS NOMBRE GRUPO CALIFICACIÓN FECHA

Apellidos: Nombre: Matrícula: Examen Programación para Sistemas Grado en Ingeniería Informática

2º curso / 2º cuatr. Arquitectura de Computadores. Grado en Ing. Informática. Seminario 1. Herramientas de programación paralela I: Directivas OpenMP

6. Sentencias repetitivas o bucles

Soluciones a los ejercicios planteados en el curso

Francisco J. Hernández López

Los tipos de datos que con mayor frecuencia se utilizan en Informática son:

Universidad Tecnológico Ecotec. Fundamento de programación. Deber

Práctica 7e: Uso de estructuras en C.

Formato para Prácticas de Laboratorio

Examen Teórico (1/3 de la nota final)

Programación I Arrays, cadenas de caracteres y estructuras

#include <stdio.h> /* Factorial de un número - versión 1- */

Cómputo en paralelo con OpenMP 1

Funciones en lenguaje C

Arquitecturas Paralelas Examen de Febrero 24 Enero 2005

SENTENCIAS DE CONTROL CICLOS for

Paralelización de Programas Secuenciales: OpenMP

Repaso Lenguaje C Área de Servicios Programación (Ing. Elect. y Prof. Tec.), Programación I (TUG y TUR) y Electrónica programable (TUE)

Algoritmos y Estructuras de Datos Ingeniería en Informática, Curso 2º SEMINARIO DE C Sesión 4

E s c u e l a P o l i t é c n i c a S u p e r i o r d e E l c h e

Prof. Dr. Paul Bustamante

Ejercicios sobre Descomposición Funcional, Parte II. tcomplejo SumarComplejos(tcomplejo, tcomplejo); que sume dos números complejos.

ºC = ((ºF - 32)*5)/9 ºF = ((ºC * 9)/5)+32 ºK = ºC

TEMA. Vectores y Matrices. Dept. Ciencias de la Computación e I.A. Universidad de Granada

Eventos e interrupciones

Variables y tipos básicos 1. Definir una variable de tipo char. Convertirla a una variable de tipo entera e imprimir su valor asociado.

ARREGLOS UNIDAD 2 PROGRAMACIÓN. Primavera 2009

Benemérita Universidad Autónoma de Puebla Facultad de Ciencias de la Computación Área de Programación

GUÍA DE LABORATORIO #3 ESTRUCTURAS ALGORÍTMICAS CONDICIONALES SIMPLES, DOBLES Y MÚLTIPLES

Operadores de comparación

Bucles anidados. M.Sc. Ana María Salgado G. UNAN - LEON 24/04/2012

SISTEMAS PARALELOS Y DISTRIBUIDOS. 3º GIC. PRÁCTICA 9 Departamento de Arquitectura y Tecnología de Computadores Universidad de Sevilla

Transcripción:

Master SIA 2012/13 Facultad de Informática Programación de Sistemas Paralelos OpenMP: Ejercicios prácticos En el directorio templates/practica de tu cuenta msiaxx tienes varios programas que hay que procesar en paralelo utilizando OpenMP. En el caso de los ejercicios 1.A 1.B, se trata de bucles sencillos de paralelizar, y el objetivo es medir la eficiencia de la ejecución paralela en la máquina que tenemos disponible. El ejercicio 2 es más complejo; es un conjunto de bucles y funciones que hay que analizar y decidir la manera más conveniente de paralelizarlos. El objetivo es conseguir el mayor speed-up posible. En los casos en los que se desea obtener el tiempo de ejecución, conviene repetir la ejecución del programa unas cuantas veces (5 por ejemplo) y promediar los resultados y obtener la desviación típica, ya que puede haber una cierta dispersión en las medidas de tiempos (en caso de que algún resultado se diferencie claramente del resto, no tomarlo en cuenta). Los programas incluyen variables, funciones, etc. como ayuda, pero puedes modificarlos en lo que quieras (manteniendo la semántica, claro). No olvides añadir #include <omp.h> al principio de los programas openmp. Como resultado de estos ejercicios, hay que redactar un informe con los resultados obtenidos (numéricos y gráficos, programas ), explicando de manera razonada el comportamiento que se observa. El trabajo es para cada grupo y forma parte de la evaluación de la asignatura; si el grupo es de dos alumnos, recuerda que no se trata de que cada uno haga la mitad de los ejercicios, sino de hacerlos entre los dos. Se valorarán las soluciones propuestas, los resultados obtenidos y la explicación de los mismos, así como la calidad (estructuración, redacción, explicaciones, gráficos ) del propio informe. 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 más al valor de π cuantos más trapecios se sumen, que es un parámetro que pide el programa. El objetivo es medir el tiempo de ejecución del correspondiente programa paralelo en función del número de threads utilizados: 1, 2, 4, 8, 16, 32. Utiliza, por ejemplo, 10.000.000 de iteraciones (sumas). El reparto del bucle que sea estático consecutivo. Dibuja las curvas del tiempo de ejecución y speed-up que se obtienen e interprétalas adecuadamente.

Ejercicio 1.B tgrano.c En este caso hay que obtener los tiempos de ejecución del programa en paralelo y en serie, en función del tamaño del vector que se procesa (lo pide el programa), por ejemplo para tamaños 1, 10, 100, 1.000, 10.000, 100.000, 1.000.000. Hay que trabajar con 4 threads y scheduling estático consecutivo. Dibuja el tiempo de ejecución y el speed-up en relación al caso serie, en función del tamaño del vector. Ejercicio 2 prog.c El programa prog.c contiene un grupo de bucles y funciones que trabajan con matrices y vectores, sin que representen una aplicación en concreto. El objetivo del ejercicio es aplicar diferentes técnicas de paralelización de bucles para conseguir ejecutar el programa en el menor tiempo posible, es decir, obtener el mayor speed-up posible. La metodología que recomendamos aplicar es la siguiente: -- Mide el tiempo de ejecución de cada bucle y/o función del programa serie (sin considerar la inicialización y la impresión de resultados). De esta manera se obtiene un perfil aproximado de qué puntos del programa son los más adecuados para paralelizar. Por ejemplo, se puede añadir al comienzo de cada función, bucle, grupo de ellos, etc., que se desee temporizar algo similar a lo siguiente: gettimeofday(&t0, 0); [código que se quiere temporizar] gettimeofday(&t1, 0); Esta función, que viene con el programa, imprime el tiempo transcurrido entre t0 y t1: TrazaTiempo("T1",&t0,&t1); En todo caso, puedes usar cualquier otra función y de la manera que te resulte más cómoda. -- 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 función del bucle, las dependencias, el reparto de datos, etc. -- Comprueba que los resultados obtenidos son coherentes con la ejecución 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 ejecución en un fichero (xxx > datos), y comparar luego ambos casos, serie y paralelo, utilizando el comando diff. -- Tras probar diferentes alternativas y en función de los resultados obtenidos, toma las decisiones más adecuadas para paralelizar el programa en su conjunto, y obtén finalmente el speed-up global. Como resultado final, el informe de resultados debe recoger el código con que se ejecuta cada bucle, el tipo de técnica que se ha aplicado para paralelizarlo y por qué, y los resultados obtenidos tiempo de ejecución en serie, tiempo de ejecución en paralelo, y el speed-up tanto para cada parte como para el programa completo. Justifica todas las decisiones que tomes y los comportamientos observados.

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 t0, t1; tej; int 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 / () 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 // tamaino maximo del vector float A[N]; main () struct timeval t0, t1; tej; int 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 2: prog.c /********************************************************************************** prog.c Ejercicio de paralelizacion OMP --- por hacer --- **********************************************************************************/ #include <omp.h> #include <stdio.h> #include <sys/time.h> // Declaracion de constantes y variables #define N1 900000 #define N2 4000 #define N3 2000 #define N4 5000 #define N5 5000 #define N6 2000000 #define PIXMAX 10 struct timeval t0, t1; int i, j, k; sum, x, pe1, pe2; int histo[pixmax], imagen[n4][n5]; A[N1], B[N1], C[N1], E[N1]; D[N2][N3]; H[N6], J[N6], N[N6]; // 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) tej; int nthr=0; #ifdef _OMP nthr = omp_get_max_threads(); #endif tej = (pt1->tv_sec - pt0->tv_sec) + (pt1->tv_usec - pt0->tv_usec) / 1e6; printf("%s = %10.3f ms (%d threads)\n",ptexto, tej*1000, nthr); // Funcion que calcula el producto escalar de dos vectores del tamaino // especificado ProductoEscalar ( *V1, *V2, int lvec) int i; 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]); void SacarVector( *V, int L1, int L2) int i; for (i=l1; i<l2; i++) if(i%5==0) printf("%12.2f ",V[i]); 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\n");

// PROGRAMA PRINCIPAL main () //Inicializacion de vectores for(i=0; i<n1; i++) A[i] = 0.0; B[i] = ()(N1-i+2); C[i] = 1 / 10.0; E[i] = 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; i<n6; i++) H[i] = 1.0; J[i] = 6.0; N[i] = 3.0; //Comienza la ejecución // 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; i<n6; i++) H[i] = 3.5 / (7.0/N[i-1] + 2.0/H[i]); N[i] = N[i] / (N[i]+2.5) + 3.5 / N[i]; J[i] = (H[i-1]/N[i-2] + 3.5/H[i-1]) / (H[i-1] + N[i-2]); // 2 funciones pe1 = ProductoEscalar(C,E,N1); pe2 = ProductoEscalar(H,J,N6); // 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 (A, 0, 10); SacarVector (A, N1-10, N1); printf("c-> "); SacarVector (C, 0, 10); SacarVector (C, N1-10, N1); printf("e-> "); SacarVector (E, 0, 10); SacarVector (E, N1-10, N1); printf("h-> "); SacarVector (H, 0, 10); SacarVector (H, N6-10, N6); printf("j-> "); SacarVector (J, 0, 10); SacarVector (J, N6-10, N6); printf("n-> "); SacarVector (N, 0, 10); SacarVector (N, N6-10, N6); printf("d->\n"); SacarMatrizD(); printf("el histograma de la imagen es:\n"); for (k=0; k<pixmax; k++) printf("%9d", k); for (k=0; k<pixmax; k++) printf("%9d", histo[k]); printf("\n\n"); printf("x = %18.2f\n", x); printf("sum = %18.2f\n", sum); printf("c*e = %18.2f\n", pe1); printf("h*j = %18.2f\n", pe2);