lunes, 30 de noviembre de 2009

Explicación al detalle de las técnicas de gestión de E/S

Un ordenador no puede funcionar si no tiene datos para poder trabajar con ellos. Estos datos no se crean de la nada, sino que tienen que alguien tiene que ponerlos en el ordenador a través de un sistema de Entrada/Salida.
Los dispositivos de E/S (teclado, ratón,…) se comunican con la CPU a través del bus del sistema. Al no estar tan optimizada la E/S como el resto de sistemas, puede llevar a la bajada de rendimiento de nuestros equipos. Para solucionar esto, se han ideado técnicas de gestión con las que realizar las tareas de E/S sin que afecte al resto del sistema.

E/S Programada.- Es tan simple como que la CPU realiza un sondeo (en bucle) sobre si los controladores del dispositivo de E/S para ver su estado, y usarlos cuando sea preciso. Este sistema está anticuado, ya que la CPU estará la mayoría de veces en espera de los dispositivos de E/S.

E/S por Interrupciones.- En vez de ser la CPU la que espere al dispositivo, será el dispositivo el que interrumpa a la CPU para avisar de la finalización de las operaciones. Entonces la CPU puede resolver que dispositivo ha lanzado la interrupción, realizar las operaciones necesarias (rutina de manejo de interrupciones) y enviar la siguiente operación al dispositivo.
Esta técnica permite a la CPU estar trabajando en otras operaciones sin dedicarle tiempo al dispositivo. Este manejo de la E/S puede parecer un mecanismo bastante bueno, pero todo depende de si hay excesiva carga de E/S, porque si se da el caso la CPU puede dedicar demasiado tiempo al manejo de estas instrucciones y llegar de nuevo a la bajada de rendimiento.

E/S por DMA (Acceso Directo a Memoria).-
Tendremos un dispositivo auxiliar que controlará por sí mismo la escritura de E/S directamente en memoria, sin pasar por la CPU. La CPU sigue teniendo carga de trabajo, pero es mínima, solo se encarga de decirle a la DMA la fuente/destino de la transferencia de datos. Para poder llevar a cabo la transferencia de datos, la DMA “roba” un ciclo del bus el sistema para poder escribir en memoria. Una vez los datos estén en memoria la DMA avisa a la CPU que los datos están listos.
Esta forma de trabajar evita que la CPU tenga que estar cambiando de contextos de procesos cada vez que una operación de E/S de termine. En contra tenemos que el DMA y la CPU estarán compitiendo por el uso del bus y puede darse que la CPU trabaje a menor velocidad al final.

E/S por Procesador Dedicado.-
Hoy en día el peso de las operaciones de E/S se deja sobre un co-procesador dedicado exclusivamente a ello. La CPU solo se comunica con él para comunicarle sus necesidades de los dispositivos de E/S. El procesador de E/S ejecuta código propio para controlar la operación. Además, en la actualidad, se añade cierta cantidad de memoria RAM a los dispositivos, y las transferencias se realizan sobre esta memoria.

Comparativa: PCI‐Express vs. PCI y AGP

Poniéndonos en antecedentes podemos ver como los buses PCI y AGP “competían” en la misma época. Ambos estaban presentes en numerosas tarjetas gráficas y de prestaciones equiparables, aunque cada una trabajase de cierta manera. PCI-Express es la evolución del PCI y el bus actual de las tarjetas gráficas. Pasemos a ver las características de cada uno.

PCI.- El bus PCI tiene 32 bits de comunicaciones que trabajan a una frecuencia de 33 MHz, por lo tanto la tasa de transferencias teórica es de 133 Mbits/s. Velocidad de transferencia más que suficiente para cualquier tarjeta gráfica 2D.
Evidentemente no solo hay un tipo de PCI, dependiendo de los requisitos electrónicos se pueden dividir en tres tipos.
  1. PCI de 5 voltios.
  2. PCI de 3.3 voltios, más usadas en ordenadores portátiles.
  3. Universales, seleccionan el voltaje automáticamente y se utilizan tanto en sobremesas como en portátiles.
También existen distintas ranuras de acuerdo con los bits que se puedan transportar.
  • Ranuras de 32 bits: son las normales y más extendidas.
  • Ranuras de 64 bits: muy recientes, agregan 32 conectores más.
AGP.- Bus para conectar periféricos a la placa base del equipo. Los buses AGP trabajan a distintas frecuencias y voltajes, hay más diferencias entre ellas que en el caso de las PCI.
  1. AGP 1X, frecuencia de 66 MHz y tasa de transferencia de 264 MB/s con un voltaje de 3,3 V.
  2. AGP 2X, frecuencia de 133 MHz y tasa de transferencia de 528 MB/s con un voltaje de 3,3 V.
  3. AGP 4X, frecuencia de 266 MHz y tasa de transferencia de 1 GB/s con un voltaje de 3,3 o 1,5 V, para poder adaptarse al diseño de tarjetas gráficas.
  4. AGP 8X, frecuencia de 533 MHz y tasa de transferencia de 2 GB/s con un voltaje de 0,7 o 1,5 V.
PCI-Express.- Es mucho más veloz que los dos buses anteriores, convirtiéndose en el sustituto natural de los dos. Dependiendo del dispositivo existen PC-Express de distintas frecuencias de reloj. Para trabajar con dispositivos de sonido o de televisión se puede utilizar PCI-Express 1x (133Mhz). Pero en el caso de tarjetas gráficas se utiliza PCI-Express 16x de 2128Mhz. Existen más modelos (1x, 2x, 3x, 4x, 16x).
Se ha convertido en el sustituto de AGP por velocidad de transferencia y al ser la evolución del PCI se ha afianzado en el mercado.

viernes, 27 de noviembre de 2009

Análisis de Jerarquia de memoria: MacBook

Voy a centrarme en el análisis de la jerarquia memoria de un ordenador que hoy en dia esta de moda (no se puede definir de otra manera). El MacBook es un ordenador portatil de Mac con unas especificaciones muy concretas, no es tan buena máquina como diseño, al estilo de los productos Mac. Según he podido investigar la jerarquia de memoria del equipo queda de la siguiente manera:
  • Caché L1: el MacBook lleva un procesador Intel Core 2 Duo con dos niveles de cache. Cada core lleva un nivel L1 de 64 KB (32 de instrucciones/32 de datos).
  • Caché L2: Un nivel de cache L2 de 3 MB compartida por el par de nucleos que funciona a la velocidad del procesador. Los dos niveles de cache trabajan a la frecuencia de reloj del procesador, 2,26 GHz.
  • Bus de comunicación frontal: Conecta la CPU, memoria principal y el resto de componentes del equipo. Trabaja a 1.066 MHz.
  • Memoria Principal: Dos módulos SO-DIMM de memoria DDR3 de 1 GB cada uno, un total de 2 GB. Trabaja a 800 MHz (2 transferencias por ciclo).
  • Memoria secundaria: Disco duro SATA de 250 GB o 500 GB.

jueves, 26 de noviembre de 2009

Memorias DRAM de Tarjetas Gráficas y Consolas

Toda arquitectura (tanto gráfica como de propósito general) tiene una memoria principal. Al aparecer arquitecturas dedicadas a gráficos se provocó un avance, y una especialización de memorias dedicadas a gráficos. En este post daré un repaso leve a distintas memorias DRAM para tarjetas gŕaficas y comentaré los tipos de memoria de la actual generación de consolas.

Memorias DRAM en Tarjetas Gráficas
:
  • DRAM EDO.- Esta memoria era capaz de acceder introducir datos mientras los de salida aun no estan colodos en el BUS del sistema, tenían una especie de buffer. La máxima velocidad de lectura de la memoria EDO RAM es de 5-2-2-2 ciclos y es difícil crear memorias de este tipo que funcionen a velocidades de reloj superiores a 66Mhz.
  • VRAM.- Este memoria es exclusiva de vídeo. Esta memoria era muy similar a la EDO, la principal caraterística es que se podía acceder a memoria desde dos dispositivos a la vez, tenia un puerto dual, o leer y escribir al mismo tiempo.
  • WRAM.- No es más que una VRAM optimizada, trabaja del mismo modo, con puerto dual, pero tiene un tiempo de acceso más rápido y es más barato.
  • SGRAM.- Es un tipo de especialización de la memoria SDRAM (de ámbito general). Añade mejoras a la hora de escribir en un solo bit sin afectar a otros y escritura de linea entera de un mismo "color". Tiene un solo puerto de entrada y salida pero puede simular el doble puerto creando dos paginas de memoria
  • MDRAM.- Esta arquitectura define la memoria como un conjunto de bloques pequeños (32 KB) en paralelo conectados a un BUS. Esto conlleva poder trabajar con accesos a memoria en paralelo.
  • 3DRAM.- Es una memoria optimizada para 3D, ya que integra en la memoria una unida ALU para poder llevar a cabo operaciones (Z-Buffer, por ejemplo) en la misma memoria.
  • GDDR (1,2,3, 4, 5).- Son memorias basadas en la tecnología DDR (dos transferencias por ciclo, en bajada y subida) pero optimizadas para tarjetas gráficas. Los distintos tipos son sucesivas mejoras en rendimiento, velocidad y amplitud de ancho de banda, pero la arquitectura sigue siendo la misma. Las tarjetas gráficas de alta prestaciones actuales usan GDDR5 y las de baja GDDR3.
Después de ver este leve resumen, podemos observar como los avances en memoria se dan de manera paralela entre memoria para PC y para gráficos, siempre siendo la de gráficos optimizada.
Ahora veamos que tipos de memoria utilizan las consolas de la actual generación:
  • XBOX 360.- GDDR3 RAM a 700 Mhz, es una arquitectura convencional, no quiere decir que la tarjeta gráfica sea de baja gamma, simplemente no les hace falta más.
  • PS3.- Para sorpresa tiene dos módulos de memoria. Uno GDDR3 para la GPU (características similares a la XBOX) y otra XDR RAM, memoria de tipo Rambus RAM que se basa en una comunicación serie de alta velocidad y prestaciones.
  • Nintendo Wii.- GDDR3 normal para trabajar con gráficos y una ARAM (memoria de bajas prestaciones) dedicada exclusivamente al audio, así liberan la GDDR3 de datos de audio.

Organizaciones de Memoria Cache y su rendimiento

Uno de los problemas importantes a la hora de la velocidad de trabajo de un ordenador son los retardos por accesos a memoria. La CPU tiene que trabajar con datos, pero estar continuamente accediendo a la memoria principal es costoso en tiempo. Por ello en los ordenadores de hoy en día existe la Jerarquía de Memorias:Esta jerarquía nos ayuda a agilizar los accesos a memoria. Pero hay que tener en cuenta que el rendimiento que esta jerarquía (el caso que estudiamos el de la cache) depende totalmente de la organización de ellas.
Podemos pensar en la caché como una tabla dividida en filas, que serán las unidades básicas de almacenamiento. Cada vez que traemos información de le memoria principal a la caché, traemos como mínimo una línea, funcionando del mismo modo a la hora de escribir desde caché a memoria principal.
La idea principal que debemos tener en cuenta para organizar la cache, es como se va a comunicar la caché con la memoria principal. Es decir, como vamos a traducir las direcciones de la memoria principal en caché. Existen tres técnicas:

1) Caché completamente asociativa:
Este tipo de caché puede almacenar en cualquiera de sus filas cualquier posición de memoria principal. Esto quiere decir que no se realizan búsquedas para seleccionar en que parte de la caché se almacenará (en la primera línea vacía que tengamos) y que el acierto es muy alto. Pero por el contrario, el tiempo de acceso a la caché es muy alto, ya que al buscar cualquier dato nos encontramos con que puede estar en cualquier parte.

2) Caché de mapeado directo:
En este caso cada dirección de memoria principal tendrá una posición en caché concreta donde se debe almacenar. Esto nos da la ventaja de saber de antemano que al acceder a caché encontraremos la dirección que estamos buscando en esa linea, es decir, velocidad de acceso muy alta.
Pero por otro lado tenemos el inconveniente de que a una linea de caché corresponden varias posiciones de memoria principal, o lo que es lo mismo, que hay muchas posibilidades que cada vez que busquemos los datos en caché de cierta posición de memoria, encontremos datos referentes a otra posición, tendremos una alta tasa de fallos.

3) Caché asociativa por conjuntos:
Si ninguno de los métodos de organización anteriores son eficientes, podemos mezclarlos para dar una organización mixta. Esta es la idea de la "asociativa por conjuntos". La caché estará dividida por bloques o conjuntos con más de una linea, cada dirección de memoria principal corresponderá a un bloque y dentro del bloque se distribuirá de manera asociativa.
En este caso particular la eficiencia dependerá del tamaño del bloque que decidamos utilizar. Mientras mayor sea el tamaño de bloque la memoria parecerá más asociativa, y si es menor más de mapeado directo, cada una con sus ventajas e inconvenientes.

lunes, 9 de noviembre de 2009

Multithreading en Arquitecturas Gráficas

El Multithreading (o multihilo en español) es una forma de programar, y por consiguiente de estructurar el hardware del procesador para la compatibilidad, en la cual los hilos de ejecución comparten el mismo estado de memoria. Al separar las tareas en hilos de ejecución diferentes, el procesador puede llevar a cabo muchos más al mismo tiempo y, por lo tanto, aumentando la productividad. Evidentemente no es fácil de hacer, hay que tener en cuenta que se deben programar hilos teniendo en cuenta su tiempo de ejecución.
El Multithreading surgió en las CPU y hasta hace poco no se encontraban en las arquitecturas gráficas. A partir de 2008 surgen tarjetas gráficas con arquitecturas con varios núcleos, en los cuales se puede aprovechar el multithreading.
En clase hemos visto la serie 9 de las tarjetas gráficas de Nvidia. Las arquitecturas de esta serie de tarjetas gráficas incluyen una arquitectura multinúcleo. Pero no solo se trabaja de esta manera en las tarjetas gráficas, por ejemplo la tecnología Hybrid SLI de Nvidia. Esta tecnología en los portátiles trabaja con una tarjeta gráfica integrada en la placa base y otra no integrada, haciendo que las dos trabajen conjuntamente.
Un ejemplo más actual de este modo de trabajo lo tenemos en la nueva tecnología de Nvidia Fermi (vista en una entrada anterior del blog). Esta arquitectura tiene un controlador llamado GigaThread que se encarga exclusivamente de poder trabajar con el multithreading.

Predictores de salto multinivel y adaptativos

Los predictores de saltos son recursos hardware para reducir ciclos de paradas de la ejecución. Concretamente paradas provocadas por tener que evaluar una condición antes de decidir cual será la siguiente instrucción. Para poder crear predictores funcionales hay que estudiar el comportamiento de los programas. Hoy voy a analizar dos tipos de predictores en concreto:

Predictores de Salto Multinivel
Los predictores multinivel se caracterizan por utilizar información del salto para el que se realiza la predicción, junto a información del resto de saltos del programa.
Un ejemplo sencillo para entender esta clase de predictores es el paso del preditor 1-1. Su nombre viene de utilizar el comportamiento del último salto para seleccionar un predictor de 1 bit para el salto que estamos evaluando. El predictor que queda es el siguiente:
  1. El primer bit denomina la predicción si el último salto del programa no se había tomado.
  2. El segundo bit denomina la predicción en el caso contrario, si se ha tomado el último salto.
Los predictores multinivel se denominan M-N, es decir, utilizan el funcionamiento de los m últimos saltos tomados para escoger un predictor de n bits para el salto que se está evaluando.
Si tenemos la información de los saltos anteriores del programa podemos mejorar la tasa de aciertos de la predicción del salto actual. Pero tiene una pega grande, la gran complejidad del hardware que hace falta para tener encuentra la predicción de todos estos saltos.

Predictores Adaptativos
Estos predictores pueden seleccionar si trabajan con predictores que trabajen con información exclusivamente del salto con el que estamos trabajando o con información los n saltos anteriores (como los predictores multinivel).
Un ejemplo de predictor adaptativo trabajaría de la siguiente manera: Si las dos últimas predicciones de salto han fallado con un predictor que evalúa la información local, se cambia la siguiente predicción, para que se escoja teniendo en cuenta la información de otros saltos del código del programa.

sábado, 7 de noviembre de 2009

Análisis de una arquitectura de CPU: Intel Core i7

Al mismo hilo que la entrada anterior, vamos a analizar un poco la nueva arquitectura de CPU de Intel: Intel Core i7La principal característica de esta linea de CPU son sus 4 procesadores de 64 bits de tamaño de palabra. Se ha optimizado la comunicación entre los procesadores para acelerar la realización de tareas simultaneas.
Además, tal y como se puede apreciar en el esquema, cada procesador lleva consigo un controlador de memoria integrado. Este controlador ofrece mejoras en el ancho de banda y latencia para programas con uso intensivo de datos. Estas mejoras vienen en forma de 3 canales de comunicación con memoria principal DDR3. Esto, según hemos visto actualmente en clases, significa la posibilidad de trabajar con hasta tres módulos de memória principal DDR3 paralélamente.
No solo el acceso a la memoria principal se ha mejorado, la cache principal del procesador es de un tamaño de 8 MB, lo que ayuda bastante a la ejecución de programas.
Un último detalle que comentar son sus ocho subprocesos de procesamiento con la tecnología Hyper-Threading, con lo cual sus cuatro procesadores simularán ser 8 procesadores.

Análisis de una arquitecuta de GPU: Nvidia Fermi

Por seguir la evolución de las tarjetas Nvidia vistas en clase he preferido analizar la nueva arquitectura de Nvidia: Fermi.
Tal y como las series vistas en clase, el hardware está pensado para gestionar tres tipos de threads que se ejecutan en la GPU. En este caso se han ampliado la cantidad de chips como se hizo en el paso de la serie 6 a 7. Especialmente diseñado para ejecutar una enorme cantidad de tareas en paralelo.

-16 celdas de stream (Streaming Multiprocessor)
-32 cores en cada celda
-Cada celda contiene una memoria a modo de registros de 4 kb.
-2 niveles de chache. Nivel 1 de cache totalmente dedicada para cada celda de stream (1Mb) y una cache compartida por todas las celdas de nivel 2 (768Kb).
-Para la ejecución de threads se dispone de un controlador que los gestiona, el GigaThread.
-Además cada celda SM contiene procesadores especiales para calculo de operaciones complejas con números en coma flotante.

Como contrapunto, la única pega que se le puede sacar es la poca memoria por celda usada a modo de registros. Imagino que esto puede acarrear dificultades a la hora de la cantidad de operaciones que se ejecutan.