Intel ha introducido en el Intel Developer Forum celebrado estos días en San Francisco, su arquitectura de nueva generación, en la que estarán basados todos sus microprocesadores desde mediados de 2006. Atención, porque los cambios, como hemos venido apuntando estos días, son muy sustanciales.

————————————————————————————————

Durante los últimos días, hemos visto primero informaciones erráticas, luego tests a los que ha acompañado una agria polémica, y finalmente los primeros análisis sobre la nueva microarquitectura de Intel. Este artículo pretende meterse en profundidad con las características esenciales de la nueva arquitectura, en la que estarán basados los procesadores que lleven los Mac a partir de mediados de 2006, para poder hacernos una idea del rendimiento real que tendrán.

En particular, este artículo pretende servir para responder a la pregunta que se hacen muchos mackeros ahora mismo: ¿hay que esperar a Conroe, o CoreDuo es más que suficiente?

Pero antes de meternos a fondo con la nueva arquitectura, voy a hacer un pequeño resumen de dos técnicas que se utilizan en los microprocesadores modernos para mejorar el rendimiento (la segmentación y la superescalaridad), para que luego podamos entender mejor las cosas.

La segmentación y la superescalaridad

Un microprocesador es un circuito integrado que se dedica a ejecutar instrucciones de una determinada arquitectura. Un microprocesador es más rápido a medida que puede ejecutar más instrucciones en un intervalo de tiempo.

La técnica de segmentación (a veces más conocida por su nombre en inglés, pipelining) consiste en dividir el proceso de ejecución de instrucciones en varias fases independientes. Cada instrucción entra en la primera fase de ejecución, y en cada ciclo de reloj, pasa a la siguiente fase, hasta llegar al final y completar su ejecución. Cuando una instrucción pasa a la fase 2, una nueva instrucción puede entrar a la fase 1. Por tanto, en un cauce de 5 etapas de segmentación, por ejemplo, puede haber 5 instrucciones ejecutándose a la vez (cada una en una etapa distinta).

segmentado.png

Ejemplo de cauce segmentado

Este ejemplo de cauce segmentado es muy similar al de los procesadores RISC de principios de los 90.

Una pregunta que nos podemos hacer es: ¿porqué la segmentación mejora el rendimiento? La respuesta es sencilla: al dividir el proceso de ejecución en etapas más pequeñas, cada etapa dura menos tiempo, y por tanto, el tiempo de ciclo es menor. La “frecuencia de reloj” del procesador está directamente relacionada con ese tiempo de ciclo, por lo que, hasta hace muy poco, un procesador con un cauce muy segmentado como el del Pentium4 podía alcanzar frecuencias muy altas, es decir, muchos megahertzios.

En los últimos tiempos, toda la industria de semiconductores se ha encontrado con un problema muy serio: el consumo de los microprocesadores. Las arquitecturas que van a frecuencias muy altas (por ejemplo, el Pentium4) están consumiendo demasiado, y eso hace que sea virtualmente imposible utilizarlas en ordenadores portátiles, y que utilizarlas en servidores y ordenadores de sobremesa sea muy caro (la factura de la luz sube mucho en entornos con decenas o centenares de servidores) y muy molesto (por ejemplo, pensemos en los ventiladores necesarios para enfriar estos micros).

Otra posibilidad distinta para mejorar el rendimiento consiste en ejecutar más de una instrucción a la vez; en otras palabras, incorporar varios cauces, cada uno de ellos segmentado, de forma que varias instrucciones puedan entrar en el mismo ciclo a ejecutarse, y varias puedan ir ejecutándose en cada una de las etapas. Esta técnica se suele denominar superescalaridad, y fue introducida comercialmente en los años 80 (la primera empresa en lanzar un micro superescalar fue IBM, por cierto).
superescalar.png

Un posible diagrama de un microprocesador superescalar y segmentado

Hemos visto como en los procesos de fabricación actuales, es muy complicado llegar a frecuencias de reloj muy altas. Por ello, una posible vía alternativa es precisamente utilizar la superescalaridad para compensar las posibles pérdidas de rendimiento que ocasiona tener que ir a frecuencias más bajas, o similares que antes.

Una arquitectura muy superescalar se suele decir que es muy “ancha”, mientras que una arquitectura muy segmentada se suele decir que es muy “profunda”. Hay arquitecturas que se consideran muy “profundas” y “estrechas”, como el Pentium4, hay arquitecturas que se consideran “anchas” y “cortas”, como el Athlon, y hay arquitecturas que intentan ser a la vez “profundas” y “anchas”, como el G5.

Como resumen, podemos concluir que ambas técnicas, la segmentación, y la superescalaridad, se utilizan para mejorar el rendimiento de los procesadores al ejecutar un conjunto de instrucciones pertenecientes a un sólo proceso. La segmentación se ha utilizado de un modo muy extenso en los procesadores de los últimos años (en el Pentium4, en el Power4, en el G5, en los Alpha), pero ahora, segmentar demasiado los cauces parece que se considera ineficiente en los procesos de fabricación actuales. La superescalaridad proporciona mejoras de rendimiento, pero es costosa de implementar, por lo que veremos después.

Una vez superado el rollo introductorio (felicidades a los que hayáis llegado hasta aquí :-)), pasamos ya a lo que interesa: la nueva arquitectura de Intel.

Introducción a la microarquitectura Core

Para empezar, un comentario: no he visto jamás una empresa más confusa a la hora de adoptar nombres en clave de los distintos proyectos, productos, y plataformas, que Intel.

Intel ha decidido dar el nombre Core a la nueva microarquitectura, que sustituye a Netburst, la microarquitectura en la que se basan los diseños del Pentium4 y PentiumD. Y lo ha hecho a pesar de que ese nombre sea el mismo que tienen sus procesadores actuales para portátiles, los CoreSolo y CoreDuo. Por tanto, es necesaria una aclaración: los Core Duo no se basan en la nueva arquitectura, sino que se basan en una microarquitectura muy similar a la de los Pentium-M anteriores, que a su vez tienen una arquitectura similar a la P6, en la que se basaban los Pentium Pro, Pentium II, y Pentium III.

Para aclararnos un poco, veamos un pequeño esquema de la mayoría de procesadores de Intel de los últimos 10 años, junto con la arquitectura en que se basan:

micros_intel.png

Esquema de los microprocesadores de Intel más importantes de los últimos años

Aunque este esquema es una simplificación (hay bastantes diferencias entre el PentiumPro original y los actuales CoreDuo), el caso es que la arquitectura Netburst, que originariamente estaba destinada a sustituir a todos los procesadores de Intel, se demostró muy pronto ineficaz para ordenadores portátiles, que requieren un consumo muy limitado.

Posteriormente, además, la última versión de esta arquitectura (llamada en clave Prescott, y comercialmente, los Pentium4 con la “e” al final en su modelo) se mostró lenta en comparación con los procesadores de AMD basados en la nueva microarquitectura de 64 bits, y con un consumo muy superior.

En 2003, Intel lanzó un nuevo procesador, basado en la arquitectura antigua (P6), el Pentium-M, destinado a ordenadores portátiles. Este nuevo procesador tenía un rendimiento inferior a los Pentium4 de la época, pero con un consumo varias veces inferior. Este procesador, integrado en la plataforma “Centrino” ha tenido un éxito comercial abrumador, y este éxito ha sido en gran parte la causa de la gestación de la nueva microarquitectura.

En 2004, Intel estaba en pleno desarrollo de los siguientes procesadores basados en Netburst, con nombre en clave Tejas. A mediados de ese año, Intel sorprendió a todos los medios anunciando que dicha arquitectura se cancelaba totalmente, y que se iba a iniciar un nuevo proyecto, totalmente distinto, para desarrollar una arquitectura que fuera más eficiente energéticamente. Los frutos de ese nuevo desarrollo los vemos ahora, en la forma de la arquitectura Core, y de los procesadores llamados en clave Merom (micro para portátiles), Conroe (micro para ordenadores de sobremesa), y Woodcrest (micro para estaciones de trabajo, y servidores).

Desde el punto de vista del usuario final, la arquitectura Core pretende conseguir más velocidad que cualquier arquitectura x86 desarrollada hasta ahora por Intel, con un consumo mucho más bajo que la actual arquitectura Netburst, y competitivo con los actuales diseños para Centrino en sus versiones para portátiles.

Desde el punto de vista arquitectónico, la forma de conseguirlo se puede resumir en el uso de la técnica de superescalaridad de forma muy extensiva, en vez de la segmentación, y en la continuación en el uso de técnicas avanzadas muy conocidas como la ejecución fuera de orden, y la ejecución especulativa, unidas a nuevas técnicas como la eliminación de la ambiguedad en los accesos a memoria, o un nuevo modelo de memorias caché para los núcleos.

En los siguientes apartados, vamos a adentrarnos en el interior de la microarquitectura Core, y veremos las distintas mejoras que permiten obtener un rendimiento muy superior, tanto a Netburst/Pentium4/PentiumD, como a Yonah/CoreDuo, con un consumo muy razonable, y que la hace perfectamente apta para su uso en toda la gama de ordenadores de Apple.

Cauce de segmentación

Como hemos mencionado ya, esta nueva arquitectura no busca frecuencias estratosféricas como Netburst. Por ello, el cauce principal está mucho menos segmentado que el del Pentium4. En concreto, existen 14 etapas de segmentación, muchas menos que en el Pentium4 Prescott, que tiene 31 etapas.

A pesar de ello, la frecuencia de reloj no ha disminuido tanto, teniendo en cuenta que se anuncian modelos estándar de Conroe a 2,67 GHz, y un modelo especial a 3 GHz. De igual forma, Woodcrest parece que saldrá a 3 GHz. Los Pentium4 más rápidos actualmente llegan a los 3,8 GHz.

Esto no es un gran acierto de Conroe, sino más bien un fallo del Pentium4. El núcleo actual del Pentium4 estaba diseñado para alcanzar frecuencias superiores a los 5 GHz. No las ha alcanzado finalmente, debido a los grandes problemas de consumo que se ha encontrado Intel con los procesos de fabricación de 90 nm y de 65 nm. Por ello, el núcleo del Pentium4, diseñado para ir óptimamente a 5 GHz, finalmente se ha quedado en 3,8, y eso merma considerablemente su rendimiento real.

CoreDuo, según estimaciones, parece tener un cauce de 12 etapas, y llega actualmente a los 2,16 GHz (con un modelo a 2,3 GHz antes del verano). Puede verse por tanto que la arquitectura Core está segmentada un poquito más, lo justo para alcanzar frecuencias de reloj razonables, sin perder rendimiento por esa segmentación adicional.

La arquitectura por partes

Vamos a continuación a analizar cada una de las partes fundamentales de la arquitectura. Primero, sin embargo, veamos el diseño general:
core.png

Núcleo Core completo (pinchar para ver en grande)

He mantenido el código de colores usado en el diagrama del microprocesador superescalar anterior, para que se puedan identificar las funciones que cumplen (más o menos) cada una de las partes del diseño.

La fase de lectura y descodificación de instrucciones

Esta fase inicial consiste en la lectura de instrucciones, y su descodificación y transformación en microinstrucciones, más sencillas, que se ejecutan en la parte del núcleo pseudo-RISC. Esta última parte (la descodificación y transformación en microinstrucciones) se hace porque muchas instrucciones x86 no son nada sencillas de ejecutar en un microprocesador segmentado moderno (x86 es una arquitectura CISC muy antigua, diseñada cuando todavía no se pensaba que la segmentación sería una técnica realmente útil). Por tanto, lo que se hace es dividir esas instrucciones complejas en varias instrucciones sencillas, que sí son fácilmente ejecutables en un microprocesador segmentado y superescalar convencional, y que se suelen denominar microinstrucciones (Intel las llama uops).

La arquitectura P6 tenía un mecanismo sencillo de descodificación, que consistía en el uso de un descodificador complejo, y dos descodificadores simples. El descodificacodor complejo es capaz de descodificar cualquier instrucción x86 que se transforme en 4 o menos microinstrucciones, y los descodificadores simples son capaces de descodificar cualquier instrucción que produzca una sola microinstrucción. Por tanto, en P6, como máximo, se pueden producir hasta 6 microinstrucciones por ciclo (si el código está bien ordenado, de forma que caigan las instrucciones “adecuadas” en la posición adecuada), a partir de 3 instrucciones x86.

Netburst desechó todo este mecanismo de descodificación, para sustituirlo por uno muy novedoso, pero que al final se ha demostrado ineficaz: la caché de traza (o trace cache, en inglés).

La idea de esta caché es sencilla: a medida que se leen las instrucciones de la caché nivel 2, se descodifican en microinstrucciones, utilizando un descodificador segmentado especial, almacenándolas en esta forma en la caché nivel 1. Por tanto, la caché de nivel 1 del Pentium4 no almacena instrucciones x86, sino microinstrucciones de la arquitectura Netburst.

La gran ventaja que tiene esta aproximación es que, una vez descodificada una instrucción, como se mantiene en este estado en la caché de traza, no hay que volver a descodificarla si queremos volverla a ejecutar.

Las desventajas que tiene esta aproximación son dos: por una parte, la caché de traza puede descodificar por ciclo solamente una instrucción x86, mientras que P6 podía descodificar hasta tres instrucciones (tiene tres descodificadores). Por otra parte, esta caché consume muchísima energía, mucho más que la caché nivel 1 convencional.

Parece ser que esta última desventaja ha sido determinante para que este mecanismo se deseche finalmente, y la arquitectura Core vuelva al sistema anterior. Core utiliza un mecanismo similar a P6, con un descodificador complejo, y tres descodificadores simples. Los criterios a la hora de descodificar parecen ser iguales (el complejo puede descodificar las instrucciones de hasta 4 uops, y los simples, las de 1 uops), pero ahora hay un descodificador simple más.

descodificacion.png

Etapa de descodificación de la arquitectura Core

(Un comentario, para que nadie se me pierda: un “buffer” es simplemente una especie de “almacén” de cosas. Un buffer de instrucciones es simplemente un lugar donde se almacenan las instrucciones).

Además de lo comentado, Intel ha implementado dos funcionalidades adicionales para mejorar la ejecución de instrucciones, la fusión de microinstrucciones, y la fusión de "macroinstrucciones". La fusión de microinstrucciones consiste en "juntar" dos microinstrucciones (uops) que están relacionadas entre sí. La fusión de macroinstrucciones consiste en juntar dos instrucciones x86, y convertirlas en una sola instrucción que luego se corresponderá con una sola microinstrucción.

Estas dos técnicas sirven para mejorar la ejecución de las instrucciones que intervienen, haciéndola más rápida. La fusión de microoinstrucciones ya se utiliza con mucho éxito en CoreDuo, mientras que la fusión de macroinstrucciones es nueva de esta arquitectura.

Renombramiento, planificación, y ejecución fuera de orden

Esta diferencia de una uop más generada por ciclo puede parecer menor, pero hay otra diferencia muy importante con respecto a P6. El siguiente paso en P6 (y también en Core) es llevar las uops generadas a un bloque llamado el buffer de renombramiento. P6 puede llevar hasta 3 uops por ciclo, mientras que Core puede llevar hasta 4 uops por ciclo. Por tanto, Core puede llevar un 33 % más de instrucciones cada ciclo por el cauce. Esta diferencia veremos que se mantiene constante en el resto del diseño, y es crucial verlo para darnos cuenta de que Core pretende ser hasta un 33% más superescalar que P6 en un caso general (en realidad, puede ser más superescalar todavía en algunos casos especiales, como luego veremos).

planificacion.png

Etapa de renombrado, reordenamiento, y planificación

Después de descodificar, las microinstrucciones se llevan a un buffer de renombrado. Esto se hace por dos razones: por una parte, la arquitectura x86 tiene muy poquitos registros de propósito general (un registro de propósito general es una memoria muy pequeñita, donde sólo cabe un dato, y que se utiliza como operando para las operaciones que se realizan en las instrucciones). Por otra parte, a medida que queremos diseñar microprocesadores más superescalares, surge el problema de que las instrucciones que se envían a ejecutar simultáneamente pueden no terminar a la vez. Si esto sucede, es necesario garantizar que los datos obtenidos al finalizar todas las instrucciones son exactamente iguales que si hubiéramos ejecutado las instrucciones de una en una (que es lo que en realidad supone el programador cuando programa).

Estos dos problemas se pueden resolver implementando en el microprocesador registros “invisibles”, que el programador no conoce, pero que la arquitectura se encarga de reasignar a cada instrucción para que nunca falten los registros que se necesitan realmente, y para que las operaciones de escritura sobre los registros “de verdad” se produzcan en el orden correcto. El mecanismo más usual para implementar esta funcionalidad es el buffer de renombrado.

Después de estar en el buffer de renombramiento, las microinstrucciones se llevan a un buffer de reorden. Este buffer se encargará guardar información de cada instrucción, con el propósito de que las instrucciones, una vez ejecutadas, se completen en el orden de programa. Esta funcionalidad es necesaria si queremos diseñar un microprocesador fuera de orden: aunque las instrucciones se ejecuten en orden distinto al de programa, su finalización (que generalmente se suele corresponder con la escritura de los datos de resultado obtenidos en los registros, o en la memoria) se tiene que realizar en orden, para garantizar que los resultados obtenidos son los que el programador esperaba (por ejemplo, no es lo mismo hacer A=3+5 y luego A=2+2, que hacerlo al revés, porque en el primer caso A=4, y en el segundo, A=8, ya que el valor de A depende de la última instrucción ejecutada).

Finalmente, las instrucciones se llevan a las estaciones de reserva, donde esperan su turno para ser llevadas a las unidades de ejecución.

Los mecanismos utilizados en esta parte son muy parecidos a los que utiliza Yonah/Coreduo, y la arquitectura P6 en general. Lo único que cambia es el tamaño: todos los buffers tienen más capacidad en Core que en P6, por lo que se puede llevar “la cuenta” de más instrucciones cada vez. Además, hay una diferencia clave: P6 sólo puede llevar las uops de 3 en 3, y Core puede llevarlas de 4 en 4.

Fase de ejecución

En la fase de ejecución, las instrucciones esperan en las estaciones de reserva para que se les asigne una unidad de ejecución que esté libre, para poder ser ejecutadas.

ejecucion.png

Fase de ejecución y de acceso a memoria de la arquitectura Core

Existen 6 “puertos de envío” diferentes. De las estaciones de reserva, pueden salir hasta 4 uops por ciclo, cada una de ellas a un puerto distinto. Varios de los puertos de envío (los relacionados con las instrucciones aritmético-lógicas, ya sea en enteros, o en coma flotante), contienen la lógica necesaria para ejecutar varios tipos de instrucciones distintas. En los bloques, ALU indica “unidad aritmético lógica”, y en este caso indica unidad de cálculo de instrucciones de enteros (o instrucciones lógicas), SSE indica bloque de ejecuciones SSE (incidiremos en ellas luego), FADD indica suma en coma flotante, FMUL multiplicación en coma flotante, y FDIV división en coma flotante.

Esta fase, la fase de ejecución, es la que cambia totalmente con respecto a P6 y CoreDuo. CoreDuo sólo puede ejecutar hasta 3 uops por ciclo, y Core puede ejecutar 4. P6 sólo tiene dos puertos de envío para instrucciones aritmético-lógicas, mientras que Core tiene 3, y en los tres, se puede enviar una instrucción SSE de 128 bits (aunque sólo se pueden enviar a dos puertos instrucciones SSE a la vez), mientras que si se envía una instrucción SSE en CoreDuo, quedan bloqueadas los dos puertos aritmético-lógicos.

En Core, hay unidades funcionales de enteros en los tres puertos aritmético-lógicos, por lo que se pueden enviar hasta tres uops de enteros por ciclo.

Parece que las diferencias aquí son muy importantes, ¿verdad? Pues en realidad, son todavía más grandes de lo que parece.

Hace unos años, Intel extendió el conjunto de instrucciones x86 a partir del Pentium III incorporando unas nuevas instrucciones llamadas SSE (Streaming SIMD Extensions). Estas instrucciones tienen formato SIMD (Single Instruction, Multiple Data), y se corresponden en la arquitectura PowerPC con las Altivec, o lo que Apple llama el Velocity Engine. Básicamente, son instrucciones aritméticas (para enteros, o coma flotante de precisión simple o doble), en las que se especifican “grupos de datos”, para manejar de forma independiente, de forma que permiten realizar una misma operación sobre varios datos a la vez.

Estas instrucciones son fundamentales en muchas aplicaciones que requieren un rendimiento muy serio, como codificación de audio o vídeo, filtros sobre imagen (Photoshop) o señales, o aplicaciones de 3D.

El conjunto de instrucciones SSE, a pesar de no ser tan potente como Altivec, en general se considera que está bien construido. Hasta ahora, el problema más importante que ha tenido es “la implementación”, es decir, los microprocesadores de Intel y AMD no han dedicado el suficiente número de transistores a garantizar que las instrucciones SSE se ejecuten de la forma más rápida posible.

Como ejemplo de esto, voy a explicar las restricciones a la ejecución de instrucciones SSE en CoreDuo. En CoreDuo, sólo se puede enviar una instrucción SSE a ejecutarse en un ciclo determinado. Esto ya de por sí es malo, pero el problema más grande es que no se pueden enviar dos instrucciones SSE seguidas, en dos ciclos sucesivos. Por tanto, como mucho, CoreDuo puede completar una instrucción SSE cada dos ciclos. Si se reordena el código, de forma que no haya dos sumas seguidas, o dos multiplicaciones seguidas, puede conseguirse enviar cada ciclo, una instrucción (una suma, o una multiplicación).

La arquitectura Core cambia en este sentido. Para empezar, los tres puertos aritmético-lógicos tienen módulo SSE. Pero lo importante no es esto, lo importante es que las unidades SSE ahora realizan los cálculos de forma paralela sobre todos los operandos, de forma que no se dividen, y se ejecutan "de golpe". Eso significa que en cada ciclo, se pueden enviar una suma y una multiplicación, logrando ejecutar dos instrucciones por ciclo, de forma sostenida. En otras palabras, la capacidad de ejecución de instrucciones SSE se ha duplicado, de forma que Core se coloca sin problemas a la altura del G5 en ejecución de código vectorial y de coma flotante (el G5 tiene unidades escalares y vectoriales independientes, pero la cantidad de programas que utilizan la coma flotante escalar y vectorial a la vez es muy reducida).

Además, queda un tercer puerto en el que se pueden enviar, a la vez, una microinstrucción más, y por supuesto, puede enviarse una instrucción de acceso a la memoria a la vez (o también puede elegirse enviar dos instrucciones de acceso a memoria en el mismo ciclo).

Además de todo esto, los puertos de envío en la arquitectura Core están muy bien balanceados, y es poco probable que no podamos enviar dos instrucciones a ejecutar porque pretendan utilizar el mismo puerto.

En resumen, el cambio central de la nueva arquitectura se encuentra aquí, en la fase de ejecución. Core es una arquitectura mucho más “ancha”, tanto que CoreDuo, como que el Pentium4, y por ello puede ejecutar muchas más instrucciones cada ciclo. Los recursos para computación vectorial han aumentado enormemente, y esto es algo extremadamente positivo para la mayoría de usuarios de Mac, puesto que las aplicaciones que se suelen utilizar en el mundo Mac (particularmente, las de Apple) suelen hacer uso extensivo de Altivec, y ahora, al utilizar SSE, podrán funcionar a pleno rendimiento, aprovechando el resto de características (excepcionales, en mi opinión) de los micros basados en Core.

El subsistema de memoria

También ha habido bastantes cambios en el subsistema de memoria, tanto desde el punto de vista “interno”, como desde el punto de vista “externo”.

Sabemos que Core es una arquitectura diseñada para funcionar desde el principio en modo doble-núcleo, de forma que en un mismo chip se incorporan dos núcleos de ejecución. Anteriores diseños basados en el PentiumD incorporaban cachés separadas, y el diseño era muy poco elegante, ya que el tráfico de mantenimiento de coherencia de cachés tenía que pasar por el bus frontal, haciéndose enormemente lento.

CoreDuo mejoró de forma muy significativa en este sentido, ya que la caché nivel 2 que incorpora está compartida por los dos núcleos, con lo que el mecanismo para garantizar la coherencia de los datos es muy simple, y a la vez muy rápido.

La arquitectura Core mejora todavía más, incorporando la caché de nivel 2 compartida entre núcleos, pero añadiendo además un enlace directo entre las cachés nivel 1 de datos de los dos núcleos. Esto reducirá considerablemente el retardo necesario para comprobar que un dato de la caché es correcto.

Desde el punto de vista interno, por otro lado, Intel ha incorporado un mecanismo que denomina memory disambiguation, que podríamos traducir como “eliminación de la ambigüedad en las operaciones de acceso a la memoria”.

La idea, en realidad, es sencilla: un microprocesador superescalar puede estar ejecutando en un mismo ciclo muchas instrucciones de acceso a la memoria, algunas de lectura, y otras de escritura. Las de escritura, la mayoría de las veces, son inofensivas, pero las de lectura en general es necesario terminarlas lo más pronto posible, puesto que el dato a cargar pueden necesitarlo muchas instrucciones de otro tipo, y si tardamos mucho en obtenerlo, esas instrucciones permanecerán bloqueadas.

Por ello, para ganar tiempo, siempre se trata de adelantar, en lo posible, las instrucciones de lectura por delante de las de escritura. Hacer esto es muy delicado y complejo, puesto que si se adelanta una instrucción de lectura por delante de una de escritura, y la de escritura iba a escribir en la misma posición que pretendía leer la de lectura, el dato que habremos leído será erróneo, y por lo tanto la ejecución a partir de ahí también.

El mecanismo implementado por Intel permite realizar este proceso (adelantar instrucciones de memoria) de forma muy agresiva, implementando un predictor para saber cuándo lo podemos hacer, que tiene un índice de aciertos muy alto. Si falla, tendremos un bloqueo del cauce, y perderemos unos ciclos, pero si el índice de aciertos es alto (y parece que lo es) ganaremos muchísimo tiempo, y un tiempo precioso, que incide de forma muy significativa en el rendimiento general, puesto que gracias a ello podemos seguir ejecutando instrucciones de otros tipos distintos.

Conclusiones finales

Me he alargado demasiado en este artículo, así que a cambio las conclusiones serán muy cortas, porque además son sencillas de escribir.

Básicamente, todo se resume en esto: este microprocesador es una verdadera bestia. Intel ha aumentado absolutamente todo: los recursos para realizar la ejecución fuera de orden, los buffers de renombrado, las capacidades de lectura y descodificación de instrucciones, ha mejorado muy sustancialmente la ejecución de instrucciones de acceso a la memoria, y ha reorganizado totalmente el bloque de ejecución de instrucciones aritméticas, ampliándolo y mejorando el diseño, de forma que es realmente muchísimo más potente, en parte porque es más grande, pero también porque está mucho mejor pensado.

Core debería ser mucho mejor en enteros que CoreDuo, y además, debería vapulearlo en código vectorial. Además, el diseño de doble núcleo es muy elegante, y el rendimiento en código multihilo también debería ser muy bueno.

La arquitectura Core es mucho más superescalar que cualquiera de las anteriores arquitecturas x86 de Intel, y además, no ha disminuido demasiado la frecuencia de funcionamiento. Las penalizaciones por saltos errados serán mucho menores que en el Pentium4, las capacidades de ejecución son mucho mayores, y el núcleo parece estar diseñado de forma muy inteligente.

Lo único que me queda por hacer es empezar a contar los días para que salga un iMac con Conroe, porque ese será mi próximo ordenador 🙂

Antonio Moreno Pérez ("MarvinTM"), 2006.

Puedes comentar este artículo (y también (es gratis), llamar de todo al autor, MarvinTM, por haberse pasado tres pueblos con la extensión :-P), en los foros de Macuarium.

Fuentes

Por ahora, el mejor sitio para obtener información técnica sobre Conroe es este artículo de RealWorldTech (de hecho, es el único que he encontrado al respecto).

Nadie más ha sacado, a día de hoy, un artículo en profundidad sobre la arquitectura. Sin embargo, sí han salido un par de pruebas, de Anandtech, que han desatado una gran polémica, en parte por las circunstancias en que las pruebas se produjeron, y en parte porque Conroe gana por una distancia muy considerable al mejor micro de AMD de los próximos meses, y para algunas personas, AMD parece que no puede perder nunca 🙂

Actualización

29-06-06: Corregido pequeño error en la comparación en la ejecución de instrucciones SSE entre Core Duo y  Core.