Buscar en este blog

Mostrando entradas con la etiqueta informática. Mostrar todas las entradas
Mostrando entradas con la etiqueta informática. Mostrar todas las entradas

Tema 1.c: Evolución de monitores y displays


La forma en la que se le muestran los datos al usuario ha variado mucho con el tiempo, en este artículo vamos a dar un pequeño repaso a la evolución de los monitores.

Monitores CRT

Son los denominados de rayos catódicos ya que se visualizan las imágenes mediante un tubo de rayos catódicos que emite un haz constante contra una pantalla de vidrio recubierta de fósforo y plomo. El fósforo hace que se reproduzcan las imágenes, mientras que el plomo consigue eliminar las radiaciones.

De este formato distinguimos dos grandes tipos:

Por un lado encontramos los monitores monocromáticos, muy simples, capaces sólo de mostrar un solo color en pantalla. 
Mientras que por otro, encontramos los monitores a color, cuyas pantallas están formadas por 3 capas de material de fósforo coloreado (RGB) representando cada capa un color básico, además cuenta con 3 cañones de electrones, uno por cada color. La combinación e intensidad de estos 3 colores básicos hace que podamos visualizar el resto de la gama cromática. 

Analizamos los estándares de monitores de rayos catódicos aparecidos.

Monitor MDA.

Sus siglas significan  (Monochrome Display Adapter), creados por la compañía IBM, aparecieron en los inicios de la década de los 80. Por supuesto eran monocromos (de un color verdoso) y muy rudimentarios ya que sólo ofrecían un formato de texto que podía exhibir 80 columnas por 25 líneas, teniendo una resolución total de la pantalla del MDA era de 720×350 pixels.

Durante años este era el color de todos mis juegos...
Como dato curioso, el MDA original de IBM incluyó un puerto paralelo para la impresora, gracias a este puerto, se evitaba la necesidad de incluir una tarjeta adicional con una interface paralela.

Monitor CGA

Representan el primer estándar gráfico en color (presentaba 16 colores en total) para el IBM PC, sin embargo también  supuso un cierto revés para la compañía ya que muchos compradores optaron por el Monitor MDA ya que hasta esas fechas el aspecto lúdico de una computadora se dejaba de lado. 


En aquellos con resolución de 320x200 se lograba tener en el modo de texto 40×25 caracteres, por el contrario en el mododo gráfico era posible acceder a cada píxel individualmente, aunque sólo 4 colores de entre los 16 totales podían ser mostrados simultáneamente y no se podían elegir libremente.

Mientras, en la resolución de 640×200 píxeles, se podían presentar en modo texto 80×25 caracteres, sin embargo aunque todo los píxeles podían ser accedidos libremente, éste era un modo monocromo.

También existía un modo de vídeo compuesto a una resolución de 160x200 que podía utilizar los 16 colores de la pantalla.


Monitor EGA

Cuyo acrónimo significa “Enhanced Graphics Adapter”. Fue introducido en 1984 por IBM para sus nuevos IBM Personal Computer/AT. La tarjeta EGA tenía una profundidad de color de 16 colores, una resolución de hasta 640×350 píxels y 16 kilobytes de ROM.

Aunque las mayores diferencias respecto a su predecesor fueron que incorporaba una gamma amplitud de colores y una resolución superior, no calaron en el mercado ya que tan sólo tres años más tarde se empezarían a comercializar los primeros monitores VGA.

Monitor VGA

Sus siglas significan Video Graphics Array y desde su comercialización marcaron un nuevo estándar en lo que a monitores se refiere ya que su potencia superaba con creces a los anteriores EGA. Llegaban a soportar una resolución de 720×400 píxeles en modo texto. Mientras que en modo gráfico una resolución de 640×480 píxeles mostraba 16 colores en pantalla, llegando a los 256 (toda una revolución en el año 1987)  a 320×200 píxeles de resolución. 

Su gran acogida y nivel de ventas procuró que años más tarde surgiera una revisión y modernización del modelo llamado Super VGA.

Super VGA

Son lanzados en el año 1989 e incorporan una serie de mejoras que hacen mayor su compatibilidad, amén de arreglar ciertos errores de diseño.  Incrementan la cantidad de colores de 32 a 64 bits de color verdadero. Mientras que pueden trabajar a resoluciones de  600x400 a 1600x1800.

En aquella época no necesitábamos más
 
Monitores LCD

Son los más actuales y casi los que han copado el mercado.  Sus siglas son en lengua inglesa liquid crystal display, pantalla de cristal líquido en castellano. Son mucho más planos, ya que se evita el incordio de un tubo de rayos catódicos y su pantalla, totalmente plana está formada por un número de píxeles en color o monocromos colocados delante de una fuente de luz o reflectora. 

Su funcionamiento, muy a grosso modo es el siguiente: en el monitor se halla una capa muy delgada compuesta por sustancias que pueden llegar a presentar a la vez el estado líquido y sólido. Si un rayo atraviesa una partícula de estas sustancias sigue el espacio vacío que hay entre sus moléculas pero a cada una de ellas se la puede aplicar una corriente eléctrica que cambie su polarización dejando pasar la luz o no ya que el dispositivo cuenta con 2 filtros polarizados perpendiculares entre sí. Además cuenta con 3 filtros más uno por cada color básico siendo los que aportan la gama cromática.

En informática  son los monitores de TFT  (Thin flim transistor), que también usan tecnología LCD, los más usados actualmente. 

Esta tecnología arrasó con el mercado de las CRT por varias razones: por primera vez la pantalla era plana y no redondeada, las esquinas se veían correctamente y la imagen no estaba ligeramente distorsionada según se llegaba a los bordes, eran mucho menos voluminosas y pesadas, el mantenimiento era más sencillo, la pantalla no parpadeaba apreciablemente y la resolución máxima era mayor. Pero por encima de todo esto estaba lo que siempre le importa más al usuario: estaban, comparativamente, muy baratas.

Sin embargo, tienen algunas desventajas por las que, aún hoy, hay gente que prefiere seguir utilizando monitores CRT para determinadas aplicaciones. Uno de los principales es la pérdida relativa de viveza de los colores (solucionada en gran parte en los últimos modelos de mayores contrastes) y la "pixelación" que se produce al visualizar imágenes que tienen una resolución nativa inferiora la del monitor: el procesador gráfico tiene que completar la información que falta para aumentar el tamaño de la imagen y si no usa un buen filtrado (o incluso a pesar de usarlo) la sensación general es que se ve peor que en un monitor más pequeño y más antiguo.

Otro de los grandes inconvenientes es que en los CRT cuando se quería representar un punto negro bastaba con no iluminarlo con el haz, en los monitores LCD por la forma de tratar las señales eléctricas es imposible que deje de pasar corriente por un píxel de la pantalla, con lo que siempre tiene una mínima iluminación que hace que los negros tiendan al gris. Con los altos contrastes dinámicos se consigue disimular este defecto pero es inherente a la tecnología y siempre estará ahí.

Dos monitores LCD con distintas tecnologías para optimizar los negros
Actualmente hay un nuevo tipo de monitor/televisor LCD que utiliza LEDs para la representación del color (Light Emiting Diode). Esta tecnología divide la pantalla en 128 segmentos que pueden ser encendidos o apagados de forma independiente, lo cual mejora los negros, el contraste y permite que exista más brillo en la imagen, además de tener un bajo consumo de energía.

Monitores de Plasma.

Una pantalla de plasma consta de celdas diminutas situadas entre dos pantallas de cristal que contienen una mezcla de neón y xenón. El gas en las celdas se convierte eléctricamente en plasma, el cual provoca que una substancia fosforescente emita luz.

Esta tecnología apareció en los televisores antes que las LCD, pero llegó más tarde que aquellos a los monitores y no parece que tuviera ningún éxito, quizá como siempre el factor determinante fuera el elevado precio de la tecnología basada en el plasma. 
 

Tema 1.d: Introducción a SpecViewperf 10

Hoy en día existe una oferta muy amplia en componentes de Hardware para ordenadores personales, la rapidez con la que se suceden las innovaciones en materia de potencia y rendimiento junto con la bajada en los precios crea una especie de círculo vicioso que contribuye a mantener esta situación.

Ahora prácticamente cualquiera puede, por muy bajo coste, acceder a tecnología que hace apenas cinco años sólo estaba al alcance de grandes empresas y profesionales. Esta variedad en precio y calidad puede generar confusión en el consumidor que se dispone a cambiar algunos componentes de su ordenador o incluso todo el conjunto.

Los folletos comerciales de tarjetas gráficas, placas bases e incluso memorias RAM suministran mucha información a un consumidor que generalmente no tiene los conocimientos necesarios para poder establecer una comparativa entre dos artículos similares. Se da también el caso de que muchos de los valores que nos suministra el fabricante no son válidos para hacernos una idea del rendimiento de ese componente, menos aún del resultado de la interacción del mismo con el resto de las piezas de nuestro sistema.

Quizá el ejemplo más claro sea el de las tarjetas gráficas ya que son un componente que se suele cambiar con más frecuencia que el resto. Normalmente escucharemos hablar de valores como la frecuencia del reloj del núcleo, la de la memoria, el número de pipelines, la cantidad y el tipo de memoria de textura, el ancho de banda, e infinidad de valores más. Ante esta maraña de datos el usuario normalmente optará por decidir cuánto dinero puede gastar y cogerá la tarjeta con el mayor número de serie que esté dentro de su rango de precios. Pero entonces, ¿porqué nos encontramos con cosas como que la Nvidia 8800 GT es más cara que la 9600 GT? Está claro que hay más factores a tener en cuenta.

Una opción muy recomendable para tener un criterio con el que elegir es el hacer uso de los denominados Benchmarks. Estos programas realizan una serie de pruebas en nuestro sistema destinadas a obtener unos valores de rendimiento que se puedan comparar con los de otro equipo que haya sido probado con el mismo Benchmark.

Normalmente el Benchmark llevará integrados varios programas de distintos fabricantes que se adapten a lo que queremos medir y lo que irá haciendo será ejecutar dichos programas secuencialmente a la vez que va alterando algunos de sus parámetros para evaluar la respuesta de nuestro sistema.

En el caso concreto del SPECViewperf 10 lo que estamos intentando determinar es la potencia gráfica de nuestro sistema, ésta vendrá determinada por el tipo de tarjeta gráfica, de placa base, de memoria RAM y de sistema operativo. Hay que tener en cuenta que el rendimiento no es sólo función de cada elemento por separado, sino que al ensamblar el conjunto se pueden producir incompatibilidades y cuellos de botella que disminuyan el rendimiento global por debajo del valor esperado.
a


El Specviwperf 10 ha sido desarrollado por la organización Standard Performance Evaluation Corporation en respuesta a la necesidad de fabricantes y consumidores de una comparativa honesta entre productos. Integra para su funcionamiento las siguientes aplicaciones: 3D Studio Max, Catia, EnSight, Maya, ProEngineer, Solidworks, UGS Teamcenter Visualization Mockup y UGS NX. Todos ellos programas estrechamente relacionados con la representación realista de gráficos 3D en tiempo real. Estas aplicaciones se denominan viewsets en SpecViewperf 10.

El programa está disponible gratuitamente desde el enlace http://www.spec.org/gwpg/downloadindex.html con el único inconveniente de que su tamaño ronda los 600 megabytes. Una vez descargado e instalado se nos ofrecen varias alternativas para su puesta en marcha, siendo la más obvia la elección entre sistemas operativos de 32 o de 64 bits respectivamente.
a
Dentro de cada una de estas dos opciones podemos elegir dos resoluciones de pantalla: 1600 x 1200 para displays de altas prestaciones o la de 1280 x 1024. En mi caso particular la resolución máxima de mi monitor es 1680 x 1050 así que correré los tests en 1280 x 1024. A la hora de ejecutar el benchmark podemos escoger entre ejecutar cada subprograma por separado o que vaya ejecutándolos todos secuencialmente. en mi sistema he comprobado que tarda alrededor de dos horas en completar todo el ciclo de pruebas.

Una vez que el Specviewperf 10 haya terminado de probar el sistema se nos abrirá una ventana del navegador de internet que tengamos por defecto donde se nos mostrará un resumen de los resultados con hipervínculos a los resultados de cada prueba. Al cerrar esta ventana se nos abrirá otra en la que se mostrará el resultado de los tests aplicando distintos niveles de antialiasing a pantalla completa y por último al cerrar ésta nos mostrará un resumen de los resultados de las pruebas usando varios threads.

El antialiasing es un algoritmo que se implementa para minimizar en lo posible el efecto "dientes de sierra" que se produce al representar lineas rectas en ángulos distintos de 0º y 90º pero en futuras entradas se comentará en mayor profundidad, baste saber que puede gravar significativamente el rendimiento de un sistema y por eso SpecViewperf 10 ejecuta varias veces el mismo test con distintos niveles de antialiasing (incluyendo sin él).

Los threads son "hilos de ejecución" lo que en este caso hace referencia a varias ventanas de representación de gráficos 3D.

Las siguientes imágenes muestran las tres pantallas de representación de resultados.





Como ya se ha mencionado antes, pinchando sobre cada linea se puede acceder a una descripción más detallada de cada prueba.
Los resultados que nos devuelve SpecViewperf 10 están en fotogramas por segundo (FPS), o lo que es lo mismo; el número de pantallas que se generan en un segundo. Cuanto más alto sea este índice, más fluido resulta el movimiento y más se le engaña al ojo humano.
Mi sistema está compuesto por una placa base tipo Asus M2N32-SLI Deluxe, procesador AMD Athlon 64 X2 Dual Core 6400+, 4 GB de memoria RAM (2X2 GB) DDR2 800 Corsair Dual Channel, tarjeta gráfica BFG 8800 GT OC2 de 512 MB y sistema operativo Windows XP Pro SP2.
Los resultados obtenidos pueden comparase con los de la página web oficial de SPEC, en la dirección: http://www.spec.org/gwpg/gpc.static/vp10results.html aunque hay que tener en cuenta que los equipos que aparecen referenciados son de muy alto nivel.
Existen distintos tipos de benchmarks con distintas aplicaciones que nos sirven para comparar diferentes componentes. En el entorno de las tarjetas gráficas es habitual el probarlas con el mismo juego, configurado con idénticas opciones. En ese caso obtendremos unos rangos de valores de FPS que nos orientarán a la hora de hacernos una idea del rendimiento de cada tarjeta gráfica. Encontramos páginas de internet en las que se hacen pruebas periódicamente en las principales tarjetas del mercado como por ejemplo la página Tom's hardware: http://www.tomshardware.com/charts/

Tema 2.a: RISC y CISC


Los acrónimos RISC y CISC hacen referencia a dos filosofías diametralmente opuestas en el diseño de microprocesadores y significan respectivamente: Reduced Instruction Set Computer y Complex Instruction Set Computer. Para entender en qué consisten estas dos arquitecturas distintas es necesario definir algunos conceptos.

El microprocesador es el núcleo de un ordenador, se encarga de realizar todas las operaciones que le sean requeridas para ejecutar un programa.

Los programas son conjuntos de instrucciones diseñados de forma que al llevarlas a cabo nos proporcionen unos resultados útiles para un determinado fin.

Los registros son memorias donde se almacenan datos temporalmente.

Para que un procesador pueda ejecutar una instrucción ésta tiene que estar en un lenguaje que pueda entender; lenguaje máquina o lenguaje de bajo nivel.

Cuando un programador crea un código, un conjunto de instrucciones, no lo hace empleando un lenguaje de programación de bajo nivel ya que sería muy engorroso. Lo que hace es usar un lenguaje de alto nivel, más adecuado para la capacidad cognitiva humana, y luego traducirlo a lenguaje máquina mediante un ensamblador. De esta forma se consigue que el procesador entienda las órdenes y las ejecute.

El procesador sólo entenderá un número determinado de instrucciones en lenguaje máquina que lleva almacenadas en su interior, así que las instrucciones del programa deberán ser traducidas a combinaciones de ellas.

Así pues, el número y complejidad de instrucciones que posee un procesador vendrá determinado por la filosofía de diseño que se esté siguiendo.

La filosofía de diseño CISC es anterior en el tiempo a su contrapartida RISC aunque su acrónimo no empezó a emplearse hasta después de la aparición de esta última. En los años 70 se creía que era mejor en términos de rendimiento el que el procesador contara con un gran número de instrucciones complejas que abarcara las operaciones más frecuentes. Es decir, a la hora de realizar una suma de dos números era más deseable que existiera una orden que llevara a cabo todo el proceso en vez de una que accediera a los números almacenados en memoria, otra que los llevara a la unidad aritmética donde eran sumados y otra que guardara el resultado en una posición de memoria.

Los diseños CISC hacían más fácil la labor del programador y permitían que hubiera un menor número de registros en el procesador, sin embargo hacen muy difícil la implementación de técnicas de mejora de rendimiento como las que se usan en la actualidad.

Aún así fueron durante mucho tiempo la filosofía de diseño más usada para los ordenadores personales, como por ejemplo toda la gama Intel X86, conocidos comúnmente como 286, 386 y 486 entre otros.

La técnica de diseño RISC surgió al comprobar que el software que se corría en los procesadores CISC no hacía un buen uso del conjunto de instrucciones del procesador y que se obtenía un mayor rendimiento si se traducían esas instrucciones complejas a varias más sencillas.

Al reducir la complejidad de las instrucciones se reducía también su tamaño y se podía usar ese espacio extra para almacenar los datos con los que se estaba trabajando, reduciendo así muchísimo el tiempo de acceso a memoria.

Con esta filosofía se dificultaba la labor del programador pero a cambio se abría la posibilidad de utilizar las técnicas de segmentación para mejorar drásticamente el rendimiento del procesador.

Un ejemplo de filosofía RISC son los procesadores PowerPC, presentes en los ordenadores Macintosh y en consolas de última generación.

Tema 2.b: Explicación en detalle de las técnicas de resolución de riesgos en procesadores segmentados utilizando como ejemplo la arquitectura MIPS.


En este artículo vamos a usar como ejemplo el procesador MIPS64 que tiene como características el ser un procesador de tipo RISC (ver artículo anterior) con cauce segmentado de 5 etapas por instrucción de 1 ciclo de duración cada una, 64 registros de 64 bits cada uno, memoria cache tipo Harvard y 66 instrucciones simples de longitud fija de 32 bits. Pero vayamos poco a poco antes de que alguien se asuste.

Ahora que ya sabemos lo que es un procesador tipo RISC (Reduced Instruction Set Computer) lo siguiente es comentar en qué consiste segmentar el cauce de ejecución de las instrucciones de un procesador. La segmentación (o pipelining) surge de la necesidad constante de aumentar la velocidad de proceso de las computadoras, para ello nos vienen rápidamente a la mente tres formas de hacerlo: mejorar el hardware para que sea más rápido, explotar la concurrencia poniendo varios procesadores a trabajar en la misma tarea o hacer lo mismo intentando que un procesador pueda hacer varias tareas a la vez. Todas ellas tienen sus ventajas y sus inconvenientes que se suelen traducir en costes de fabricación y/o de programación.

La primera solución es probablemente la más cara y está limitada por el estado actual del arte, la segunda hoy en día es muy común pero antes su precio era prohibitivo y además se puede usar junto con la tercera. Evidentemente la tercera es la segmentación.

Se suele recurrir al ejemplo de la lavadora para explicar cómo funciona, pero se pueden encontrar multitud de ejemplos hoy en día que lo ilustran de igual manera. Hoy vamos a usar como modelo la fabricación de un automóvil, en honor a Henry Ford que fue uno de los primeros en aplicar las cadenas de montaje.

Fabricar un automóvil era tanto en 1913 como hoy una tarea compleja, que requería un grupo experto de mecánicos trabajando muchas horas. La idea básica era dividir esa tarea compleja es varias más pequeñas y más sencillas, de manera que las pudieran realizar operarios menos cualificados en menos tiempo. Vamos a suponer, de forma totalmente falsa, que Henry Ford dividió su línea de producción en 5 pasos “sencillos”:

  1. Recoger las piezas del almacén.
  2. Leer las especificaciones del cliente y configurar las máquinas.
  3. Ensamblar todas las piezas en el chasis.
  4. Enviar el coche al concesionario para su venta.
  5. Escribir los datos de venta en los libros de cuentas.

Si tuviéramos una persona que sabe hacer todas las tareas y tarda 1 día en cada una, podría construir el coche él sólo en 5 días, si contáramos con 5 de estas personas y empezaran a trabajar el mismo día, venderían 5 coches cada 5 días pero necesitaríamos multiplicar por 5 los recursos de la fábrica.

Lo siguiente es tener a una persona formada en cada operación, de forma que tenemos un transportista de piezas, un operario de las máquinas, un montador, un transportista de vehículos terminados y un contable. Seguimos teniendo 5 operarios pero si les ponemos a trabajar sobre el mismo coche sólo venderemos 1 cada 5 días y siempre habrá 4 esperando a que se les dé trabajo.

Ahora bien, si encadenamos las operaciones de manera que tengamos varios coches en fabricación a la vez podemos llegar a lo siguiente:


Con este esquema llegamos a vender 1 coche en 5 días (como al principio), pero a partir del día 5 vendemos 1 coche al día, teniendo una producción igual a la del ejemplo de 5 operarios expertos en todas las tareas pero con unos costes mucho menores y vendiendo un coche diario en vez de tener que esperar 5 días para vender 5 coches.
Si ahora dividiéramos cada tarea en dos subtareas tendríamos que contratar 5 operarios más pero venderíamos dos coches al día, etcétera, etcétera.

Como puede verse la segmentación no reduce el tiempo de proceso sino que aumenta el rendimiento, racionaliza los recursos y disminuye los costes. Este aumento del rendimiento depende directamente del número de etapas de que se componga nuestro proceso.

Ahora traduciremos este ejemplo a la arquitectura MIPS64, para ello las fases por las que pasa una instrucción son:

  1. Instruction Fetch (IF).
  2. Instruction Decode (ID).
  3. Execution (E).
  4. Memory Access (M).
  5. Write Back (WB).

Ahora se entiende lo rebuscado de las operaciones de la analogía con los automóviles; el objetivo era que fueran similares a las etapas del procesador.
Las 3 primeras son fáciles de entender y corresponden con la carga de la instrucción a ejecutar, la segunda con la decodificación de la instrucción y lectura de los registros de los operandos, y la tercera es donde se hacen los cálculos. Para las otras dos etapas es conveniente explicar muy por encima la jerarquía de memoria.

Cuanto más cerca está la memoria del procesador, más rápida debe ser y menos tamaño puede tener. Conforme nos vamos alejando del procesador tenemos: registros, cache, RAM y disco duro. Las dos primeras están alojadas directamente en el procesador, la RAM está en la placa base y el disco duro se engancha a la misma.
En el MIPS64 tenemos 64 registros de 64 bits (32 de propósito general y 32 para operaciones en coma flotante) y una caché de primer nivel (puede haber más niveles…) de 64 kilobytes para instrucciones y otros 64 para datos.

Por tanto la etapa de Memory Access representa una lectura o escritura en la memoria RAM y la de Write Back representa la escritura en los registros de los resultados de las operaciones.

Las ventajas de la segmentación son muchas pero como todo en la vida tienen un precio o unos inconvenientes. Los problemas que hacen que la segmentación no funcione al mismo rendimiento que en la teoría se llaman riesgos y puede haberlos de tres tipos: riesgos de datos, de control y estructurales.

Riesgos Estructurales: en este tipo de riesgo uno de los problemas es que no todas las instrucciones van a requerir hacer uso de todas las etapas pero pueden tener que esperar a que alguno de los recursos quede libre, tardando al final lo mismo que la instrucción más larga. Así mismo no todas las operaciones elementales tienen la misma duración, por ejemplo una suma se realiza en menos tiempo que una división.

Además, si queremos armonizar las etapas de manera que todas avancen a la vez, sincronizadas con el reloj del procesador, tenemos que hacer que todas las etapas duren lo mismo. Esta es la solución ideal y, por definición, inalcanzable por lo que en la realidad diseñaremos el procesador de manera que en un ciclo le dé tiempo a terminar a la etapa más lenta. En el resto de etapas estaremos “perdiendo” tiempo desde que se termine hasta que se pase a la siguiente.

Otra de las facetas de los riesgos estructurales es cuando dos instrucciones distintas tienen que hacer uso del mismo recurso:


Para resolver este problema se pueden introducir paradas (“no op”: etapas que no realizan ningún trabajo) que sincronizan el cauce a costa de hacerlo menos productivo. Otra opción, más cara, es replicar los recursos que más van a utilizarse. Una tercera opción es dividir las etapas en dos subetapas, en una de ellas se leen datos y en la otra se escriben de manera que en la misma etapa se pueden hacer operaciones concurrentes con el mismo registro.

Riesgos de Datos: este tipo de riesgos se producen cuando entre las instrucciones existen dependencias de datos (tienen operandos comunes). Hay tres tipos de dependencias de datos:

-          Verdadera dependencia o RAW (Read After Write).
-          Antidependencia o WAR (Write After Read).
-          Dependencia de salida o WAW (Write After Write).

En MIPS no hay riesgos WAR ya que se produce la emisión de instrucciones en orden, de manera que se leen los registros antes de que se puedan modificar por otra orden posterior.

Los riesgos WAW pueden entenderse con el siguiente esquema:


En la imagen siguiente puede verse un caso de riesgo RAW; la instrucción de multiplicación requiere un dato guardado en el registro 1 que es el resultado de una instrucción suma que aún no ha terminado.


Hay tres formas de solucionar esto: introduciendo paradas que sincronicen el código, reordenando las instrucciones para evitar esas dependencias o implementar la técnica del “data forwarding”.

La primera de estas técnicas ya se ha visto para riesgos estructurales, mientras que la segunda también se puede aplicar para estos y consiste en introducir otras instrucciones que no dependen de los registros en conflicto hasta que se resuelva la parte WB de la primera instrucción. Esta técnica forma parte de la llamada “planificación dinámica”.

El “data forwarding” o anticipación consiste en dotar al hardware de una manera de redirigir el resultado de la etapa E de la primera instrucción en conflicto, directamente a la entrada de la etapa  E de la otra instrucción en conflicto. Esto evita que se detenga el cauce pero hace que la etapa ID de la segunda instrucción lea valores incorrectos.


Riesgos de Control: este tipo de datos se dan cuando en el cauce de instrucciones hay “saltos” fruto de sentencias condicionales tipo if. Normalmente el registro contador de programa (PC) se va actualizando con el valor de la siguiente instrucción a ejecutar pero cuando tenemos sentencias condicionales tenemos que esperar hasta que se resuelva la comparación para saber qué instrucción va a ser la siguiente en ejecutarse.
Como siempre, podemos poner paradas en el cauce hasta que se resuelva la indeterminación pero ya sabemos que con eso estamos echando por tierra las ventajas de la segmentación.

Otras soluciones pasan por predecir el salto o retardar la decisión (bifurcación retardada). Además de esto, existe una mejora del cauce MIPS que intenta minimizar el efecto de estos riesgos adelantando el cálculo de la dirección de salto a la etapa ID, de esta manera sólo se retarda un ciclo la ejecución de la siguiente instrucción.

En la bifurcación retardada seguimos ejecutando las siguientes instrucciones que hay en cola hasta que se resuelva el salto, siempre y cuando estas instrucciones se deban ejecutar siempre independientemente de que se tome o no el salto.

En la predicción de saltos lo que se hace es asumir que siempre se va a tomar el salto (o lo contrario) y actuar en consecuencia mientras no se sepa el resultado. Una vez que se sabe el resultado del salto se sigue con la ejecución ya planeada o se desechan las instrucciones que se habían alimentado. Analizando los costes de las dos opciones (siempre sí o siempre no) se llega a la conclusión de que en MIPS lo que más cuenta trae es actuar siempre como si nunca se fuera a tomar el salto. Esto se puede apreciar en el esquema siguiente.


 Bibliografía:

-          Patterson and Hennessy: Computer Organization and Design. The Hardware/Software Interface. Morgan Kaufmann Publishers. ISBN 1-55860-604-1
-          Apuntes de Arquitectura de Computadores y AGM de varias facultades de Informática

Tema 2.d: Explicación en detalle de los predictores de salto multinivel y adaptativos


En este artículo exploraremos con un poco más de profundidad algunas de las técnicas de resolución de riesgos de control, de los que ya hablamos en un artículo anterior.
Los riesgos de control son aún más frecuentes que los de datos, se dan en una de cada cinco instrucciones habitualmente, y tienen un impacto muy negativo sobre el cauce de ejecución de las instrucciones, penalizando incluso las soluciones tomadas para resolver los otros tipos de riesgo.

Nos centraremos en los predictores de salto multinivel y adaptativos.

Los predictores multinivel se denominan así porque pueden tener en cuenta información tanto local (del salto que se está intentando predecir) como global (de los demás saltos del programa). Estarán compuestos entonces de predictores locales y predictores globales y seguirán una notación como la siguiente (G, L) en la que la letra G indica el número de saltos globales que se tienen en cuenta y la L el número de bits del predictor local.

De los predictores locales hay dos tipos que son los que se usan con más frecuencia: los de 1 y 2 bits que en la notación vista se denominarían (0,1) y (0,2) respectivamente.

El de 1 bit sigue el esquema siguiente: tiene valor 1 si la última vez se tomó el salto y 0 si no fue así. Si la predicción falla se cambia su valor. Es un planteamiento muy sencillo y con una utilidad limitada ya que para ciclos repetitivos se suele fallar dos veces.

Con dos bits el esquema se vuelve un poco más complejo y nos protegemos de las excepciones en bucles condicionales repetitivos, se puede observar mejor su comportamiento en la siguiente figura:


Pueden implementarse predictores de más de dos bits pero la práctica ha demostrado que no merece la pena.

El uso de los predictores multinivel se basa en que se puede predecir el resultado del salto de una instrucción en función de los resultados de instrucciones de salto anteriores.

Los predictores adaptativos (o tournament predictors) tienen la capacidad de escoger un predictor local o un predictor global según cuál se vaya a comportar mejor para un determinado salto.

Si el buffer de predicción predice que el salto no se toma, no hay ningún retraso puesto que al ciclo siguiente se busca la instrucción siguiente. Pero si se predice que el salto se va a tomar, no se puede buscar la instrucción destino de salto hasta que no se haya calculado la dirección de esta instrucción. Y una vez que se conozca esta instrucción ya se conoce si el salto se toma realmente o no, así que no tiene sentido continuar utilizando la predicción.

La solución está en implementar algún mecanismo que permita predecir también la dirección destino de salto. Este mecanismo es el buffer de predicción de destino de salto llamado BTB (Branch Target Buffer).

El uso del BTB resulta especialmente importante en arquitecturas como la MIPS en la que conocemos a la vez el resultado de evaluar la condición de salto y la dirección de destino del mismo. El BTB es en esencia una caché que almacena la dirección destino que tuvo cada salto la última vez que se tomó. El acceso al BTB se hace durante la etapa IF de las instrucciones: al mismo tiempo que se busca la instrucción en la memoria de instrucciones con su dirección se accede al BTB para saber si se trata de una instrucción de salto.

Otra forma de predicción de saltos adaptativa y que resulta especialmente útil para aquellos saltos que se evalúan en tiempo de ejecución (saltos indirectos) es la pila de direcciones. La razón por la que no se puede usar el BTB con la misma fiabilidad para este tipo de saltos radica en que la dirección de destino del salto va variando en cada ejecución de la instrucción de retorno.

Esta pila funciona de manera que se almacenan las direcciones desde las que se llama a los procedimientos. Si la pila es lo suficientemente profunda, cuando se realicen los retornos se irán recuperando las direcciones adecuadas de la pila y se cumplirán las predicciones con un elevado porcentaje de acierto.

En el gráfico siguiente se puede ver el rendimiento de esta técnica en distintos procesadores.