Archivo de la categoría ‘UCM Informatica.’

Medidas de tendencia central para el rendimiento de un S.I.

Miércoles, 9 de diciembre de 2009

Media aritmética:

 \overline X_A = {1 \over n} \cdot {\sum_{i=1}^n x_i}

Media geométrica:

 \overline X_G = ({\prod_{i=1}^n x_i})^{1 \over n}

Media armónica:

 \overline X_H = {1 \over {\sum_{i=1}^n {1 \over x_i}}}

También hay dos medidas de centralización que pueden ayudar en el rendimiento. Son la media y la moda. Para ambos valores necesitamos tener la muestra de rendimientos ordenada, lo que supone un coste extra.

La mediana es justo el valor que esta en el medio, si la muestra es par, entonces por convenio se coge el de la izquierda o una media entre los dos valores centrales. Por ejemplo si tenemos (1, 2, 3, 4) sumamos el 2 y el 3 y lo dividimos por la mitad. La mediana resultante es 2.5.

La moda es el valor que mas se repite en la muestra, si hay dos con la misma frecuencia, entonces hay dos modas o bimodal, tres trimodal. A partir de cuarto empate, la moda no existe.

Cuando conocemos la frecuencia de los programas que queremos medir utilizaremos las medias ponderadas. Para ello tenemos que recordar que la suma de las frecuencias siempre sera igual a 1:

 1 = {1 \over n} \cdot \sum_{i=1}^n w_i

Donde el “w sub i” son las frecuencias, se vera mucho mas claro en los ejemplos.

Media aritmética ponderada:

 \overline X_A = {1 \over n} \cdot {\sum_{i=1}^n x_i \cdot w_i}

Media geométrica ponderada:

 \overline X_G = ({\prod_{i=1}^n {x_i^{w_i}}})

Media armónica ponderada:

 \overline X_H = {1 \over {\sum_{i=1}^n {w_i \over x_i}}}

Bueno ahora lo importante, para que queremos estas 6 formulas, pues basicamente se utilizan segun estas directrices:

  • Media aritmética se utiliza para calcular tiempos de ejecución.
  • Media armónica se utiliza para ratios (MIPS y MFLOPS).
  • Media geométrica para otros indices (con mas factores).
  • Mediana y moda se utiliza cuando las demás no son suficientemente representativas.

Analisis comparativo de rendimiento de dos Sistemas Informaticos.

Martes, 1 de diciembre de 2009
Una tabla de barras horizontal que mide MFLOPS de los procesadores.

Una tabla de barras horizontal que mide MFLOPS de los procesadores.

El objetivo es el comparar el rendimiento de dos S.I. (Sistemas informaticos). Fundamentalmente medimos tiempo de ejecucion de un conjunto de programas. Estos programas en general son los habituales. Estos programas los llamamos benchmark. El tiempo de ejecucion es la unica medida fiable de para medir el rendimiento de un computador.

Medidas de rendimiento MIPS y MFLOPS.

1. MIPS (Millones de instrucciones por segundo). Se calcula con la siguiente formula:

MIPS = Num de instrucciones /( tiempo de ejecucion * 10^6)

La ventaja de MIPS es que son faciles de calcular. La desventaja es que depende directamente del juego de instrucciones del computador. No es lo mismo ejecutar la operacion ADD (suma) que LOAD (carga desde memoria). Algunas tardan mas otras menos.

2. MFLOPS (Millones de operaciones de coma flotante por segundo). Se calcula con la siguiente formula:

MFLOPS = Num de instrucciones por segundo / (Tiempo de ejecucion * 10^6)

La ventaja de MFLOPS es que tambien es bastante facil de calcular, mientras la desventaja es que depende de la arquitectura hardware. Es una medida algo mas fiable que MIPS. Se puede aplicar una mejora, los MFLOPS normalizados.

3. Tiempo de ejecucion. Se calcula mediante el siguiente producto:

T = I*CPI*t

Donde:

  • I es numero de instrucciones a ejecutar.
  • CPI numero medio de instrucciones de reloj. (Cuantas instrucciones se ejecuta por ciclo de reloj)
  • t el tiempo de ciclo de reloj.

Ejemplos:

Por ejemplo si tenemos un programa de calculo numerico que se ejecuta en 2 minutos y hace las siguientes operaciones de coma flotante en ese tiempo.

Operaciones FLOPS, cantidad y normalizacion.

Operaciones FLOPS, cantidad y normalizacion.

Si calculamos sin la normalizacion, considerando que todas las operaciones son identicas en tiempo. Tenemos:

MFLOPS = (78 + 29 + 13 + 42) / 120 segundos = 1,35 MFLOPS.

Los 10^6 de la formula se van en la division, por eso no esta puesto. Pero esto no es real, si tenemos en cuenta la normalizacion. Por ejemplo la tabla nos dice que 1 operacion ADD es igual a 12 operacion EXP en tiempo. Si lo aplicamos en la formula:

MFLOPS = (78*1 + 29*3 + 13*8 + 42*12) / 120 = 6,442 MFLOPS

Una cifra bastante mas grande, y sobre todo mucho mas real.

Introducción a evaluación del rendimiento de un sistema informático. Primera parte.

Jueves, 22 de octubre de 2009

Sietema informatico.

Sietema informatico.

Estas es una pequeña introducción, de la asignatura. El principio es bastante aburrido, ya que se trata de conocer las definiciones y unas pocas nociones teóricas para poder comprender mejor. Mas adelante se centrara en la practica, evaluar rendimiento de un sistema Unix (Unix)

Definiciones:

Antes de definir nada, planteemos que es un sistema informático, esta palabra tendrá una redundancia en el texto “bestial”, es fundamental entenderla correctamente. Es un concepto muy, pero que muy amplio, recurriendo a la wikipedia:

Un sistema informático como todo sistema, es el conjunto de partes interrelacionadas, hardware, software y de Recurso Humano (humanware). Un sistema informático típico emplea una computadora que usa dispositivos programables para capturar, almacenar y procesar datos.

Vamos que un ordenador, mas una persona que lo maneja es un sistema informático, también una oficina llena de gente con sus computadores podría considerarse un sistema informático.

Evaluación del rendimiento de un sistema informática es una medida de la calidad en el uso del Hardware respecto a un conjunto de programas llamado “carga del sistema” donde puede existir interacción con usuarios.

Usuario: cualquier persona o cualquier programa que solicitan ejecución de tareas al sistema informático. Por ejemplo: una persona solicita la impresión de un documento, para ello pulsa el botón imprimir.

  1. Pulsa el botón imprimir – >un usuario intermedio (programa) solicita el encolado de la tarea en la cola de impresión.
  2. Otro ejemplo: Un teléfono móvil cada 3 segundos emite una señal solicitando localización por la antena mas próxima.

Carga del sistema: conjunto de programas que se ejecutan en el S.I. par satisfacer a los usuarios, suele ser un conjunto complejo y variable en el tiempo.

Por ejemplo: en la secretaria de alumnos de la fdi (facultad de informática de la complutense), una persona realiza la tarea de dar de alta y matricular a los alumnos. La carga del sistema puede ser el conjunto siguiente:

1. Interfaz de introducción de datos.
2. Almacenamiento en la B.D.
3. Programa de gestión de impresión e informes diarios.
4. Backup de datos.

Definir la carga del sistema nos sirve para modular correctamente el S.I. en conjunción con los dispositivos físicos y las relaciones existentes entre ellos.

Como y para que medir el rendimiento de un sistema informático.

Por ejemplo en función de medidas tradicionales, o sea, en las primeras maquinas lo controlaba el propio programador, prácticamente no existía el software, todo se media en los siguientes elementos.

  • Longitud de la palabra.
  • Repertorio de instrucciones.
  • Ciclos base de la C.P.U.
  • Tiempo de ejecución de una instrucción básica.

Con el tiempo, gracias a los avances tecnológicos necesitamos medir en función de otros elementos no solo el Hardware sino el Software.

Objetivos fundamentales de la evaluación del rendimiento:

1. Encontrar factores que impidan un buen funcionamiento del sistema informático.

Cuello de botella: es una situación en la que muchos dispositivos del sistema informático. realizan una petición a otro, o si un dispositivo recibe muchas peticiones. Se trata de evaluar el rendimiento del dispositivo donde se encuentra el cuello de botella.

2. Predicción del comportamiento de un sistema informático.

  • Con la carga de trabajo habitual  (el sistema informático envejece). Por ejemplo, se necesita ampliar la capacidad del disco duro en 3 meses
  • Con una nueva carga de trabajo (Sistemas informáticos muy dinámicos) Por ejemplo,  en un banco, se desea predecir el comportamiento de la aplicación web, ante una posible avalancha de transacciones.

Se plantea la siguiente cuestión: ¿ Cuando debemos realizar una evaluación del rendimiento? Las posibles respuestas son las siguientes:

    1. Se fabrica una maquina nueva.
    2. Se quiere diseñar un sistema informático nuevo.
    3. Se quiere seleccionar un sistema informático entre varias alternativas.
    4. Se quiere planificar la capacidad de un sistema informático.
    5. Se quiere ajustar un sistema informático (operaciones de mantenimiento)

      Reflexiones con y sin Stencil Buffer.

      Miércoles, 30 de septiembre de 2009

      1. Primera parte de Stencil Buffer.

      Esta es la continuación de uno de mis trabajos de informática gráfica de la Universidad Complutense de Madrid, al final tengo el código que podéis compilar en cualquier compilador C++, aunque previamente tendréis que averiguar como instalar las librerías necesarias. Mi codigo esta compilado con el C++Builder en modo consola.

      Sin stencil.

      Esquema general de las transparencias.

      Esquema general de las transparencias.

      El algoritmo de creación de reflexiones sin Stencil es muy simple. El algoritmo de la reflexión mas simple es cuando el espejo esta en cualquiera de los planos XY, XZ, YZ. Simplemente dibujamos otro objeto idéntico detrás de este plano transparente.  El algoritmo es el siguiente:

      1.    Cargamos la matriz de modelado y damos las coordenadas de la vista:

      glMatrixMode(GL_MODELVIEW);
      glLoadIdentity();
      gluLookAt(   0.0f, 3.0f, 7.0f,
      0.0f, 0.0f, 0.0f,
      0.0f, 1.0f, 0.0f);

      2.    Metemos en la pila matriz de modelado:

      glPushMatrix();

      3.    Multiplicamos la siguiente matriz de modelado por la matriz de reflejos a través de plano XZ, que lo único que hace es negar las coordenadas Y.

      glScalef(1.0, -1.0, 1.0);

      Si fuera otro plano aleatorio deberíamos de calcular la matriz nosotros mismos y después multiplicar la matriz de modelado por esta matriz. El algoritmo de cálculo de la matriz (4 x 4) a partir del punto del plano y su normal es el siguiente:

      void mirrorMatrix(GLfloat& m[4][4], // Matriz resultante.
      GLfloat p[3], // Punto del plano.
      GLfloat v[3]) // Vector perpendicular al plano.
      {
      GLfloat dot = p[0]*v[0] + p[1]*v[1] + p[2]*v[2];
      m[0][0] = 1 – 2*v[0]*v[0];
      m[1][0] = – 2*v[0]*v[1];
      m[2][0] = – 2*v[0]*v[2];
      m[3][0] = 2*dot*v[0];
      m[0][1] = – 2*v[1]*v[0];
      m[1][1] = 1 – 2*v[1]*v[1];
      m[2][1] = – 2*v[1]*v[2];
      m[3][1] = 2*dot*v[1];
      m[0][2] = – 2*v[2]*v[0];
      m[1][2] = – 2*v[2]*v[1];
      m[2][2] = 1 – 2*v[2]*v[2];
      m[3][2] = 2*dot*v[2];
      m[0][3] = 0;
      m[1][3] = 0;
      m[2][3] = 0;
      m[3][3] = 1;
      }

      Después lo único que tendríamos hacer es multiplicar la matriz de modelado por esta matriz.

      glMultMatrixf(&matriz[0][0]); //Le pasamos dirección de nuestra matriz.

      4.    Si dibujamos caras traseras tenemos que dibujar caras frontales.

      glCullFace(GL_FRONT);

      5.    Dibujamos nuestra escena debajo del plano XZ:

      dibujaEsfera();

      6.    Reestablecemos el modo de dibujado de caras y retiramos la matriz de modelado.

      glCullFace(GL_BACK);
      glPopMatrix();


      7.    Dibujamos el plano transparente entre las dos esferas:

      glEnable(GL_BLEND);
      glBlendFunc(GL_ONE, GL_ONE);
      dibujaSuelo();
      glDisable(GL_BLEND);

      8.    Finalmente dibujamos nuestra escena.

      dibujaEsfera();

      Las limitaciones de este sistema son evidentes. Tenemos que limitar nuestra vista para que no mire detrás de nuestro espejo. Otra limitación es pensar que ocurriría si tenemos más de un espejo. Solo lo podríamos usar bien en planos infinitos que no siempre son posibles. El resultado es este:

      La transparencia cutre, abajo podeis divisar la esfera en si.

      La transparencia cutre, abajo podeis divisar la esfera en si.

      Con stencil.

      Con stencil el algoritmo descrito anteriormente casi no cambia los pasos. La diferencia crucial es que etiquetamos cada espejo con un identificador. Cuando una reflexión es renderizada el algoritmo lo que hace es actualizar los píxeles que coincidan con el identificador de la superficie. Para actualizar el algoritmo lo primero que tenemos que hacer es crear una ventana que soporte Stencil Buffer. En el bucle principal tenemos que limpiar los buffers y renderizár la escena con stencil buffer desabilitado.

      glClearStencil(0);
      glClearColor(0.0, 0.0, 0.0, 1.0);
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT  |  GL_STENCIL_BUFFER_BIT);
      glEnable(GL_DEPTH_BUFFER_BIT);
      glDisable(GL_STENCIL_TEST);
      dibujaEscena();

      Despues para cada espejo tenemos que seguir estos pasos:

      1.    Crear el buffer con el valor 1, siempre cuando el buffer de prifundidad es pasado. Desabilitamos escritura en el buffer del color y finalmente dibujamos el espejo.

      glEnable(GL_STENCIL_TEST);
      glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
      glStencilFunc(GL_ALWAYS, 1, ~0);
      glColorMask(0,0,0,0);
      dibujaSuelo();

      Este paso etiqueta cada espejo con valor 1, el test de profundidad es para que los pixels no visibles no sean etiquetados.

      2.    Con el “color buffer” desabilitado ,  establecemos un rango de profundidad para escribir los valores mas lejanos posibles para todos los pixeles actualizados y que buffer de profundidad siempre pase. Establecemos stencil que solo actualize pixels etiquetados con valor 1. Dibujamos los poligonos del espejo.

      glDepthRange(1,1);
      glDepthFunc(GL_ALWAYS);
      glStencilFunc(GL_EQUAL,1 , ~0);
      glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
      dibujaSuelo();

      Este paso reajusta buffer de profundidad a su maximo valor por defecto para todos los pixeles visibles.

      3.   Restauramos profundidad y color para sus valores estándar.

      glDepthFunc(GL_LESS);
      glColorMask(1,1,1,1);
      glDepthRange(0,1);

      Ahora ya estamos listos para renderizar la reflexion en si. Los pixeles que pertenecen a la reflexion son etiquetados con el valor 1, pero al mismo tiempo tienen el maximo valor de profundidad. La operación GL_LESS (menor que test de profundidad) asegura el correcto dibujado de la escena (Hace que la reflexion no se vea).

      4.    Ahora tenemos que dibujar la escena al otro lado del plano, Para el ejemplo solo negare la coordenada Y porque el espejo esta en el plano XZ:

      glPushMatrix();

      glScalef(1.0, -1.0, 1.0);

      dibujaEsfera();

      glPopMatrix();

      Basicamente el algoritmo es este aunque cambia si queremos añadir mas espejos. Yo añadí al final el renderizado del espejo en si con una función de transparencia porque, no se veía el espejo en si, solo el reflejo.

      glEnable(GL_BLEND);
      glBlendFunc(GL_ONE, GL_ONE);
      dibujaSuelo();
      glDisable(GL_BLEND);

      El resultado de los dos algoritmos es el siguiente, en la primera imagen se ve claramente que debajo del plano simplemente hay otra esfera. La imagen de la derecha se parece mas a un reflejo de verda aunque no muy conseguido, ya que no tiene texturas:

      Transparencia con Stencill Buffer. Podeis observar que debajo del plano no hay ninguna esfera.

      Transparencia con Stencill Buffer. Podeis observar que debajo del plano no hay ninguna esfera.

      Aqui teneis codigos de ambos ejemplos en c++, tambien viene una carpeta con librerias, sinceramente ya no me acuerdo como instalarlo y menos si se podria instalar en compliladores que no son C++Builder. Seguramente para DevC++ o GCC hay manuales a parte:

      Generación de sombras y reflejos con stencil buffer parte 1.

      Lunes, 28 de septiembre de 2009

      Este es parte de mi trabajo sobre la generación de Sombras con Stencill Buffer para la informática gráfica:

      Sin Stencil a la izquierda y con Stencil a la derecha. A la izquierda simplemente hay una esfera debajo...

      Con Stencil a la izquierda y sin Stencil a la derecha. A la derecha simplemente hay una esfera debajo, es la forma mas simple de crear reflejos.

      Introducción.

      No hace mucho tiempo en los inicios de juegos en 3 dimensiones la programación visual de los juegos era básicamente: aplicar texturas sobre polígonos, dibujarlos en la pantalla y que el buffer de profundidad haga el resto. Por eso quizás todos los juegos o básicamente su mayoría se parecían en mayor o menor medida. Seguramente tendrían diferencias en la jugabilidad, diseño, sonido o juego en red. Pero la mayor diferencia siempre esta en el aspecto visual y así seguirá hoy y en el futuro.

      Dos efectos que hacen diferenciar y aumentar la calidad del aspecto visual del juego son reflexiones y sombras. Este trabajo esta enfocado en técnicas de creación de sombras usando Stencil Buffer.

      Stencill Buffer es una memoria intermedia que analiza y actualiza píxeles (con sus operaciones) junto con “depth buffer” o buffer de profundidad.  Añade planos de bits adicionales para cada píxel además de los bits de color y profundidad.

      Para comprender mejor Stencil Buffer se puede pensar que simplemente etiqueta los píxeles en la interpretación o renderización de la escena en la pantalla para controlar las siguientes interpretaciones. Los pasos son siguientes:

      1. Dada una escena con una sombra fija. Los píxeles de la escena se podrían considerar con “dentro” de la sombra o “fuera”. Asumimos que podemos etiquetar cada píxel apropiadamente.
      2. Cuando los píxeles ya son etiquetados, actualizamos los píxeles etiquetados como “dentro” de la sombra. Y renderizamos la escena con la fuente de luz desactivada.
      3. Después actualizamos los píxeles etiquetados como “fuera” de la sombra. Activamos la luz y renderizamos otra vez.
      Figura 1. Stencil Buffer.

      Figura 1. Stencil Buffer.

      Prueba “Stencil” por píxel.

      Para explicar “Stenciling” debemos asumir la existencia de “Stencil buffer” así como explicar que es. Stencil buffer es similar al buffer de profundidad en que los dos son colección de planos de bit que no se pueden mostrar. Del mismo modo que el buffer de profundidad asocia a cada píxel de la ventana un valor de profundidad, el stencil buffer asocia su propio valor a cada píxel mostrado. Cuando el buffer de profundidad esta activado los valores de profundidad son usados para aceptar o rechazar fragmentos, del mismo modo los valores de Stencil buffer son usados para aceptar o rechazar fragmentos.

      El primer paso para usar stencil buffer es inicializar la ventana que lo soporte. Mediante modulo GLAUX es fácil de hacer. Tenemos que inicializar ventana mediante esta función:

      auxInitDisplayMode(AUX_DOUBLE | AUX_DEPTH | AUX_STENCIL);

      Si lo hacemos mediante GLUT tenemos que usar esto:

      glutInitDisplayString(“stencil>=1 rgb depth double”);

      El valor “stencil” en si es un entero sin signo (unsigned int). Este entero se puede incrementar, decrementar, comparar y enmascarar. En comparación con buffer de profundidad el valor de profundidad que va de 0 a 1 no se puede decrementar, incrementar, ni enmascararlo.

      Tipicamente en principio del renderizado de una escena, stencil buffer es liberado o se establece un valor por defecto. La liberación o despejado se hace junto al buffer de profundidad y de color.

      glClearStencil(0);
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT |  GL_STENCIL_BUFFER_BIT);

      Igual que el análisis de profundidad el “stencil test” se puede habilitar o deshabilitar, cuyo resultado es que los fragmentos son descartados o van mas adelante. Cuando esta habilitado los fragmentos o píxel son probados. Si esta habilitado y el test o la prueba falla entonces el píxel o fragmento es descartado. De otra manera si el stencil test esta deshabilitado el píxel sigue su curso de procesamiento.

      glEnable(GL_STENCIL_TEST);
      glDisable(GL_STENCIL_TEST);

      Se puede pensar que el stencil test es un obstáculo, como prueba de profundidad (depth test) o prueba de transparencia (alpha test). El stencil test es realizado después del test de transparencia y antes del test de profundidad (Figura 1). El orden de estas operaciones parece a simple vista arbitrario, en realidad es un algoritmo crucial. Los tres test (depth, alpha y stencil) realizan una comparación.

      Depth: Compara valores de píxel con los almacenados en el buffer.
      Alpha: Compara valores de alpha de píxel con un valor de referencia. (No existe ningún apha buffer).
      Stencil: Compara los pixeles del Stencil buffer con el valor de referencia.

      Afortunadamente los tres comparten 8 funciones de comparación: Nunca, Siempre, <,  <=,  >,  >=,  =, ¬ =.

      La funcion de comparación en OpenGL se establece asi:

      glStencilFunc(GL_EQUAL,        //Función de comparación.
      0×1,                             //Valor de referencia.
      0xff);                         //Mascara de comparación.

      Cuando el test Alpha falla simplemente el fragmento es descartado. Cuando es aprobado simplemente sigue hacia delante. El test de profundidad es más complejo. Si el test de profundidad falla el fragmento es descartado sin ningún efecto. En el caso de que lo pasa entonces el valor de profundidad del píxel reemplaza al valor del almacenado en el buffer. El test Stencil es bastante mas complicado. Tiene tres efectos de actualización que dependen de:

      1. Stencil test falla.
      2. Stencil pasa pero depth falla.
      3. Stencil y depth pasan.

      El programador puede configurar las tres operaciones dependiendo de los tres casos. Las 6 operaciones estándar (hay dos operaciones mas en realidad implementadas en direct3D)  son las siguientes:

      1. GL_KEEP: deja el valor de stencil sin modificar.
      2. GL_REPLACE: actualiza el buffer con el valor actual.
      3. GL_ZERO: limpia el valor.
      4. GL_INCR: añade uno al valor del píxel y lo actualiza en el buffer.
      5. GL_DECR: resta uno al valor del píxel y lo actualiza en el buffer.
      6. GL_INVERT: invierte los bits del valor del stencil.

      Cuando los valores stencil son actualizados, se aplica una mascara de escritura “Stencil bit-mask”. Las operaciones y la mascara se establecen asi en OpenGL:

      glStencilOp(GL_KEEP,    //Stencil falla
      GL_DECR,    //Stencil pasa, profundidad falla
      GL_INCR);    //Stencil pasa, profundidad pasa
      glStencilMask(0xff);

      Cuando limpiamos el Stencil buffer tenemos que entender que después se aplica la mascara a ese valor. Esto puede crear confusión cuando limpiamos los valores de pixels y obtenemos un resultado no deseado. En el caso de querer borrar los valores de todos los bit-planos de stencil tenemos que llamar a glStencilMask(~0) antes de llamar glClear.

      Pero para que necesitamos el stencil buffer? Como he dicho antes para dar más realismo en los juegos intentamos introducir sombras y reflejos. Las dos cosas se pueden perfectamente hacer sin la ayuda del stencil buffer. Además  es bastante mas simple hacerlo sin el. Pero mas simple no significa mejor, ya que todas con los métodos normales tenemos demasiadas deficiencias.