Programación (PRG) PRACTICA 6. Cálculo de complejidad de programas.

Documentos relacionados
Programación (PRG) PRÁCTICA 10. Algoritmos de búsqueda

La eficiencia de los programas

Lenguaje C. República Bolivariana de Venezuela Fundación Misión Sucre Aldea Fray Pedro de Agreda Introducción a la Programación III

RESUMEN DEL PROGRAMA GNUPLOT

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

Programación. Test Autoevaluación Tema 3

Cátedra I Informática Autor I Carlos Bartó

Tema 3. Análisis de costes

Fundamentos de Programación 2017-I

2.1 METODOLOGÍA PARA LA SOLUCIÓN DE PROBLEMAS

Es un conjunto de palabras y símbolos que permiten al usuario generar comandos e instrucciones para que la computadora los ejecute.

Guía práctica de estudio 05: Diagramas de flujo

Funciones Definición de función

RECORDAR TIPOS DE DATOS

Informática Ingeniería en Electrónica y Automática Industrial

Unidad II: Análisis semántico

ESTRUCTURAS REPETITIVAS EN PHP

TECNICO SUPERIOR EN INFORMÁTICA EMPRESARIAL MÓDULO INTRUCCIONAL

Tema 2 Conceptos básicos de programación. Fundamentos de Informática

MyOpenLab. Versión Manejo de datos en Matrices y Tablas.

Programación MODULAR: Subalgoritmos - funciones y procedimientos

Formatos para prácticas de laboratorio

SESIÓN DE EJERCICIOS E1

$0 Representa al parámetro cero o nombre del programa $1 Representa al parámetro uno $2 Representa al parámetro dos

Tipos de datos y Operadores Básicos

Es un lenguaje estructurado, tiene una abundante cantidad de operadores y tipos de datos.

Sentencias de Procesamiento Iterativo: while y do-while

Laboratorio de Arquitectura de Redes. Entrada y salida estándar

Factorización LU y la librería GSL. Graficaciíon en Gnuplot

Fundamentos PHP. El término puntuación nos referimos a la sintaxis usada en PHP para la terminación de una línea de código (;)

ESTIMACIÓN DE TIEMPO Y COSTO DE PRODUCTOS SOFTWARE

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

FUNCIONES. Identificador valido. Tipo-Funcion Identificador_de_la_funcion (Tipo par1,tipo par2 )

Programación en C. Algoritmo y Estructura de Datos. Ing. M. Laura López. Programación en C

Manual de usuario MetaTrader 4 TraderNovo:

TAREA 1. INTRODUCCIÓN A LOS SISTEMAS OPERATIVOS.

Caracteres y Cadenas Conversión de Datos Funciones y procedimientos Archivos cabecera. Fundamentos de programación

7.3. Estructura de un programa

Práctica 3. Paso de parámetros entre subrutinas. 3. Consideraciones sobre el paso de parámetros

LABORATORIO 3 ESTRUCTURAS REPETITIVAS WHILE / DO WHILE

INSTITUTO POLITECNICO NACIONAL CENTRO DE ESTUDIOS CIENTIFICOS Y TECNOLOGICOS " GONZALO VAZQUEZ VELA "

CAPÍTULO 3 ESTRUCTURAS DE DATOS ESTÁTICAS

La última versión disponible cuando se redactó este manual era la 5 Beta (versión ), y sobre ella versa este manual.

Tema: Estructuras de Selección en C#.

SISTEMAS INFORMÁTICOS PROGRAMACION I - Contenidos Analíticos Ing. Alejandro Guzmán M. TEMA 2. Diseño de Algoritmos

TEMA 4. ESTRUCTURAS DE CONTROL

Elementos de un programa en C

Ejercicios del Tema 3. Fundamentos de la programación en ensamblador

: Algorítmica y Estructura de Datos I

Texto estructurado (ST)

Preliminares. Tipos de variables y Expresiones

Tema: Sobrecarga. Objetivos. Materiales y Equipo. Introducción Teórica. Programación II. Guía No. 7

EQUIVALENCIAS EN C DE CONSTRUCCIONES SECUENICIALES EN PSEUDOCÓDIGO

TEMA 7: Ficheros. TEMA 7: Ficheros Concepto de fichero

ESTRUCTURAS REPETITIVAS

Algoritmos. Diagramas de Flujo. Informática IV. L. S. C. Heriberto Sánchez Costeira

Métodos para escribir algoritmos: Diagramas de Flujo y pseudocódigo

ESTRUCTURA DE ASIGNACIÓN

Introducción a la programación: Algoritmos

Introducción a la programación

Ejercicios Tema 6. Funciones

Boletín de ejercicios de la asignatura de INFORMÁTICA para la realización de las prácticas de laboratorio. Ejercicios de Estructuras de Control

Estructuras de Repetición (Repita para)

PROGRAMACIÓN ORIENTADA A OBJETOS

Manual de turbo pascal

Introducción rápida a la programación (estructurada ) con C++

Programación en Lenguaje C

Cuales son los tipos de instrucciones que se utilizan en la programación?

Cuáles son los lenguajes que pueden utilizarse para programar Karel?

Modularización en lenguaje C. Funciones

Porque usar Arreglos?

Hoja de ejercicios del Tema 3

Índice. Ya sé Excel, pero necesito más

Tema: Clases y Objetos en C#. Parte II.

Sesión 8- Práctica de Medida de Rendimiento

SISTEMAS OPERATIVOS Arquitectura de computadores

UNIVERSIDAD NACIONAL DE SALTA Sede Regional Orán AÑO: 2013 Carreras: TIG - TUP

Diseño Estructurado de Algoritmos

TEMA 1: Algoritmos y programas

Comenzando a usar MatLab:

Teoría de Autómatas y Lenguajes Formales, IS17 Ingeniería Técnica en Informática de Sistemas. Práctica 1: Introducción al Analizador Léxico FLEX

Cuestiones: Ejercicios 2: 1) Qué imprimen los siguientes bucles?

IMPORTAR Y USAR CLASES DEL API DE JAVA. EJEMPLO CLASE MATH Y MÉTODO POW. CONSTRUCTORES PRIVADOS. (CU00647B)

Programación I. Carrera: ECM Participantes Participantes de las academias de ingeniería electrónica de los Institutos Tecnológicos.

C1 INTRODUCCIÓN AL LENGUAJE C. Fundamentos de Informática Departamento de Ingeniería de Sistemas y Automática. EII. Universidad de Valladolid

NOTACIÓN O GRANDE. El análisis de algoritmos estima el consumo de recursos de un algoritmo.

Métodos que devuelven valor Dado el siguiente triángulo rectángulo:

Funciones: Pasos por Referencia Recursividad

Métodos numéricos para ingeniería Francisco Javier Delgado Cepeda

Tema 01: Algoritmia y diagramas de flujo. Estructuras de datos (Prof. Edgardo A. Franco)

Números enteros (cortos, largos y sin signo) Números reales (precisión simple y doble) Carácter y cadenas de caracteres. Lógicos.

Introducción a Sistemas Operativos: Ficheros

Agradecimientos. Nota de los autores. 1 Problemas, algoritmos y programas 1

Consideremos una función que determine si una fecha dada (d, m, a) es valida:

PRÁCTICA DE LABORATORIO 4 Programación Orientada a Objetos

funciones printf scanf

Introducción a Python. Cecilia Manzino

Algoritmos y Programas

Tema 13: Apuntadores en C

Instituto de Matemática. Agosto de ) Encuentre experimentalmente los siguientes valores de su calculadora:

Transcripción:

Programación (PRG) PRACTICA 6. Cálculo de complejidad de programas. Facultad de Informática Departamento de Sistemas Informáticos y Computación Universidad Politécnica de Valencia Curso 2002/2003 1. Introducción El objetivo de esta práctica es aprender a calcular experimentalmente el coste de un algoritmo. Para ello, se proponen dos métodos de medida: mediante el conteo de operaciones significativas, o mediante un reloj. La caracterización de un algoritmo mediante la definición de su coste computacional (tanto en espacio necesario en memoria como en tiempo de CPU) es una tarea importante en cualquier área de la programación de aplicaciones, siendo crítica en entornos donde la memoria es limitada (tarjetas inteligentes) o la velocidad de respuesta debe cumplir unos requisitos mínimos (sistemas de respuesta en tiempo real). En general, todo problema se puede resolver de varias formas, todas ellas válidas. Sin embargo, unas soluciones pueden ser mejores que otras. Un algoritmo se dice que es mejor que otro para una aplicación determinada, si su coste espacial (memoria necesaria) o su coste temporal (tiempo de CPU) es menor que el segundo. 2. Coste de un algoritmo 2.1. Coste espacial El coste espacial de un algoritmo es la cantidad de memoria que va a necesitar para su ejecución. Supongamos el siguiente ejemplo. Se desea calcular la media de 10000 números enteros que se encuentran en un fichero. Dos alumnos proponen las siguientes soluciones: 1. Definir un vector de enteros de tamaño 10000, leer todo el fichero dentro del vector, y calcular la media del vector. 1

2. Definir un acumulador donde se va sumando cada entero que se lee del fichero. Una vez que se haya obtenido la suma, se calcula la media dividiendo el contenido del acumulador por 10000. Qué solución crees que es más eficiente respecto al coste espacial? 2.2. Coste temporal El coste temporal de un algoritmo indica la cantidad de tiempo de proceso que se necesita para resolver un problema. Dicho coste se puede expresar de varias formas, por ejemplo: número de veces que se ejecuta un bucle, número de operaciones significativas ejecutadas (acceso a un elemento de un vector, una operación matemática, etc) o cantidad de tiempo consumido. La ventaja de las dos primeras formas de calcular el coste de un algoritmo es que son válidas tanto teórica (se puede calcular el número de pasos que va a dar un bucle sin necesidad de utilizar el ordenador) como experimentalmente (se puede incluir código en el programa para que lleve la cuenta del número de veces que se pasa por una cierta instrucción). Sin embargo, la utilización del tiempo para caracterizar un algoritmo es muy dependiente de la máquina y del momento de ejecución del programa, por lo que sólo es válida para medidas experimentales. Ejercicio. Dado el programa siguiente, modifícalo para que lleve la cuenta del número de veces que se ha ejecutado la instrucción del bucle más interno. Antes de terminar, deberá mostrar por pantalla dicho número. #include <stdio.h> int main() { int i,j,n,t; } printf("\nintroduce un número: "); scanf("%d",&n); i=0;t=0; while (i<n) { for (j=0;j<n;j++) t+=3; i+=2; } printf("\nt=%d\n",t); return 0; 10 de diciembre de 2002 Página 2 de 15

flop. Un flop, o floating point operation se define como el esfuerzo computacional necesario para efectuar una operación en la que intervienen números reales. Una medida muy extendida para comparar la velocidad de distintos computadores son los MFLOPS (leído mega-flops), o millones de operaciones en coma flotante por segundo que pueden ejecutar. 3. Estudio experimental de la eficiencia de un algoritmo Para calcular experimentalmente la eficiencia de un algoritmo es necesario seguir los siguientes pasos: 1. Implementar el algoritmo en un lenguaje de programación adecuado. 2. Generar un conjunto de pruebas que muestren los distintos comportamientos del algoritmo (en el caso de que el coste del algoritmo varíe en función de los datos de entrada). 3. Resolver con el algoritmo dichos conjuntos de prueba, aumentando la talla del problema. Para cada ejecución, generar una medida del esfuerzo que se ha invertido. 4. Presentar los resultados adecuadamente. 3.1. Generar conjuntos de prueba En el caso de que el comportamiento del algoritmo dependa de los datos de entrada, habrá que generar distintos casos que muestren dichas variaciones. Si se desea estudiar el comportamiento de un algoritmo determinado, como por ejemplo la búsqueda secuencial de un elemento dentro de un vector, se deben estudiar los siguientes casos: Caso peor. Se busca aquella configuración de los datos de entrada que hace que el algoritmo se comporte peor. En el ejemplo de la búsqueda secuencial, el caso peor se da cuando se busca un elemento que no se encuentra en el vector (hay que recorrer todos sus elementos). Caso mejor. Es aquel conjunto de datos de entrada cuya solución necesita el mínimo esfuerzo. En el ejemplo, es el caso cuando el primer elemento del vector es el elemento buscado. Caso promedio. Este caso es el más interesante, ya que es el que, estadísticamente, se acercará al caso promedio, y el que definirá el comportamiento del algoritmo en la mayor parte de las ocasiones. Este 10 de diciembre de 2002 Página 3 de 15

caso se mide generando aleatoriamente instancias del problema. Dado que aleatoriamente se puede generar el caso peor o el caso mejor, habrá que repetir varias veces el experimento, para poder calcular la media de dichos experimentos. Hay casos en los que el coste del algoritmo no depende de los datos de entrada. Por ejemplo, la suma de dos vectores de N números enteros siempre cuesta lo mismo, independientemente de los valores a sumar. En estas ocasiones, no hay distinción entre los casos mejor, peor o promedio. Azar determinista. Es posible hacer que el ordenador genere números enteros pseudoaleatorios mediante las siguientes funciones, definidas en stdlib.h: int random(void); void srandom(unsigned int semilla); La función random devuelve un número entero entre 0 y la constante RAND_MAX (2147483647 en las máquinas del laboratorio). Cada vez que se invoca devuelve un nuevo número. Dicho número se calcula mediante una función matemática que depende del valor generado anteriormente. El valor que define el comienzo de una serie de valores pseudoaleatorios se denomina semilla. La función srandom 1 permite establecer dicha semilla. A partir de una semilla dada, se generará siempre la misma serie de números. Es común necesitar números menores que RAND_MAX. Para convertir los valores devueltos por random a un rango menor, se puede utilizar el operador módulo (%). Por ejemplo, para obtener números entre 0 y 100, se puede utilizar: a=random()%101; Ejercicio. Escribe un programa que escriba en pantalla 10 números aleatorios entre 1 y 10. 1 En Windows estas funciones se llaman rand y srand. Para utilizar siempre random y srandom y compilar el mismo programa en Windows y en Linux puedes poner en la cabecera del programa: #ifndef random #define random rand #define srandom srand #endif 10 de diciembre de 2002 Página 4 de 15

Repetitivo. Ejecuta varias veces el programa anterior. Qué observas en los resultados? A qué crees que es debido? Para establecer una semilla del generador de números aleatorios distinta en cada ejecución, se suele utilizar el reloj del sistema. Así, es muy probable que dos ejecuciones del programa generen series de números distintas. La función time de la librería time.h devuelve el número de segundos transcurridos desde el 1 de enero de 1970. A continuación se muestra un ejemplo de utilización de esta función para establecer la semilla. srandom(time(null)); 3.2. Aplicar los casos de prueba al algoritmo Este paso consiste en resolver cada uno de los casos de prueba generados, calculando el coste de resolución de cada uno de ellos. Ejercicio. Completa el siguiente programa, que calcula el número medio de pasos necesarios para buscar un elemento dentro de un vector: #include <stdio.h> #include <stdlib.h> #define MAX 250000 int main(void) { int i,tam,x,cont; int v[max]; /* Inicializar v con valores entre 1 y MAX */ for (i=0;i<max;i++) v[i]=i+1; } /* Para tam = {10000, 20000, 30000 MAX} */ for (tam= { /* x es un entero aleatorio entre 1 y tam */ x= /* Buscar x dentro de v. Calcular el número de comparaciones realizadas */ /* Imprimir en una línea por pantalla: tam coste */ printf("%d\t%d\n",tam,cont); } return 0; 10 de diciembre de 2002 Página 5 de 15

Al mostrar el resultado del ejercicio anterior mediante una gráfica, se obtendrá un resultado parecido al mostrado en la Figura 1. 35000 Coste de la búsqueda 30000 25000 Comparaciones 20000 15000 10000 5000 0 0 50000 100000 150000 200000 250000 Talla Figura 1: Gráfica de un posible resultado del programa de la página 5 Ejercicio. Observando la gráfica anterior, crees que el resultado es correcto? Muestra la gráfica el comportamiento promedio de la búsqueda secuencial de elementos en un vector? Modifica el programa para calcular una aproximación al comportamiento promedio de dicho algoritmo. 3.3. Presentar los resultados adecuadamente La salida del programa anterior son dos columnas de números, que a primera vista puede ser difícil de interpretar. El uso de gráficas como la mostrada en la Figura 1 facilita la interpretación de los resultados. A continuación se presenta una herramienta que permite la creación de dichas gráficas de una forma sencilla, a partir de datos formateados. 3.3.1. Dibujo de gráficas con gnuplot gnuplot es un dibujador de gráficas interactivo. Es un programa que se distribuye bajo licencia GNU, y hay versiones disponibles para Linux, Windows y otros sistemas operativos 2. Para ejecutarlo, se debe lanzar el comando gnuplot desde un terminal: 2 Se puede descargar desde la página web http://www.gnuplot.info 10 de diciembre de 2002 Página 6 de 15

[fjabad@pc0101 p6]$ gnuplot G N U P L O T Linux version 3.7 patchlevel 1 last modified Fri Oct 22 18:00:00 BST 1999 Copyright(C) 1986-1993, 1998, 1999 Thomas Williams, Colin Kelley and many others Type help to access the on-line reference manual The gnuplot FAQ is available from <http://www.ucc.ie/gnuplot/gnuplot-faq.html> Send comments and requests for help to <info-gnuplot@dartmouth.edu> Send bugs, suggestions and mods to <bug-gnuplot@dartmouth.edu> Terminal type set to unknown gnuplot> gnuplot permite dibujar funciones matemáticas con el comando plot. Por ejemplo, para dibujar la función seno se utiliza: gnuplot> plot sin(x) El resultado de la orden anterior se puede ver en la Figura 2. Mediante la orden help functions se puede consultar la lista de funciones definidas por gnuplot. Dado un fichero de texto con el siguiente formato: # Tiempo Pasos 10000 5004 20000 9852 30000 15327 230000 115328 240000 118646 250000 127508 gnuplot puede dibujar cada línea del archivo como un punto, donde el primer número es la coordenada en el eje X, y el segundo es la coordenada en el eje Y. Las líneas que empiezan con el carácter # se ignoran. La instrucción para dibujar dicha gráfica es la siguiente: 10 de diciembre de 2002 Página 7 de 15

Figura 2: Gráfica de la función seno gnuplot> plot resbusca2.txt donde resbusca2.txt es el nombre del fichero que se encuentra en el directorio actual y contiene la información a dibujar. El resultado se puede ver en la Figura 3. Por defecto, cuando se utiliza el comando plot como se acaba de ver, genera una gráfica de puntos, donde cada línea del archivo indicado se convierte en un punto. La primera columna dentro del archivo de texto es la coordenada en el eje X, y la segunda columna la coordenada en el eje Y. Si hay más columnas en el fichero, se ignoran. Los límites de los ejes mostrados en la gráfica se ajustan a los datos de entrada. En la parte superior derecha de la gráfica se muestra la leyenda de la gráfica, donde se muestra un punto exactamente igual a los utilizados en la gráfica, junto al nombre del fichero. Sin embargo, plot es muy potente, y admite gran variedad de opciones. La sintaxis de dicho comando es: plot [rangos] {<función> fichero_datos [using <cols>]} [title Titulo ] [with <estilo>] [, <otra función o fichero>] donde: [<rangos>]: Tamaño de los ejes X e Y. Por ejemplo: plot [0:20] [-1:1] sin(x) <función>: Especifica la función a dibujar fichero_datos : nombre del fichero con los datos a dibujar. 10 de diciembre de 2002 Página 8 de 15

Figura 3: Dibujo de una gráfica mediante puntos [using <cols>]: especifica el orden de las columnas que se van a utilizar como ejes X e Y. Por ejemplo: plot datos.txt u 3:1 [title Titulo ]: define el título de la curva que aparecerá en la leyenda [with <estilo>]: estilo puede ser: points, lines, linespoints, impulses... Por ejemplo: plot x w points, x**2 with lines plot sin(x) with impulses A continuación se muestra una tabla con otras instrucciones comunes de GNUPLOT: Comando Acción help Muestra la ayuda set xlabel Etiqueta Etiqueta del eje X set ylabel Etiqueta Etiqueta del eje Y set title Título Título principal del gráfico cd <directorio> Cambia el directorio actual quit Terminar 10 de diciembre de 2002 Página 9 de 15

Ejercicio. Dibuja el resultado de la modificación del ejercicio propuesto en la página 6. Utiliza líneas para dibujarlo y llama a la curva Promedio búsqueda. El eje X deberá mostrar la etiqueta Talla, y el eje Y Comparaciones. Para volcar la salida por pantalla de un programa a un fichero de texto, se puede utilizar la redirección de la salida estándar, mediante el símbolo >. Por ejemplo: resbusca2 > resultado.txt. 3.3.2. Ajuste de funciones con gnuplot Una vez que se ha obtenido la gráfica que muestra el comportamiento de un algoritmo, es necesario encontrar la función matemática que describa de forma más precisa el comportamiento de dicho algoritmo. gnuplot proporciona el comando fit para ajustar una función dada por el usuario a unos puntos definidos en un archivo. La sintaxis de dicho comando es: fit <función> fichero_datos [using <cols>] via <var1> [,<var2>] donde: <función>: es la función a ajustar. Se debe haber definido previamente [using <cols>]: indica el orden en las que se utilizarán las columnas del fichero via <var1>[,<var2>]: especifica los parámetros de la función a ajustar. Por ejemplo, el fichero datos.txt define la curva mostrada en la Figura 4. Por inspección de la curva, parece que los puntos siguen un comportamiento cuadrático. Así, hay que definir un polinomio cuadrático genérico, para posteriormente ajustarlo. Para ello, se ejecuta la orden: gnuplot> f(x)=a*x**2+b*x+c Dentro de gnuplot se pueden definir funciones con los operadores normales de C, además del operador **, que indica exponenciación. La función f(x) no es directamente representable porque las variables a, b ycno tienen valor definido. Para darles aquel valor que haga que la función f(x) se ajuste lo más posible a los puntos anteriores, se puede utilizar el comando fit: gnuplot> fit f(x) datos.txt via a,b,c El siguiente comando muestra ambas curvas en la misma gráfica: 10 de diciembre de 2002 Página 10 de 15

3000 datos.txt 2500 2000 1500 1000 500 0 0 5 10 15 20 25 30 35 40 45 50 Figura 4: Gráfica generada a partir de unos puntos de entrada. gnuplot> plot datos.txt title Puntos w l, f(x) tit Función y la Figura 5 muestra el resultado. La selección de la familia de funciones que se utilizará para ajustar los puntos encontrados experimentalmente se puede basar en dos métodos, que dependen si el código fuente del programa que generó los puntos está disponible o no. Si el código fuente está disponible, se puede calcular el coste del mismo. Para ello hay que buscar la zona de código que consume mayor tiempo de computación. Normalmente dicha zona está localizada en uno o más bucles del programa, que se ejecutarán más o menos veces dependiendo de la talla del problema. De la inspección de dichos bucles, se debe poder extraer el coste esperado (ver el primer ejercicio de los Ejercicios propuestos). Si el código fuente de la función que se desea estudiar no está disponible, entonces la familia de funciones se deberá derivar de la observación de los puntos que describen el tiempo de ejecución del algoritmo, en función de la talla. En este caso, se deberá utilizar un reloj para medir el tiempo de ejecución para cada talla del problema. La siguiente sección explica cómo utilizar el reloj del sistema. Ejercicio. Ajusta los puntos obtenidos en el ejercicio de la página 6 a la función matemática que estimes conveniente mediante el comando fit de gnuplot. 10 de diciembre de 2002 Página 11 de 15

3000 Puntos Función 2500 2000 1500 1000 500 0 0 5 10 15 20 25 30 35 40 45 50 Figura 5: Ajuste de los puntos de la Figura 4 mediante una función 3.4. Medida de tiempos de ejecución En los compiladores ANSI C estándar se puede encontrar la función clock definida en time.h: clock_t clock(void); La función clock devuelve una aproximación del tiempo de procesador consumido por el programa. Las unidades en las que devuelve dicho tiempo son unidades de reloj, y para convertirlas en segundos hay que dividir por la constante CLOCKS_PER_SEC, también definida en time.h. Para calcular el tiempo que ha tardado el ordenador en ejecutar un bloque de código, se puede utilizar el siguiente método: int t1,t2; double resultado; t1=clock(); /* Código a medir */ t2=clock(); resultado=((double)(t2-t1))/clocks_per_sec; 10 de diciembre de 2002 Página 12 de 15

Ejercicio. Calcula experimentalmente el coste de las operaciones suma y producto de matrices, y ajusta los resultados obtenidos a las funciones matemáticas que estimes oportunas. Utiliza para ello los ficheros matrix.h y matrix.c que se encuentran en el directorio /misc/ practicas/asignaturas/prgfi/p6. Tu programa deberá mostrar por pantalla tres columnas, con la talla de la matriz, el tiempo que ha necesitado una suma y el tiempo que ha necesitado un producto: # Talla tsuma tprod 10 0.0003 0.009 20 0.0012 0.072 30 0.0027 0.243 100 0.03 9 Te puedes basar en el ejercicio de la página 5 para estructurar tu programa, y lo estudiado en el Apartado 3.4 para medir los tiempos de las operaciones. No tienes que implementar las operaciones sobre matrices (ni tampoco debes modificar los ficheros matrix.h o matrix.c). Para utilizar las funciones de matrix.c en otro fichero: 1. Incluir la cabecera matrix.h en el programa donde se vayan a usar sus funciones. 2. Llamar a las funciones normalmente. Tienes funciones para rellenar una matriz con valores (iniciam), para mostrarla por pantalla (escribem), para sumar dos matrices (sumam) y para multiplicarlas (productom). 3. Para compilar el programa, utilizar: gcc -o prog prog.c matrix.c 10 de diciembre de 2002 Página 13 de 15

Tiempo cero. Es posible que, al ejecutar el programa anterior, obtengas resultados parecidos a estos: [fjabad@pc0101 p6]$ midematrix 10 0.000000 0.000000 20 0.000000 0.000000 30 0.000000 0.000000 40 0.000000 0.000010 50 0.000000 0.000000 60 0.000000 0.000020 70 0.000000 0.000010 80 0.000000 0.000030 90 0.000000 0.000040 100 0.000000 0.000060 Evidentemente, este resultado es falso (no hay ningún ordenador que pueda sumar dos matrices en tiempo cero). El problema es la precisión del reloj. Las unidades de la función clock son demasiado grandes para medir los tiempos de ejecución de las operaciones. La solución a este problema es repetir la operación un número de veces suficiente como para que el tiempo sea significativo. Luego, a la hora de sacar la cantidad de segundos que ha tardado en realizarse una operación, habrá que dividir por el número de veces que se ha repetido dicha operación. Ejercicio. Modifica el ejercicio anterior para evitar que aparezcan tiempos nulos. 4. Ejercicios propuestos 1. A continuación se muestran los fragmentos de programas que se han detectado como los que consumen más tiempo de ejecución. A partir del código de los bucles, indicar el coste esperado de cada ejemplo, para una talla de problema n, y la familia de funciones que se debería utilizar para ajustar su comportamiento. 10 de diciembre de 2002 Página 14 de 15

for (i=0;i<n;i++) for (i=0;i<n;i++) for (j=0;j<10;j++) for (i=0;i<n;i++) { printf("%d",i); for (j=n;j>0;j--) for (k=0;k<n-10;k++) } for (i=0;i<10;i++) for (j=0;j<n;j++) for (i=0;i<n;i++) for (j=0;j<n;j++) for (k=0;k<n;k++) for (i=0;i<n;i++) for (j=0;j<n;j++) acum=acum+a[i][j]; for (k=0;k<n;k++) acum=acum-k; 2. En el fichero enigma.o del directorio/misc/practicas/asignaturas/ prgfi/p6, están implementadas las funciones f1, f2, f3 y f4. No se dispone del código fuente de dichas funciones, pero se desea caracterizar su comportamiento temporal. Las cabeceras de las funciones se encuentran en el fichero enigma.h, dentro del mismo directorio. Todas las funciones reciben un parámetro de tipo entero, que es el que determinará el tiempo de ejecución de cada una de ellas. Para compilar el programa que utilice dichas funciones, utilizar: gcc -o prog prog.c enigma.o -lm Ajusta el comportamiento de cada función mediante la función matemática que estimes oportuna. 10 de diciembre de 2002 Página 15 de 15