Mostrando entradas con la etiqueta Intel. Mostrar todas las entradas
Mostrando entradas con la etiqueta Intel. Mostrar todas las entradas

miércoles, 6 de enero de 2010

Itanium

Los procesadores Itanium fueron desarrollados por Intel y HP entre los años 1989 y 2000. El lanzamiento se produjo finalmente en el año 2001 y en 2002 se lanzó al mercado Itanium 2 que corregía la jerarquía de memoria del primer diseño, que se mostró ineficiente, además de añadir más unidades funcionales. Esta versión ha tenido revisiones en las que se ha mejorado el proceso de fabricación, aumentado el tamaño de la memoria caché, añadido núcleos y algunas características como soporte para virtualización o multithreading.

El objetivo del diseño del itanium era conseguir una arquitectura que maximice el número de instrucciones por ciclo. A esta arquitectura se le conoce con el nombre EPIC (Explicitly Parallel Instruction Computing). La base de este diseño es utilizar instrucciones muy largas (128 bits) que en realidad contienen 3 instrucciones de 41 bits que pueden ejecutarse simultáneamente. Esta agrupación la realiza el compilador, que es el que tiene toda la responsabilidad en lugar de la lógica del procesador como sucede en los procesadores x86 más comunes, que pueden ejecutar fuera de orden.

Este es un esquema de bloques del procesador Itanium original:

Como hemos dicho, el objetivo del diseño es ejecutar el mayor número posible de instrucciones en paralelo. Por ello tiene un gran número de unidades funcionales en 11 grupos diferentes:
  • 6 ALUs de propósito general
  • 2 unidades de enteros
  • 1 unidad de desplazamiento de bits
  • 4 unidades de acceso a caché
  • 6 unidades de cálculo multimedia
  • 2 unidades de desplazamiento de bits en paralelo
  • 1 unidad de multiplicación en paralelo
  • 1 unidad de "population count" (número de bits a 1 en un registro)
  • 2 unidades de coma flotante de 82 bits
  • 2 unidades de coma flotante SIMD
  • 3 unidades de cómputo de saltos
Cada grupo de unidades puede ejecutar un subconjunto de instrucciones, dependiendo del tipo que sean. Las instrucciones más comunes pueden ser ejecutadas por más de 1 tipo de unidades. Cada instrucción pertenece a uno de los siguientes tipos:
  • A: números enteros (ALU)
  • I: números enteros (no ALU)
  • M: acceso a memoria
  • F: Punto flotante
  • B: Salto
  • L+X: Tipo extendido, dependiendo del subtipo se ejecuta en distintas unidades.
Por ejemplo las instrucciones de tipo A pueden ejecutarse en las unidades de enteros, en las ALUs de propósito general y en las de cálculo multimedia.

El procesador tiene una gran cantidad de unidades disponibles y reparte el trabajo según el tipo de instrucción entre ellas, mediante estaciones de reserva siguiendo la estrategia del algoritmo de Tomasulo. Si nos fijamos, un conjunto de 3 instrucciones ocupa 41*3=123 bits. Los 5 bits que faltan hasta 128 bits indican al procesador que combinación de tipos de instrucciones hay. Por ejemplo, 00001 indica que la primera instrucción es de tipo M, mientras que la 2ª y 3ª son de tipo I. Además de una gran cantidad de unidades funcionales, también tiene una gran cantidad de registros. Hay 128 registros de proposito general de 64 bits, 128 registros de coma flotante de 82 bits y 64 registros de predicación de 1 bit.

Para mantener las unidades funcionales activas, el procesador implementa varias técnicas conocidas. En primer lugar, emite dos instrucciones por ciclo de reloj. Teniendo en cuenta que cada una es un paquete con 3 instrucciones, son 6 las instrucciones efectivas que puede llegar a emitir. Otra técnica de la que hace uso este procesador es la predicción de saltos. El procesador tiene 2 predictores, uno de ellos es un buffer de predicción de salto, mientras que el 2º es un predictor de 2 niveles. También implementa un predictor de dirección de retorno para las llamadas a funciones. Lo más distintivo de este procesador es que el compilador puede añadir sugerencias sobre los saltos, haciendo que el procesador lo evalúe de manera dinámica (utilizando los predictores) o de manera estática (haciendo caso a la recomendación del compilador).

El procesador también tiene la capacidad de especular y también implementa una técnica que no es común en los procesadores actuales, que es la predicación. Al usar esta técnica, el procesador ejecuta las 2 ramas de un salto y descarta la que no se toma una vez conocido el resultado de la instrucción de salto. Esta técnica encaja con la gran cantidad de registros y unidades funcionales del procesador. Esto es especialmente práctico en el caso de saltos condicionales que ejecutan pocas instrucciones. El compilador puede elegir qué debe realizar el procesador. Para ello, cada instrucción tiene 6 bits reservados para indicar que registro de predicación indica si la instrucción se debe ejecutar o no. Hay un registro cuyo valor es siempre verdadero, por lo que se puede usar para ejecutar instrucciones sin predicción. El funcionamiento de esta técnica se puede ver en este esquema:

En el caso de usar predicación, se evalúa que r1 valga 5 y el resultado se asigna a los registros de predicación qp1 y la negación a qp2. A continuación se ejecutan ambas ramas, solo que las operaciones cada una están asociadas un registro de predicación. El resultado de las ramas se utilizará o se desechará según el resultado final de la instrucción test. Otra vez más, es el compilador el que tiene la responsabilidad de utilizar la predicación adecuadamente.

La jerarquía de memoria está dividida en 3 niveles. La memoria de primer nivel está separada en 2, una para instrucciones y otra para datos. Ambas son asociativas por conjuntos (4) y tienen un tamaño de 16 KB cada una. La memoria de nivel 2 ha sufrido varios cambios. Inicialmente era una memoria asociativa por conjuntos (6) con un tamaño de 96 KB, compartida para código y datos. Con los procesadores Itanium II aumentaron el tamaño hasta 256 KB y la asociatividad a 8. Desde mediados del 2006 la memoria caché de nivel 2 está separada en una caché de datos de 256 KB y una de instrucciones de 1 MB. La memoria caché de nivel 3 se accedía a través del FSB en el caso de los primeros Itanium y consistía de una caché asociativa por conjuntos (2) de 2 ó 4 MB. Al revisar la jerarquía de memoria con los Itanium II se incluyó memoria caché asociativa por grupos (2 ó 4) de nivel 3 en el mismo integrado. El tamaño varía según el modelo desde 1.5 MB hasta 24 MB en los últimos modelos con 2 núcleos (12 por núcleo).


Este tipo de procesadores está orientado a la computación de alto rendimiento. La arquitectura Itanium consigue un rendimiento altísimo en cálculo en coma flotante y de hecho ha sido muy utilizada en supercomputadores.

Patxi Astiz

martes, 5 de enero de 2010

Análisis "ClarkDale's Efficiency"

Hay varias páginas web que realizan análisis y comparativas de hardware de consumo como procesadores, memoria, tarjetas gráficas, placas base, etc, etc. Una de las más famosas es Tom's Hardware.

Vamos a fijarnos en el siguiente artículo. En él se compara el rendimiento del procesador Intel Core i5-661 frente a los procesadores AMD Phenom II X2 550, AMD Athlon II X2 240e e Intel Core 2 Duo E8600.


El árticulo comienza con dando detalles de la arquitectura de la familia de procesadores Core i5 que Intel ha lanzado recientemente. Una de las novedades más importantes de estos es que en el mismo empaquetado se encuentra el procesador, el controlador de memoria y una GPU. En el caso de los demás procesadores, se han escogido placas base con GPUs integradas.


En este tipo de análisis hay muchísimos factores que influyen en el resultado final y resulta casi imposible aislar el rendimiento del procesador. Por ello se suelen realizar una gran cantidad de pruebas de distinto tipo, tanto sintéticas como pruebas de rendimiento con aplicaciones o juegos de uso común. En este artículo se utilizan los benchmarks SiSoftware Sandra 2009, PCMark y 3DMark y se utilizan aplicaciones muy exigentes con la CPU o con la GPU, desde juegos como Far Cry o Left for Dead hasta aplicaciones audio/video, compresión de datos, antivirus y modelado 3D entre otros. El conjunto de tests es variado y permite hacerse una idea del rendimiento que ofrece el sistema en bastantes de las tareas más comunes.

Este árticulo hay ciertos aspectos criticables. En primer lugar, los sistemas elegidos para comparar son muy diferentes. Mientras que el procesador Core i5 tiene la GPU empaquetada junto con el procesador, los demás la tienen integrada en la placa base. Además estas GPUs integradas, son más antiguas y todas, excepto las de los procesadores AMD son diferentes entre sí, por lo que en algunos test las diferencias de rendimiento no se sabe en que medida se deben a la CPU o a la GPU. Quizás habría sido más acertado comparar los diferentes modelos de la misma familia de procesadores o no incluir benchmarks en los que la GPU tenga un papel importante, si el objetivo era evaluar solo la CPU.

Otro aspecto a destacar es que se está comparando un procesador con un diseño muy reciente (Core i5) y fabricado en una tecnología de 32nm, (más capacidad de integración y menor consumo) con diseños menos actuales con una tecnología peor (45 nm.). De hecho teniendo en cuenta el precio de venta de los procesadores, algunos de ellos ni siquiera se podría considerar que sean de la misma gama.

Algunas diferencias entre los procesadores escogidos para comparar son especialmente importantes. Por ejemplo, el procesador Core i5 tiene un motor que acelera el cifrado/descifrado AES, lo que le da una ventaja enorme en los test que lo utilizan. Además, en la parte final del artículo se ejecutan una serie de aplicaciones y se compara la potencia eléctrica consumida para realizar el mismo trabajo, suponiendo que la mayor parte de la potencia consumida se debe al procesador. De aquí se saca una medida de la eficiencia eléctrica del procesador. Esta es una medida interesante, pero esta influenciada por demasiados factores, como la tecnología de fabricación antes mencionada, el consumo del resto de elementos del sistema, la calidad del PFC de la fuente de alimentación, etc.

En resumen, el análisis examina el rendimiento de un sistema con Core i5 en pruebas muy diferentes, ayudando a tener una idea del rendimiento que podemos esperar de este procesador. Sin embargo al comparar con otros procesadores, hay demasiadas diferencias (en tecnología y en precio) entre los sistemas escogidos y las comparaciones en algunos aspectos pierden valor. Habría sido más ilustrativo el enfrentar distintas versiones del mismo procesador o simplemente analizar el Core i5 sin compararlo con otros.

Patxi Astiz

martes, 10 de noviembre de 2009

Core i7

Los procesadores Core i7 están fabricados con la última arquitectura de Intel. Esta es una evolución de la de los procesadores Core 2. Se han mejorado varios puntos de dicha arquitectura, se ha añadido multithreading y varios elementos al procesador que veremos al final de esta entrada. Primero vamos a concentrarnos en el núcleo de la arquitectura.

Empezaremos por el front buffer, encargado de suministrar las instrucciones a las unidades de ejecución. Es la parte que corresponde a las fases IF (instruction fetch) e ID (instruction decode) de un pipeline sencillo. Veamos un esquema.



Como se puede ver, el procesador tiene una caché de instrucciones de 32 KB de la que se leen para pasar a decodificarlas. Esta caché está conectada a otra de nivel 2, de 256 KB. La decodificación y traducción desde instrucciones x86 hasta microOps, que son las que realmente maneja el procesador internamente se realiza en 2 pasos. El procesador al tener varios decodificadres, uno de ellos complejo y poder fusionar instrucciones, tiene un máximo teórico de 5 instrucciones x86 emitidas por ciclo. En este proceso de decodificación también se realiza la predicción de saltos y la detección de bucles. Aunque Intel no ha revelado qué tipo de predictor de saltos utiliza, se sabe que hay al menos 2 predictores de 2 niveles. También hay un buffer con direcciones de retorno de llamadas a procedimientos. De esta manera se gestionan más rápidamente estos saltos indirectos. Como novedad en esta arquitectura, la detección de bucles se realiza después de terminar la decodificación. De esta manera las instrucciones de un bucle ya están decodificadas y se libera de trabajo a los elementos previos del front-end, incluida la caché de instrucciones. Por último, se reservan registros y se leen los valores del buffer de reordenación que sean necesarios antes enviar una instrucción a la fase de ejecución, que vemos en el siguiente diagrama.

Como se muestra en el diagrama, solo hay una estación de reserva unificada de 128 entradas, que se encarga de suministrar instrucciones a las 6 unidades funcionales siempre que sea posible. De estas unidades, 3 hacen operaciones load/store y otras 3 calculos aritméticos y lógicos. Los resultados se llevan al buffer de reordenación que hemos visto anteriormente. Los resultados de las operaciones load/store además, no acceden directamente a la caché de datos de 32 KB que tiene el procesador, sino que pasan por un buffer intermedio, para evitar los riesgos de datos al leer y escribir en instrucciones diferentes que han podido ser ejecutadas fuera de orden. Desde este buffer pasa a la caché.

De manera resumida hemos visto el funcionamiento de la base de un procesador Core i7, y como en general sigue un diseño típico en los procesadores de propósito general de hoy en día, utilizando las técnicas de optimización comunes, como predicción de saltos, especulación o multithreading. Sin embargo lo que hemos visto corresponde solo a un nucleo del procesador. El diseño del Core i7 se ha hecho de manera modular, por lo que un procesador con esta arquitectura puede tener 2 o más nucleos como el descrito. Todos estos núcleos comparten otros elementos que vamos a ver a continuación:

En este ejemplo, hay 4 núcleos. Cada uno de ellos tiene los elementos que se han descrito anteriormente. Los 4 sin embargo comparten el resto de elementos, entre ellos la caché de nivel 3, cuyo tamaño es 8 MB.

Mientras que los núcleos de un Core i7 son en gran medida iguales a los de un Core 2 aunque con más recursos (más entradas en la estación de reserva, mayor buffer de reordenación, etc...) y algunas mejoras, en el diseño de esta arquitectura hay cambios muy importantes. Especialmente la inclusión del un controlador de memoria DDR3 de 3 canales en el chip y el uso de un bus (llamado QPI) de interconexión entre procesadores (para entornos multiprocesador) y entre el procesador y el hub de la placa base. De esta manera se evita el clásico FSB (front side bus) que en caso de haber más de un procesador, se compartía para acceder a la memoria así como para comprobar la coherencia de las cachés de cada procesador. La arquitectura Core i7 pasa a ser NUMA (Non-Uniform Memory Access). Este diseño es prácticamente el mismo que introdujo AMD hace varios años en sus procesadores Opteron y posteriores con buenos resultados.

En este diagrama podemos ver la configuración de una máquina con dos procesadores Core 2 y a la derecha la configuración NUMA equivalente con 2 procesadores Core i7.

Mientras que antes los procesadores tenían que repartirse el bus de salida para llegar a cualquier recurso que estuviera fuera del propio procesador, con la arquitectura Core i7, un procesador tiene buses diferentes para acceder al parte de la memoria, al hub de la placa base (y por lo tanto a periféricos como la tarjeta gráfica) y al otro procesador (y a la memoria que este controla), por lo que no habrá conflictos por compartir un mismo bus con el otro procesador. Otra de las ventajas de este diseño es que los accesos a memoria tienen menos latencia, al estar conectada directamente al controlador de memoria del procesador. Incluso en los casos en los que un dato está en los bancos de memoria del otro procesador, la latencia, aunque peor que si la memoria estuviera conectada directamente al procesador que pide el acceso, mejora respecto a las arquitecturas anteriores.

Como hemos visto esta arquitectura no presenta grandes cambios en lo que es el diseño del núcleo del procesador, pero sí supone un avance importante en la forma de conectarse con la memoria y otros elementos externos al procesador y que muchas veces puede ser el cuello de botella de un sistema.

Patxi Astiz