El encadenamiento aumenta la velocidad de proceso, pero aún se puede
mejorar añadiendo técnicas como el supersescalado. Esta técnica permite
hacer paralelas las mismas etapas sobre instrucciones diferentes.
Un procesador superescalar puede ejecutar más de una instrucción a la vez.
Para ésto es necesario que existan varias unidades aritmético-lógicas, de
punto flotante y de control. El proceso que sigue el micro es transparente al
programa, aunque el compilador puede ayudar analizando el código y
generando un flujo de instrucciones optimizado. Veamos cómo se ejecutarían
las instrucciones en un procesador superescalar de que tiene duplicadas las
subunidades que lo componen:
Aunque esto mejora la velocidad global del sistema, los conflictos de datos
crecen. Si antes las instrucciones se encontraban muy próximas, ahora se
ejecutan simultaneamente. Esto hace necesario un chequeo dinámico para
detectar y resolver los posibles conflictos.
Ejemplo: El Pentium
El Pentium ofrece un juego de instrucciones CISC, pero internamente está
diseñado como un procesador RISC. Cada instrucción CISC del juego x86
antiguo se descompone en una o varias RISC. Este proceso de conversión
sólo ocupa el 3% del circuito que se dedica a microprogramas. El Pentium
tiene dos unidades de ejecución de enteros (U y V) y una de punto flotante.
Presenta encadenamiento (pipeline) de 5 etapas para los enteros y de 8
para los número de punto flotante. Para realizar una operación de punto
flotante, se aprovechan las 4 primera etapas de la primera unidad de enteros
y la unidad de punto flotante toma el control para las 4 últimas etapas.
Para saber si las instrucciones son paralelizable, el procesador sigue un
sencillo algoritmo. Para ejecutar las instrucciones I1 e I2:
IF I1 es simple
AND I2 también simple
AND I1 no es salto
AND destino de I1 no es fuente de I2
AND destino de I1 no es destino de I2
THEN
envía I1 a U
envía I2 a V
ELSE
envía I1 a U, para I2 ( será evaluada con I3)
Si se utiliza un compilador que conoce este modo de funcionamiento, mejora
hasta un 30% la velocidad.
Existen mejoras en las arquitecturas superescalares, que intentan reducir el
impacto de los conflictos de datos en el rendimiento. Veamos dos de ellas:
Out of order execution
O sea, ejecución desordenada. Supongamos un conflicto de datos entre las
instrucciones i y j consecutivas. El procesador retarda sólo j y las
instrucciones que dependen de ella, pero no otras instrucciones
independientes que vayan detrás de i. Esto implica mayor complejidad,
pero también mayor ancho de banda de ejecución. El Pentium Pro y el
HP8000 usan esta técnica.
También llamados Shadow Registers o Dynamic Register Renaming. Esta
técnica consiste en elminar las dependencias de orden o de salida teniendo
varios juegos de registros, uno por unidad de ejecución.
Hablemos ahora del rendimiento. Los procesadores superescalares, como
el Alpha 21264, el Sillicon Graphics MIPS/R10000, el PowerPC 604 y el
Pentium Pro ejecutan hasta 4 instrucciones simultáneas. Pero 1/CPI
(Instrucciones Por Ciclo, IPC) es menor de lo esperado en programas
reales, debido a conflictos que no se pueden soluccionar. El IPC ideal en
estos procesadores sería de 4, pero en la práctica sólo se alcanza entre
0,5 y 1,5. Estos valores disminuyen a medida que aumenta el número de
unidades replicadas. El coste es mucho mayor de lo esperado. Por ejemplo,
si analizamos el MIPS R5000, que es un procesador RISC simple, frente al
MIPS R10000 (out-of-order, ejecución especulativa) observamos que el
modelo R10000 ocupa 3,43 veces más área, pero sólo es 1,64 veces más
rápido (según el índice SPECint95).