Nivel de Microarquitectura 1.-El nivel de Microarquitectura: También llamada como organización de la computadora, es la manera que una arquitectura del conjunto de instrucciones (ISA) es implementada por el procesador. La arquitectura de la computadora es la combinación del diseño determinado de la microarquitectura y del conjunto de instrucciones La microarquitectura de una máquina se presenta generalmente como diagramas más o menos detallados que describen las interconexiones de los diferentes elementos microarquitectónicos de la máquina. Una microarquitectura describe, entre otros: el nombre de los segmentos y su tamaño, el nombre de las memorias caché y su asociabilidad respectiva, la existencia de un renombre de registros, de una unidad de ejecución fuera de orden, de una unidad de predictor de saltos. A diferencia del diseño arquitectónico, donde lo que se pretende es lograr un nivel de desempeño óptimo, el diseño microarquitectónico presta una atención más cercana a otras necesidades. Puesto que las decisiones de diseño microarquitectónico afectan directamente a lo que va dentro de un sistema, se debe prestar atención a cosas como: Área/coste del chip. Consumo de energía. Complejidad de la lógica. Facilidad de la conectividad. Facilidad de fabricación. Facilidad de la depuración. Facilidad de hacer pruebas. 1 Nivel de Microarquitectura 2 Un Ejemplo De Implementacion Después de especificar la microarquitectura y la macroarquitectura con detalle, el aspecto que nos falta es la implementación. Es decir ¿Qué aspecto tiene un programa que se ejecuta en la primera y que interpreta la segunda, y como funciona? Para poder contestar estas preguntas, debemos considerar con detenimiento la notación que usaremos para describir la implementación. 2.1 Microinstruccion y Notacion En principio, podríamos describir el almacén de control en binario, 36 bits por palabra. Sin embargo, al igual que en los lenguajes de programación convencionales, es muy provechoso introducir una notación que comunique la esencia de los aspectos que necesitamos tratar y al mismo tiempo oculte los detalles que carecen de importancia o que se manejan mejor automáticamente. Es importante darse cuenta aquí de que el lenguaje que hemos escogido pretende ilustrar los conceptos mas que facilitar diseños eficientes. Si esto ultimo fuera nuestra meta, usaríamos una notación muy diferente para maximizar la flexibilidad de la que dispone el diseñador. Nuestra notación especifica todas las actividades que ocurren en un solo ciclo de reloj en una sola línea. Es de decir el control ciclo por ciclo es muy importante por que ofrece la oportunidad de realizar varias operaciones de forma concurrente y es necesario poder analizar cada ciclo para entender y verificar las operaciones. Si la meta es una implementación rápida y eficiente, entonces cada ciclo cuenta. En una implementación real, el programa oculta muchos trucos sutiles, y se emplean secuencias u operaciones poco claras con objeto de ahorrar un solo ciclo. La recompensa por ahorrar ciclos es atractiva: si podemos reducir en dos ciclos una instrucción que tarda cuatro ciclos, se ejecutara en la mitad del tiempo, y esta aceleración ocurre cada vez que ejecutamos la instrucción. 2 Nivel de Microarquitectura Una estrategia simple seria hacer una lista de las señales que deben activarse en cada ciclo del reloj. Supongamos que en un ciclo queremos incrementar el valor de SP. También queremos iniciar una operación de lectura y queremos que la siguiente instrucción sea la que reside en la posición 122 del almacen de control. Podríamos escribir. ReadRegister=SP, ALU=INC, WSP,Read, NEXT_ADDRESS=122 WSP: escribir registro SP SP=SP+1; rd Llamaremos a nuestro microlenguaje ensamblador MAL (micro assembly language) MAL esta hecho a propósito para que refleje las características de la microarquitectura. Durante cada ciclo se puede escribir cualquiera de los registros, aunque normalmente solo se escribe uno. Solo se puede colocar el contenido de un registro en el lado B de la ALU. En el lado las opciones son +1 0 -1 y el registro H. Asi, podemos usar un sencillo enunciado de asignación, como en java, para indicar la operación de ejcutar. Por ejemplo, si querremos copiar algo de SP a MDR , podemos decir. MDR=SP Si queremos indicar el uso de las funciones de la ALU aparte de dejar pasar simplemente el contenido del bus B, podemos escribir , por ejemplo. MDR=H+SP Que suma el contenido del registro H a SP y escribe el resultado en MDR. El operador + es conmutativo , asi que el enunciado anterior también puede escribirse como. MDR= SP + H Y generar la misma microinstrucción de 36 bits, aunque en términos estrictos H deba ser el operando izquierdo de la ALU. Debemos tener cuidado de usar solo operaciones permitidas. Las operaciones mas importantes permitidas se muestran en la figura 4-16, donde SOURCE (origen) puede ser 3 Nivel de Microarquitectura cualquiera de MDR, PC, MBR, MBRU, SP, LV, CPP, TOS u OPC (MBRU se refiere a la versión sin signo de MBR). Todos estos registros pueden actuar como fuentes de la ALU en el bus B. de igual manera, DEST puede ser MAR, MDR, PC, SP, LV, CPP, TOS, OPC o H, los cuales son posibles destinos de la salida de la ALU en el bus C. este formato es engañoso porque muchos enunciados aparentemente razonables no están permitidos, por ejemplo. MDR= SP+MDR Parece perfectamente razonable, pero no es posible ejecutarlo en la trayectoria de datos de la figura 4-6 en un solo ciclo. Esta restricción se debe a que en una suma (fuera de incremento o decremento) uno de los operandos debe ser el registro H. de igual modo. H=H-MDR Podrá ser útil, pero también es imposible porque el único origen de un sustraendo es el registro H. corresponde al ensamblador rechazar enunciados que parezcan validos pero que en realidad están prohibidos. Extenderemos la notación para permitir multiples asignaciones empleando varios signos de igual. Ejemplo, si queremos incrementar SP y guardar el nuevo valor en SP y también en MDR, podemos escribir. SP=MDR=SP+1 Para indicar lecturas y escrituras de palabras de datos de 4 bytes en la memoria simplemente incluiremos rd (leer) y rw (escribir) en la microinstrucción. La obtención de un byte a través del puerto de un byte se indica fetch (buscar). Pueden ocurrir asignaciones y operaciones de memoria en el mismo ciclo. Esto se indica escribiéndolas en la misma línea. Para evitar confusiones, repetiremos que Mic-1 tiene dos formas de acceder a la memoria. Las lecturas y escrituras de palabras de datos de 4 bytes usan MAR/MDR y se indican en las microinstrucciones con rd y rw, respectivamente. Las lecturas de códigos de operación de un byte del flujo de instrucciones usan PC/MBR y se indican con fetch en las 4 Nivel de Microarquitectura microinstrucciones. Ambos tipos de operaciones de memoria pueden efectuarse simultáneamente. Sin embargo, el mismo registro no puede recibir un valor de la memoria y de la trayectoria de datos en el mismo ciclo. Considere el código. MAR=SP,rd MDR = H El efecto de la primera microinstrucción es asignar a MDR un valor de la memoria al final de la segunda microinstrucción, sin embargo la segunda microinstrucción también asigna un valor a MDR al mismo tiempo. Estas dos asignaciones están en conflicto y no se permiten porque el resultado no está definido. Recuerde que cada microinstrucción debe proporcionar explícitamente la dirección de la siguiente microinstrucción que se ejecutara. Para facilitar la tarea al micro programador, el ensamblador normalmente asigna una dirección a cada microinstrucción y llena el campo NEXT_ADDRESS de un modo que microinstrucciones escritas en líneas consecutivas se ejecuten una tras otra. Sin embargo, hay ocaciones en que el microinstrucción necesita efectuar un salto, sea incondicional o condicional. La notación para los saltos incondicionales es fácil: goto etiqueta y se puede incluir en cualquier microinstrucción para nombrar explícitamente a su sucesora. Por ejemplo, casi todas las secuencias de microinstrucciones terminan con un regreso a la primera instrucción del ciclo principal, de modo que la última instrucción de una secuencia de semejante por lo regular incluye: goto Main1 Cabe señalar que la trayectoria de datos está disponible para operaciones normales aun durante una microinstrucción que contiene un goto. Después de todo cada microinstrucción contiene un campo NEXT_ADDRESS. Lo único que goto hace es ordenar 5 Nivel de Microarquitectura al micro ensamblador que coloque ahí un valor especifico en lugar de la dirección donde el microensamblador decidio colocar la microinstrucción de la siguiente línea. Necesitamos una notación distinta para los saltos condicionales. Recuerde que JAMN y JAMZ usan los bits N y Z. a veces es necesario probar un registro para ver si es cero, por ejemplo. Una forma de hacerlo sería pasar el contenido del registro por la ALU y almacenarlo de vuelta en el mismo registro. El enunciado TOS=TOS Sin embargo, extenderemos MAL añadiendo dos registros imaginarios, N y Z a los cuales podemos hacer asignaciones. Por ejemplo Z=TOS Pasa el contenido de TOS por la ALU y establece los valores de flip-flops Z y N, pero no almacena un valor en un registro. La sintaxis para indicarle al microensamblador que establezca el bit JAMZ es: si (Z) goto L1; else goto L2 Normalmente, estos dos enunciados se combinan; por ejemplo. Z=TOS; if(Z) goto L1; else goto L2 El efecto de este enunciado es que MAL genera una microinstrucción en la que TOS se hace pasar por ALU para que su valor establezca el bit Z. poco después de que Z se ha cargado con el valor del bit de condición de la ALU, se hace OR con el bit de orden alto de MPC, lo que obliga a traer la dirección de la siguiente microinstrucción de L2 o bien de L1. MPC estará estable y listo para usarse en la obtención de la siguiente microinstrucción. Por ultimo, necesitamos una notación para usar el bit JMPC. La queremos es: goto(MBR OR valor) 6 Nivel de Microarquitectura esta sintaxis dice al microensamblador que use valor para NEXT_ADDRESS y ajuste el bit JMPC de modo que el resultado de MBR OR NEXT_ADDRESS se coloque en MPC. Si valor es 0, como sucede normalmente, basta con escribir. goto(MBR) 4.3.2 IMPLEMENTACION DE IJVM UTILIZANDO EL MIC-1 La figura 4-17 es el microprograma que se ejecuta en Mic-1 e interpreta IJVM. Es un programa sorprendentemente corto: 112 microinstrucciones en total. Se dan tres columnas para cada microinstrucción: el rotulo simbolico, el microcodigo real y un comentario. Al principio y al final de cada microinstrucción, TOS contiene el valor que esta en la posición de memoria a la SP apunta, la palabra que esta en el tope de la pila, tenerlo en un registro a menudo ahorra una referencia a memoria. El registro OPC es un registro temporal; no tiene un uso preasignado. Se usa, para guardar la dirección del código de operación de una operación de ramificación mientras PC se incrementa para acceder a parámetros. OPC también se usa como registro temporal en las instrucciones de ramificación condicional de IJVM. El microprograma de la figura 4-17 tiene un ciclo principal que busca, decodifica y ejecuta instrucciones del programa que se esta interpretando, en este caso, instrucciones IJVM. Su ciclo principal comienza en la línea rotulada Main1, con la invariante de que PC ya se cargo previamente con la dirección de una posición de memoria que contiene un código de operación. Además, ese código de operación ya se colocó en MBR. Cabe señalar que esto implica que cuando regresemos a este punto deberemos asegurarnos de que PC se haya actualizado de modo que apunte al siguiente código de operación a interpretar y que el byte del código de operación mismo ya se haya traído y se haya colocado en MBR. Esta sucesión de inicial de instrucciones se ejecuta al principio de cada instrucción, por lo que es importante que sea lo más corta posible. Gracias a un diseño muy cuidadoso del 7 Nivel de Microarquitectura hardware y software del Mic-1 hemos logrado reducir el ciclo principal a una sola microinstrucción. Ahora podemos revelar la verdadera razón por la que cada microinstrucción nombra explícitamente a su sucesora, en lugar de dejar que se ejecuten en sucesión. Todas las direcciones del almacén de control que corresponden a códigos de operación deben reservarse para la primera palabra del intérprete de la instrucción correspondiente. Para ver si funciona el intérprete, supongamos, por ejemplo, que MBR contiene el valor 0x60, es decir, el código de operación de IADD, en el ciclo principal, que abarca una sola microinstrucción, realizamos tres cosas: Incrementamos PC, de modo que ahora contiene la dirección del primer byte después del código de operación. Iniciamos la búsqueda del siguiente byte para colocarlo en MBR. Este byte se necesitara tarde o temprano, sea como operando para la instrucción IJVM en curso o como siguiente código de operación (como en el caso de la instrucción IADD(ver figura 4-11), que no tiene bytes de operandos). Realizar una ramificación multivias a la dirección contenida en MBR al principio de Main1. Esta dirección es igual al valor numérico del código de operación que se está ejecutando. La microinstrucción anterior la coloco ahí. El valor que se está obteniendo en esta microinstrucción no desempeña ningún papel en la ramificación multivias. La obtención del siguiente byte se inicia aquí para que esté disponible cuando inicie la tercera microinstrucción. Podrá necesitarse o no, pero se usara tarde o temprano, por lo que iniciar la obtención ahora en nada podría perjudicar. 8 Nivel de Microarquitectura 9 Nivel de Microarquitectura 10 Nivel de Microarquitectura 11 Nivel de Microarquitectura La microinstrucción BIPUSH es un poco más complicada porque el código de operación va seguido de un solo byte, como se muestra en la figura 4-18. El byte que debe interpretar como un entero con signo. Este byte, ya se obtuvo y se colocó en MBR en Main1. Se debe extender con signo a 32 bits y meter en el tope de la pila. Por tanto, esta secuencia debe extender a 32 bits el signo del byte que está en MBR y copiarlo en MDR. Por último, SP se incrementa y se copia en MAR, lo que permite escribir el operando en el tope de la pila. Además, este operando debe copiarse en TOS. Cabe señalar que, antes de regresar al programa principal, se debe incrementar PC para que el siguiente código de operación este disponible en Main1. 12 Nivel de Microarquitectura 3.-El Diseño del nivel de Microarquitectura. Las computadoras tienen muchas características deseables, como rapidez, bajo costo, confiabilidad, facilidad de uso, bajo consumo de energía y tamaño físico. Sin embargo el equilibrio que determina las decisiones más importantes que el diseñador de una CPU debe hacer es el de rapidez versus el costo: Existen varias formas de medir la rapidez, pero dada una tecnología de circuitos y una ISA (arquitectura del conjunto de instrucciones), hay tres estrategias básicas para aumentar la velocidad de ejecución: Reducir el número de ciclos de reloj necesarios para ejecutar Una instrucción. Simplificar la organización para que el ciclo de reloj pueda ser más corto. Traslapar la ejecución de instrucciones. La primera y la segunda serian las más obvias pero existen Múltiples actividades que afectan a los ciclos del reloj y a pesar de que usemos hardware especializados para una actividad igual este se verá afectado por otro lado como por ejemplo el tiempo de espera de los datos provenientes de la memoria. En cambio si aprovechamos la tercera técnica “traslapar la ejecución de instrucciones” que no es más que superponer las instrucciones o hacer que la unidad sea independiente de los circuitos que traen las instrucciones la velocidad ganada seria significativa. El costo es otro de los aspectos y este viene variando por la complejidad de los procesadores y tamaño, los chips más grandes y complejos son más caros que los pequeños y sencillos. Entre mayor sea el área que se requiere para las función es incluidas, mas grande será el chip. Y el costo de fabricación del chip crece con mucha más rapidez que su área por esta razón los diseñadores a menudo hablan del costo en términos del área requerida para un circuito. ¿Qué otra cosa podemos hacer para reducir la longitud de la trayectoria de ejecución? Una solución fácil es que la ALU tenga dos buses de entradas completos, un bus A y un bus B, para un total de tres buses, todos o casi todos los registros deberán tener acceso a ambos buses de entradas. Así se puede sumar dos registros en solo un ciclo y por lo tanto reduciremos la cantidad de ciclos en una instrucción. Mejoramiento del desempeño Todos los fabricantes de computadoras quieren que sus sistemas operen con la mayor rapidez posible y los usuarios también buscan lo mismo. Las ideas que plantearemos se pueden clasificar en dos categorías: mejoras en la implementación y mejoras en la arquitectura. Las mejoras en la implementación son formas de construir una nueva CPU o memoria para hacer que el sistema opere más rápidamente sin cambiar la arquitectura. Modificar la implementación sin alterar la arquitectura implica que los programas viejos podrán ejecutarse en la nueva máquina, lo cual es un atractivo que eleva las ventas. Algunos tipos de mejoras solo pueden lograrse modificando la arquitectura. 13 Nivel de Microarquitectura Aveces tales cambios son incrementales, como añadir nuevas instrucciones o registros, de modo que los programas viejos puedan seguir funcionando en los modelos nuevos, pero debería existir una re compilación en el software para provechar al máximo estas nuevas características. Mejora en la memoria cache: El considerable aumento en la velocidad de los procesadores a últimas fechas no ha sido acompañado de un aumento correspondiente en la velocidad de las memorias. En comparación con las CPU las memorias se han vuelto más lentas desde hace décadas. Dada a la enorme importancia de la memoria principal, esta situación a limitado severamente el desarrollo de sistemas de alto desempeño, y ha estimulado investigaciones sobre formas de resolver este problema de memorias, que son mucho más lentas que los CPU problema que empeora cada vez más al avanzar en términos de velocidad el CPU. Los procesadores modernos someten a los sistemas de memoria a demandas abrumadoras, tanto en términos de de latencia (lo que tarda en proporcionar un operando) como en ancho de banda (la cantidad de datos que se proporcionan por unidad de tiempo) lamentablemente estos dos aspectos de un sistema de memoria son en gran medida opuestos muchas técnicas para aumentar el ancho de banda lo logran únicamente aumentando la latencia. Una forma de atacar este problema es incluir caches, un cache contiene las palabras de memoria que se usaron más recientemente en una memoria pequeña y rápida, con lo que se agiliza el acceso a ellas. Si un porcentaje suficientemente grande de las palabras de memoria que se necesitan están en la cache la latencia de memoria efectiva se puede reducir enormemente. Una de las técnicas más eficaces para mejorar tanto el ancho de banda como la latencia se basa en el empleo de múltiples cachés. Una técnica fundamental que resulta muy eficaz es introducir cachés individuales para instrucciones y para datos, lo que se conoce como caché dividida. Esto tiene varias ventajas. Primero las operaciones de memoria se pueden iniciar de forma independiente en cada caché lo que duplica efectivamente el ancho de banda del sistema de memoria. Esta es la razón por la que conviene tener dos puertos de memorias distintos, cabe señalar que cada caché tiene acceso independientemente a la memoria principal.Las caches dependen de dos tipos de direcciones para lograr su objetivo.Localidad espacial es la observación de que es probable que en el futuro cercano se acceda a localidades de memorias con direcciones numéricamente similares auna localidad de memoria a la que se accedió recientemente. Las caches aprovechan esta propiedad trayendo más datos de lo que se solicitaron con la expectativa de anticipar solicitudes futuras. Ocurre localidad temporal cuando se vuelven a acceder a localidades de memorias a las que se accedió recientemente. Esto puede ocurrir por ejemplo, con localidades de memorias cercanas al tope de la pila, o instrucción dentro de un ciclo. La localidad temporal se aprovecha primordialmente en los diseños de caché al tomar la decisión de que debe desecharse cuando no se encuentra algo en ella (fallo de caché). Muchos algoritmos de remplazo de caché aprovechan la localidad temporal desechando las entradas a las que no se han accedido recientemente. Predicción de ramificaciones: 14 Nivel de Microarquitectura Predice el flujo del programa a través de varias ramificaciones, mediante un algoritmo de predicción de ramificaciones múltiples, el procesador puede anticipar los saltos en el flujo de las instrucciones. Éste predice dónde pueden encontrarse las siguientes instrucciones en la memoria con una increíble precisión del 90% o mayor. Esto es posible porque mientras el procesador está buscando y trayendo instrucciones, también busca las instrucciones que están más adelante en el programa. Esta técnica acelera el flujo de trabajo enviado al procesador. Ejecución fuera de orden y cambio de nombres de registros: Es un paradigma utilizado en la mayoría de los microprocesadores de alto rendimiento como forma de aprovechar los ciclos de instrucción que de otro modo serían desperdiciados produciéndose cierta demora de trabajo. Gran parte de los diseños modernos de CPU soportan la ejecución fuera de orden. Procesadores fuera de orden. Este nuevo paradigma rompe con lo anterior basándose en el siguiente orden: 1. Captura de la instrucción. 2. Envío de la instrucción a una cola (también llamada buffer o estación de reserva). 3. La instrucción espera en cola hasta que los operandos de entrada estén disponibles, de manera que una instrucción más reciente puede abandonar el buffer antes que otra anterior si ya tiene los datos disponibles. 4. La instrucción es enviada a la correspondiente unidad funcional, que la ejecuta. 5. Se envía el resultado a cola. 6. La instrucción en curso solamente puede escribir en el archivo de registros una vez que todas las anteriores a ella hayan escrito sus correspondientes resultados. La idea clave de la fuera de orden consiste es permitir al procesador evitar ciertos tipos de burbuja que suceden cuando la información necesaria para realizar una operación no está disponible. Siguiendo los pasos antes explicados, el procesador fuera de orden evita las burbujas comentadas en el paso 2 de la ejecución en orden cuando la instrucción no se puede completar a causa de la falta de datos. Los procesadores con ejecución fuera de orden rellenan esos "huecos" de tiempo con instrucciones que sí están listas para ejecutarse para después reordenar los resultados y aparentar que fueron procesadas de manera normal. La forma en que las instrucciones son ordenadas en el código original a ejecutar se conoce como orden de programa, mientras que el orden en que el procesador las maneja es el orden de datos, siendo aquel en que los datos van quedando disponibles para su captura desde los registros del procesador. Se necesita una circuitería bastante compleja para convertir un orden en otro y poder además mantener el orden lógico de la salida; el propio procesador ejecuta las instrucciones de forma aparentemente aleatoria. Los beneficios del procesamiento de ejecución fuera de orden crecen a medida 15 Nivel de Microarquitectura que se profundiza en la segmentación, así como con el crecimiento de la diferencia de velocidades entre la memoria principal(o memoria cache) y el procesador. En las máquinas modernas, el procesador funciona a velocidades mucho mayores que la memoria, de modo que mientras un procesador en orden pierde tiempo esperando por los datos, uno con ejecución fuera de orden ya habría procesado un gran número de instrucción. Ejecución especulativa: Es la ejecución de código por parte del procesador que no tiene por qué ser necesaria a prioridad. En la programación funcional, suele usarse el término "evaluación especulativa". La ejecución especulativa no es más que una optimización. Obviamente, sólo es útil cuando la ejecución previa requiere menos tiempo y espacio que el que requeriría la ejecución posterior, siendo este ahorro lo suficientemente importante como para compensar el esfuerzo gastado en caso de que el resultado de la operación nunca llegue a usarse. Ejemplo de nivel de micro arquitectura: Micro arquitectura Intel Nombre en Código Nehalem La micro arquitectura de nueva generación de Intel, que se demostró por primera vez con el procesador Intel® Core™ i7, representa el siguiente nivel de tecnología multi-core más rápida que maximiza con inteligencia el desempeño según sus necesidades de trabajo. La micro arquitectura Intel® nombre en código Nehalem,que se ha diseñado desde el principio para aprovechar las ventajas de lamicroarquitectur a Intel® Core™ Hi-k de 45nm de próxima generación, ofrece el desempeño para procesamiento paralelo mediante un controlador de memoria integrado y Intel® QuickPath Technology que brinda interconexiones de altavelocidad núcleo de procesamiento independiente. por cada El siguiente nivel del desempeño multi-core La microarquitectura Intel, nombre en código Nehalem, ofrece la máximainnovación procesadores y se distingue por lo siguiente: en •Escalabilidad dinámica, núcleos administrables, subprocesos, caché, interfaces y alimentación de energía para el desempeño ecológico a pedido. •Escalabilidad del diseño y desempeño, para servidores, estaciones de trabajos, laptops y PCs compatible con dos y más de ocho núcleos, y hastamás de 16 subprocesos medianteIntel® HyperThreading Technology (Intel® HT Technology), así como tamaños de caché escalables,interconexio nes del sistema y controladores de memoria integrados. •Desempeño inteligente a pedido, con Intel® Turbo Boost Technology que saca provecho de la energía y el margen térmico del procesador. Gracias a estas tecnologías se aumenta el desempeño para las cargas de trabajo que ejecutan uno o varios subprocesos. 16 Nivel de Microarquitectura •Mayor desempeño en las aplicaciones muy sofisticadas, mediante Intel HT Technology, que integra las aplicaciones de alto desempeño en la informática de uso general con 1 y más de 16 subprocesos optimizados para la arquitectura de procesadores multi-core de nueva generación. •Memoria compartida escalable, que se distribuye entre cada procesador con los controladores de memoria integrados y las interconexiones de punto a punto de alta velocidad de Intel Quick Path Technology a fin de dar rienda suelta al desempeño de las futuras versiones de los procesadores Intel®multi-core de próxima generación. •Caché compartida a multinivel que aumenta el desempeño y la eficacia al reducir la latencia de acceso a los datos más utilizados. 4 MEJORAMIENTO DEL DESEMPEÑO Cada cierto número de décadas los diseñadores se dan cuenta de que la vieja arquitectura ha dejado de ser útil y que la única forma de progresar es comenzar otra vez desde el principio. Comenzaremos con tres mejoras de la implementación bien establecidas y luego pasaremos a uno que necesita un poco de apoyo arquitectónico para trabajar óptimamente. Las técnicas en cuestión son Cache, predicción de ramas, ejecución no en orden con cambio de nombre de registros y ejecución especulativa. 4.1 MEMORIA CACHE. Los procesadores modernos someten a los sistemas de demandas abrumadoras, tanto en términos de latencia como ancho de banda. Lamentablemente estos dos aspectos de un sistema de memoria son en gran medida opuestos. Muchas técnicas para aumentar el ancho de banda lo logran únicamente aumentando la latencia. Una forma de atacar este problema es incluir caches. Una cache contiene las palabras de memoria que se usaron más recientemente en una memoria pequeña y rápida. Con lo que se agiliza el acceso a ellas. Si un porcentaje suficientemente grande de las palabras de memoria que se necesitan están en la cache, la latencia de emotiva efectiva se puede reducir menormente. Una de las técnicas más eficientes para mejorar tanto el ancho de banda como la latencia se basa en el empleo de múltiples caches. Una técnica fundamental que resulta muy eficaz es introducir caches. Una técnica fundamental que resulta muy eficaz es introducir caches individuales para instrucciones y para datos. Lo que se conoce como cache dividido. Hoy dia muchos sistemas de memoria son mas complicados, y una cache adicional, llamada cache de nivel 2. Podría residir entre las caches de datos e instrucciones y la memoria principal. De hecho, podría haber tres o más niveles de cache si se requiere sistemas de memoria más sofisticados. 17 Nivel de Microarquitectura 4.1.1 CACHES EN MAPEO DIRECTO Es el cache más sencillo, llamada cache con mapeo directo. Se muestra un ejemplo de caches con mapeo directo de un solo nivel. - El bit VALIDEZ indica si la entrada contiene i no datos válidos. Cuando el sistema se arranca (Inicia), todas las entradas se marcan como no válidas. - El campo ETIQUETA (tag) consiste en un valor único de 16 bits que identifica la línea de memoria de la cual provienen los datos. - El campo DATOS contiene una copia de los datos de la memoria. Este campo contiene una línea de cache de 32 bytes. 18 Nivel de Microarquitectura Para almacenar y recuperar datos de la cache. La dirección se divide en cuatro componentes, como se menciono. - El campo ETIQUETA corresponde a los bits Etiqueta almacenamiento en una entrada de caches- - El campo LÍNEA indica cual cache de entrada contiene los datos correspondientes, si están presentes. - El campo PALABRA indica a cual palabra se hace referencia dentro de la línea. - El campo BYTE generalmente no se usa, pero si solo se solicita un Byte indica cual byte dentro de la palabra se necesita. En el caso de una cache que solo proporciona palabras de 32 bits, este campo siempre es 0. 4.1.1.1 CACHES ASOCIATIVAS POR CONJUNTOS Muchas líneas de memoria distintas compiten por las mismas ranuras de caché. Si un programa que usa la cache de la figura anterior, usa muchas las palabras que están en las dirección 0 y 65.536, habrá conflictos constantes y cada refencia podrá expulsar a la otra cache. Una solución de este problema es permitir dos o mas líneas en cada entrada de cache. Una cache con n posibles entradas para cada dirección se denomina Cache asociativa por conjunto de n vías. En la siguiente figura se ilustra una cache asociativa de cuatro vias. 4.1.2 PREDICCIÓN DE RAMIFICACIONES Los programas no son secuencias líneas de código, están llenos ramificaciones. Considere los sencillos enunciados. de instrucciones de Si se puede correctamente una rama, no hay nada especial que hacer. La ejecución simplemente continua en la dirección objetivo. El problema surge cuando se predice erróneamente una rama. Hay dos formas de atacar el problema. La primera es permitir que las instrucciones que se adquieren después de una ramificación condicional predicha se ejecuten en tanto no traten de modificar el estado de la máquina. La segunda técnica es guardar el valor de cualquier registro que esté a punto de sobrescribir para que la maquina pueda revertirse al estado en que estaba cuando llego a rama predicha erróneamente. 4.1.3 EJECUCIÓN FUERA DE ORDEN Y CAMBIO DE NOMBRES DE REGISTROS En un intento por superar estos problemas y lograr un mejor desempeño, algunas CPU permiten saltarse por el momento las instrucciones dependientes para llegar a instrucciones futuras que no sean dependientes. Sobre decir que el algoritmo de planificación de instrucciones interno que 19 Nivel de Microarquitectura se deben producir el mismo efecto que se obtendrá si el programa se ejecutarán en el orden en que esta escrito. 4.1.4 EJECUCIÓN ESPECULATIVA La ejecución especulativa no es más que una optimización. Obviamente, sólo es útil cuando la ejecución previa requiere menos tiempo y espacio que el que requeriría la ejecución posterior, siendo este ahorro lo suficientemente importante como para compensar el esfuerzo gastado en caso de que el resultado de la operación nunca llegue a usarse. Los procesadores modernos que hacen uso de un pipeline usan la ejecución especulativa para, entre otras cosas, reducir el coste computacional de las instrucciones de salto condicional. Cuando el procesador se encuentra con una instrucción de salto condicional, el procesador intenta adivinar donde es más probable que se salte (a esto se le llama predicción de saltos) e inmediatamente comienza a ejecutar el código que empieza en ese área. Si a posteriorise demuestra que la predicción fue errónea, todo lo ejecutado después del salto se descarta. Esta ejecución prematura sale realmente rentable en términos de uso de recursos puesto que si no el pipeline se pararía hasta conocer cuál sería la próxima instrucción. Hay un tipo de ejecución 'vaga' que no realiza este tipo de predicciones. La incorporación de la ejecución especulativa en lenguajes de programación es un tema de investigación actualmente, probándose en diversas implementaciones de Haskell. Lasversiones recientes del GHC permiten un tipo de ejecución especulativa llamada "ejecución optimista". 20 Nivel de Microarquitectura 5.-Ejemplos Del Nivel De Microarquitectura 5.1.-LA MICROARQUITECTURA DE LA CPU PENTIUM II • El Pentium II representa el extremo superior de la familia de CPU de Intel. Maneja operandos y operaciones aritméticas de 32 bits y operaciones de punto flotante de 64 bits, además operandos y operaciones de 8 y 16 bits, lo cual es el legado de anteriores procesadores de la familia • El Pentium II puede direccionar hasta 64 bits de memoria y lee palabras de la memoria de grupos de 64 bits. • El paquete SEC del Pentium II consiste en dos circuitos integrados, la CPU que incluye las cache de nivel 1 divididos y los cache de nivel 2 unificado 5.1.1.-LAS UNIDADES DE PENTIUM II • Las unidades juntas actúan como una fila de procesamiento de alto nivel, estas tres unidades se comunican a través de una reserva de instrucciones 5.1.2.-LA UNIDAD DE BUSQUEDA / DECODIFICACION 21 Nivel de Microarquitectura • La unidad de búsqueda / decodificación usa filas de procesamiento intensivamente, con 7 etapas rotuladas IFUO a ROB las instrucciones ingresan en la fila de procesamiento en la etapa IFUO, donde se carga líneas de 32 byte enteras de la cache 1 5.1.3.-LAS UNIDADES DE DESPACHO/ EJECUCION • La unidad de despacho / ejecución planifica y ejecuta las micro operaciones, resolviendo dependencias y conflictos de recursos 5.1.4.-LAS UNIDADES DE RETIRO • La unidad de retiro se encarga de enviar los resultados al lugar apropiado 5.2.-LA MICROARQUITECTURA DE LA CPU UltraSPARC II • La serie UltraSPARC II es la implementación hecha por Sun de la arquitectura de SPARC versión 9, es una máquina de 64 bits y con registros de 64 bits, también puede manejar operadnos con 32 bits, ejecuta software para 32 bits sin modificaciones, análogo a la arquitectura de 32 bits de Pentium II con bus de memoria de 64 bits • Toda la serie de SPARC ha sido un diseño RISC desde que nació, casi todas las instrucciones tienen dos registros fuente y un registro de destino. Por lo que se presenta a la ejecución en filas de procesamiento en un ciclo, no hay necesidad de descomponer instrucciones CISC antiguas en microoperaciones RISC, como tiene que hacer Pentium II 5.2.1.-GENERALIDADES DE UltraSPARC II • Todos los componentes que se muestran están en el chip de la CPU excepto la cache de nivel 2. la cache I es totalmente asociativa de 16 KB de dos vías con una línea de 32 bytes, la media línea contiene exactamente cuatro instrucciones, las cuales pueden emitirse en un solo ciclo del reloj. La cache D es de 16 KB, con mapeo directo, escritura a través y sin asignación que también usa líneas de 32 bytes divididas en dos sublineas de 16 bytes 22 Nivel de Microarquitectura 5.3.-LA FILA DE PROCESAMIENTO DE PicoJava II • La PicoJava II tiene una fila de procesamiento de seis etapas. La primera etapa busca instrucciones de cache I de 8 en 8 bytes y las coloca en buffer de instrucciones cuya capacidad es de 16 bytes, la siguiente etapa decodifica las instrucciones y la pliega, lo que sale en la unidad decodificadora es secuencia de microoperaciones. PREGUNTAS 1. La microarquitectura es denominada también cómo? 2. La microarquitectura de la computadora es la combinación de? 3. Escriba el significado de las siguientes siglas, para implementar un en ejemplo en IJVM • CPP : 23 Nivel de Microarquitectura • LV : • SP : • PC : • TOS : • Rd: • Wr: • Fetch : 4. Cuál es la Función de IJVM? 5. Dado un circuito y una ISA(Arquitectura de conjunto de instrucciones) enumere las tres estrategias básicas para aumentar la velocidad de micro arquitectura? 6. Cuál es la estrategia que tomaron como base para el diseño de la arquitectura moderna? 7. Cómo funciona la memoria cache? 8. Para qué sirve la Cache? 9. En el Mic la unidad decodificadora establece una correspondencia entre el código de operación IJVM y el índice en ROM en el que están almacenadas las micro operaciones correspondientes. Podría parecer más sencillo omitir la etapa de decodificación y alimentar el código de operación IJVM directamente en la unidad de cola de espera. Esta podría usar el código de operación IJVM como índice para el ROM, igual que se hace en el MIC-1 ¿Qué defecto tiene el plan? 24