agosto 10, 2020

BitCuco

¡Hola Mundo!

Set de instrucciones del procesador Intel Pentium

El procesador Intel Pentium ha servido como base para otros procesadores, incluso multicore. Aprender de su arquitectura nos acerca al conocimiento de como funciona el procesador.
Tiempo de Lectura20 Minuto(s), 23 Segundo(s)
Anuncio / Advertisement

El 17 de mayo 1993 Intel lanzó al mercado el primer microprocesador Pentium (5ª generación). En el segundo semestre de 1993 se consiguieron vender 100.000 Pentium a un precio de 958 dólares cada uno.

El microprocesador Pentium sigue teniendo una arquitectura interna IA-32 de 32 bits, similar a la de sus predecesores 80386 y 80486. Además mantiene la compatibilidad binaria de software de manera que se ejecutan en los nuevos todo lo que se desarrolló a partir del 8088. Esta política comercial ha proporcionado a Intel su indiscutible éxito de ventas dejando atrás así a sus competidores más directos como Motorola.

El primer modelo de Pentium, el Pentium I fue construido con 3,1 millones de transistores (muchos más que el 8086 que poseía 29.000 transistores aproximadamente), fabricado con una tecnología BICMOS de 0,8 micras y funcionaba con una frecuencia de 60 MHz.

En la siguiente tabla podemos apreciar la evolución de las primeras versiones del Pentium:

Arquitectura Interna de Pentium

La arquitectura del procesador Pentium consta de los siguientes bloques:

*Unidad de enteros superescalar

*FPU: coprocesador matemático

*Subsistema de memoria caché

*Sistema de predicción de saltos condicionales

*BIU: unidad de interfaz con el bus

*Monitor de presentaciones

*Bus a ráfagas

*Redundancia funcional

Unidad de enteros superescalar

Primeramente, aclararemos el significado de la palabra superescalar. Este término hace referencia a que en su interior existe más de una unidad de ejecución dedicadas a realizar las mismas funciones. Así queda reflejado en la siguiente figura:

En este caso, existen dos cauces (U y V) que operan en paralelo para ejecutar las instrucciones de números enteros. Son independientes entre sí, ya que son capaces de funcionar uno independientemente del otro. Es como si existieran dos procesadores del tipo 80486 trabajando al mismo tiempo, por lo que el Pentium podría proporcionar dos resultados enteros por ciclo de reloj, es decir, ejecutamos dos instrucciones en cada ciclo de reloj. Cada unidad de enteros tiene un cauce segmentado de instrucciones de cinco etapas:

1.- Prebúsqueda de instrucciones

2.- Decodificación

3.- Cálculo de la dirección efectiva (búsqueda de operandos)

4.- Ejecución

5.- Escritura de los resultados

Estas etapas del cauce segmentado siguen el orden de la siguiente figura:

Cada unidad de proceso interno tiene su propia unidad aritmético lógica (ALU) con un circuito de generación de direcciones exclusivo y un interfaz específico con la memoria caché de datos. Los resultados de las operaciones se almacenan en la caché interna y no se transfieren a la memoria principal a no ser que sea necesario. Estas dos ALUs tienen características diferentes.

La ALU A que pertenece al cauce U es más simple que la del cauce V. El cauce U sólo ejecuta instrucciones simples y del núcleo RISC. Por otra parte la ALU B correspondiente al cauce V es más potente y utiliza instrucciones complejas de tipo CISC.

El bloqueo en la ejecución paralela de instrucciones se realiza de forma transparente para el software y el usuario, y también cuando existe dependencia entre los operandos de las instrucciones. Por ejemplo, si una instrucción realiza una operación que deja el resultado en el registro EDX, la siguiente si utiliza el registro EDX como uno de los operandos origen para cualquier otra operación.

El Pentium intenta paralizar al máximo la ejecución de instrucción, sólo si se garantiza la integridad de los datos, y es capaz de ejecutar alrededor de 1,3 instrucciones por cada ciclo de reloj, rompiendo por tanto la mítica barrera de conseguir la ejecución de la instrucción en cada ciclo de reloj.

Ahora pasaremos a explicar el funcionamiento de la segmentación. La unidad de prebúsqueda manda una dirección a la caché de instrucciones. Si la caché tiene dicha dirección manda una línea de información (32 bytes) a uno de los buffer de prebúsqueda que a su vez pasará la dirección en cuestión a la unidad decodificadora donde decodificará la información. Inicialmente las instrucciones son decodificadas para ver si pueden ser ejecutadas a la vez. En caso afirmativo, una instrucción irá al cauce U y otra al V para realizar simultáneamente, ya que no existen dependencias entre ellas. En caso contrario, es decir, que existen dependencias entre ellas, la primera deberá completar su ejecución antes de que comience la segunda.

Cuando se predice un salto, la dirección de esta instrucción es demandada por la caché de instrucciones. Si se encuentra allí, una línea de código se manda al otro buffer de prebúsqueda de tal manera que se impide cualquier retraso cuando la instrucción branch se ejecute. Si no hay instrucciones de este tipo ambos cauces son tratados conjuntamente, realizando las prebúsquedas linealmente.

Con esta arquitectura se pueden introducir y obtener dos instrucciones en cada etapa del cauce (ver figura anterior). A esto en inglés se le denomina “pairing” o emparejamiento. Durante el primer ciclo de reloj un par de instrucciones realizan la prebúsqueda; en el segundo ciclo de reloj las dos instrucciones se tratan en paralelo, una en el cauce U y otra en el cauce V , claro está, sino existen dependencias entre ambas instrucciones. En un tercer ciclo de reloj se decodificarán para q en el último se ejecuten. Por todo ello se deduce que el máximo número de instrucciones que puede ejecutar el Pentium son dos.

Por ejemplo, la instrucción FADD ST, ST(2), la instrucción MOV EAX,10H y la instrucción MMOV EBX,12H pueden ejecutarse al mismo tiempo, ya que ninguna de tales instrucciones depende de las otras. El coprocesador ejecuta la instrucción FADD ST,ST(2) la canalización U ejecuta la instrucción MOV EAX,10H y la canalización V ejecuta la instrucción MMOV EBX,12H. Como la unidad de punto flotante tambien se utiliza para las instrucciones MMX (si están disponibles), el Pentium puede ejecutar dos instrucciones con enteros y una instrucción MMX de manera simultánea.

Anuncio / Advertisement

Se debe escribir software para aprovechar estas características mediante un análisis de las instrucciones en un programa y luego mediante su modificación, cuando se descubran casos en los que instrucciones dependientes puedan separarse mediante instrucciones no dependientes. Estas modificaciones llegan a producir un aumento de hasta el 40% de la velocidad de ejecución en cierto software. Como programador se debe estar seguro de que cualquier compilador u otro paquete de aplicación está aprovechando la característica superescalar del Pentium.

FPU: coprocesador matemático

El coprocesador matemático o también llamado unidad de punto flotante, es un microprocesador utilizado para realizar operaciones de punto flotante (por esa razón se llama también unidad FPU o Floating-Point Unit) y cálculos matemáticos. Inicialmente dentro de los procesadores x86 de la familia Intel era una parte complementaria o bien no formaba parte del procesador principal, como por ejemplo dentro de los procesadores 8088, 8086, 80386, 80486; sin embargo al aparecer el procesador Pentium, éste ya venía ensamblado al procesador en “una sola pieza”.

La FPU es un coprocesador que opera con unidades enteras de otros procesadores, de los cuales coge sus instrucciones desde el mismo decodificador y secuenciador que la unidad de enteros, compartiendo con esta última el bus del sistema. Cabe destacar que la unidad de enteros y la FPU operan independientemente y en paralelo y que éste bloque se ha rediseñado totalmente respecto al que se utilizaba en el 80486. Sin embargo sigue siendo compatible 100%. Utiliza nuevos algoritmos que aceleran la ejecución de las operaciones (hasta tres veces más rápido que con el 80486) e incluye elementos de hardware dedicados (un multiplicador, un sumador y un divisor).

La FPU consta de un cauce segmentado de instrucciones de 8 etapas que permite obtener resultados partiendo de instrucciones de coma flotante en cada ciclo de reloj. Las etapas son las siguientes:

1º : Prebúsqueda de instrucciones

2º : Decodificación

3º : Cálculos de la dirección efectiva

4º : Ejecución

5º : Ejecución de las instrucciones de coma flotante

6º : Ejecución de las instrucciones de coma flotante

7º : Escritura de los resultados

8º : Informe de posibles errores

Para llevar a cabo estas instrucciones el coprocesador matemático internamente posee registros. Son 8 registros de datos y los siguientes registros especiales:

Registros de datos, que es donde se guardan los operandos y los resultados. Consta de 8 registros (de R0-R7) de 80 bits de longitud cada uno. Un bit es para el signo, 15 bits para el exponente y los 64 restantes para la mantisa.

  • Registros de estado, son registros de 16 bits que indican la situación actual de la FPU, los flags incluidos en estos registros son activados por la FPU para mostrar el resultado de sus operaciones.
  • Registros de control, estos registros controlan la precisión de la FPU y los métodos de redondeo usados.
  • Registros de palabra, tienen 16 bits y están divididos en campos de 2 bits cada uno (se le denomina tag). Así contendrá 8 tag cada uno del 0 al 7. Cada tag hace referencia a un registro de datos, numerados del R0 a R7.
  • Registro puntero de instrucciones, se trata de un registro de 48 bits que guarda la dirección RS (16 bits) y el desplazamiento (32 bits) de las direcciones virtuales de las últimas instrucciones que hemos usado.
  • Registro puntero al último operando, también denominado puntero dato, se trata de un registro de 48 bits que guarda la dirección RS (16 bits) y el desplazamiento (32 bits) de las direcciones virtuales de los últimos datos que hemos usado.
  • Registro de código, se trata de un registro que consta de 11 bits. La FPU almacena el código de las últimas instrucciones ejecutadas que no sean de control.

El coprocesador puede obtener y escribir datos en memoria de los siguientes tipos:

Entero: Words de 16 bits, Dword de 32 bits y Qwords de 64 bits.

Real: Words de 16 bits, Dword de 32 bits, Qwords de 64 bits y Twords de 80 bits.

Simple precisión en coma flotante.

Doble precisión en coma flotante.

Doble precisión expandida en coma flotante.

Entero con signo.

BCD.

Subsistema de memoria caché

CLASIFICACIÓN DE LAS MEMORIAS

Como podemos observar la memoria caché es muy rápida pero tiene poca capacidad además de ser costosa por eso no podemos sustituir la memoria principal DRAM (Dynamic Random Access Memory) lo que se hizo es interponer entre el CPU y la memoria principal una memoria cache de esta manera podemos hacer que el intercambio de datos sea más eficiente y veloz.

La caché en el Pentium se modificó, en comparación con la que se encuentra en el microprocesador 80486. El Pentium contiene dos memorias caché de 8 Kbytes, en lugar de una como en el 80486. Hay una caché de datos de 8 Kbytes y una caché de instrucciones de 8 Kbytes. La caché de instrucciones sólo almacena instrucciones, mientras que la caché de datos almacena los datos que utilizan las instrucciones. Este esquema acelera las prestaciones y la capacidad de transferencia del procesador.

Las dos memorias cachés son memorias asociativas  de dos vías que utilizan como unidad de información una línea que es de 32 Bytes; 8 dobles palabras es decir 8x2x16 bits = 256 bits = 32 Bytes, ya que el bus externo del Pentium es de 64 bits. De esta forma en un acceso de tipo ráfaga se puede llenar una línea completa de caché. Los buses independientes que abastecen a las cachés internas desde la unidad de bus externo son de 64 bits cada uno

Anuncio / Advertisement

Las etiquetas contienen los 20 bits de más peso de la dirección además de dos bits de código: el WP protege contraescritura y V predice si es línea valida o no.

Los datos asociados a la etiqueta tiene cada uno 32 bytes (= una línea), es decir, cada vez que la caché se actualiza se le introducen 32 bytes. Cada vía tiene 128 etiquetas. Cada vía guarda 128 x 32 bytes = 4 Kbytes de datos, luego la memoria la dividimos en 4 KB.

En el 80486 con su caché unificada, un programa que utilizaba datos en forma intensiva llenaba la caché con rapidez y dejaba muy poco espacio para las instrucciones. Lo anterior reducía la velocidad de ejecución del microprocesador 80486. En el Pentium, esto no llega  a ocurrir debido a la caché de instrucciones separada

La caché es una SRAM (Static Random Access Memory) que tiene un tamaño comprendido entre los 8 Kbytes y los 512 Kbytes

La memoria caché proporciona dos factores destacables:

  1. Factor velocidad
  2. Factor eficacia

El bus que parte de la caché de datos es de 64 bits, mientras que el que conecta la caché de instrucciones con los registros de pre búsqueda de instrucciones es de 256 bits.

Translation Lookaside Buffer (TLB) es una memoria caché administrada por la MMU, que contiene partes de la tabla de paginación, es decir, relaciones entre direcciones virtuales y reales. Posee un número fijo de entradas y se utiliza para obtener la traducción rápida de direcciones.

La caché de datos utiliza el protocolo MESI (Modified Exclusive Shared Invalid) para asegurar la consistencia de datos entre la memoria principal y los cachés de todos los procesadores que integren el sistema multiprocesador, es decir, puede haber varias cachés y puede darse que dos CPU´s estén empleando la misma posición de la memoria principal. Así dicha posición se encontrara en ambas cachés. Por este motivo, dicho protocolo asegura que se lea el dato que este mas actualizado. Por ello, cada línea de la caché puede tener cuatro estados diferentes:M (modificado, por lo que la línea no está actualizada en la memoria principal), E (exclusivo, si únicamente se encuentra en esa cache), S(simultaneo, si la línea estárepetida en varias cachés) e I (inválida, si su contenido no sirve).

Cuando se precisa almacenar instrucciones o datos en la caché correspondiente y está totalmente ocupada con valores válidos, se usa el algoritmo de sustitución de líneas LRU (Last Recently Used). Se remplazara la línea menos recientemente usada, es decir, la que hace más que no se usa.

Las cachés son de escritura obligada (Write Back), mientras que su antecesor 80486 era de escritura inmediata, es decir, se almacenaban en la caché y en la memoria principal al mismo tiempo. Que una caché sea de escritura obligada implica que los resultados de las operaciones no se transfieren a memoria principal sino que se quedan dentro de la cache hasta que sea preciso actualizarla, porque no queda otro remedio. Su principal ventaja por tanto es que nunca da fallo

Existen dos situaciones que obligan a actualizar la memoria principal

  • Cuando se va a eliminar una línea de la caché porque está llena y está no ha sido transferida a memoria principal.
  • Cuando algún otro procesador, intenta acceder a una posición de memoria principal cuyo dato está en la caché y ha sido modificado por la CPU. Por tanto, habrá que detener este acceso hasta que se actualice la memoria principal. Una vez actualizada, se prosigue con el acceso.

En el tipo de escritura obligada, al no existir transferencias de resultados a la memoria principal, las operaciones se terminan antes.

Por último, cabe destacar que dos cachés que integran el subsistema de memoria caché son de primer nivel (L1 aprox. 8ns de velocidad) y admiten una interconexión fácil con caches de segundo nivel (L2 aprox. 15ns de velocidad) con lo que se aumentan significativamente las prestaciones.

Sistema de predicción de saltos condicionales

Una de las razones que más influyen en el bajo rendimiento del procesador son los saltos condicionales, que obligatoriamente introducen tres burbujas en el cauce (tres ciclos del cauce sin nada) ya que no se sabe la siguiente instrucción a ejecutar por lo que hay que esperar a ver si se cumple la condición para saber cuál es dicha instrucción.

Los fabricantes intentan eliminar estas burbujas del cauce. Intel lo hace prediciéndolo en un solo ciclo.

Para ello utiliza dos elementos:

Software: Consiste en un potente algoritmo estadístico.

Hardware: (BTB) Buffer de destino de las bifurcaciones. (“Branch Target Buffer”). Es una caché ultrarrápida que tiene 256 posiciones donde se guardan los resultados de las 256 últimas instrucción de salto BRANCH (salto condicional).

Cuando una instrucción supone un salto la BTB recuerda dicha instrucción y la dirección de salto efectuada y predice, aplicando ciertos algoritmos en qué dirección se va a producir el salto la próxima vez que se ejecute. Hay una tasa de acierto del 90%. En este caso, si la predicción es correcta, la bifurcación se realizará en 0 ciclos de reloj, puesto ésta ya se realizó, y se siguieron buscando instrucciones en dicha dirección. Por otro lado, si la predicción falla (en un 10% de los casos) habrá una penalización de tiempo debido a que se han metido en el cauce tres instrucciones erróneas por lo que hay que deshacer todas las operaciones realizadas con dichas instrucciones.

En la siguiente figura se muestra como está conectada la BTB a la caché de instrucciones y al decodificador de las mismas, de tal forma que si la BTB acierta existe una recompensa de tiempo ya que no hay que recoger la instrucción siguiente de la caché.

Anuncio / Advertisement

BIU: unidad de interfaz con el bus

La BIU (“Bus Interface Unit”) es el bloque encargado de soportar todas las transferencias con el mundo exterior. Controla los ciclos del bus que acceden a la memoria y a las E/S. El BIU está conformado por las siguientes partes:

  • Monitor de presentaciones
  • Bus a ráfagas
  • Redundancia funcional

El Pentium tiene el mismo rango de direccionamiento que los 80386 y los 80486. Esto es debido a que también usa un bus de direcciones de 32 bits. Sin embargo, el bus de datos externo es de 64 bits, el doble que sus predecesores. El subsistema de memoria debe por tanto, estar organizado en ocho grupos de 8 bits cada uno, es decir, un total de 64 bits para adecuarse al bus del procesador.

Monitor de prestaciones

Desarrollar aplicaciones es cada vez más complejo y precisa de una cuidadosa realización para evitar que la mayor parte del tiempo se pierdan ciertas rutinas o selecciones del código que no son excesivamente importantes. Para facilitar el trabajo de los desarrolladores de software, el procesador Pentium incorpora un monitor de prestaciones y una unidad de depuración software.

El procesador posee un conjunto de contadores y unidades de rastreo y traza, que exploran y archivan todos los acontecimientos significativos del flujo de control. Es una herramienta hardware que la puede usar el programador para saber cómo funciona el programa. Se creó para facilitar el trabajo de los desarrolladores de software.

Estos contadores junto a las unidades de rastreo y traza, permiten conocer el estado del procesador, el tiempo que se emplea en la realización de operaciones y las instrucciones que se ejecutan. Desde el exterior del procesador, por medio del puerto serie, se puede interactuar con esta unidad.

A parte de todo esto, se puede obtener el número de ciclos que el procesador emplea en operaciones internas que de algún modo afecten a:

*La lectura y escritura de datos.

*La ausencia o presencia de datos o código en las memorias caché internas del Pentium.

*Las interrupciones.

*La utilización del bus.

También se puede saber cuánto tiempo tiene que esperar el procesador para conseguir el control del bus externo. Gracias a todo lo anterior, se consigue sistema más rápido debido a la fácil optimización del mismo.

La unidad de traza cuando se produce cierta condición de bifurcación o los saltos a subrutinas o si la ejecución se produce en determinada sección de código o que instrucción ha provocado una interrupción, etc. Por tanto, se pueden detectar los cuellos de botella, es decir, dónde el sistema se ralentiza o la aplicación pierde mucho tiempo inútilmente. Por ello, se optimiza consiguiendo mejores prestaciones y mejor tiempo de respuesta.

Bus a ráfagas

Es una circuitería de silicio que permite cargar 256 bits (32 Bytes que es igual a la línea de caché) en la caché de datos de una sola vez, es decir en un ciclo.

Como se acaba de comentar, el tipo de ciclo de bus de ráfaga puede cargar 256 bits de una sola vez. El bus externo de 64 bits es capaz de transferir datos entre la memoria y el procesador a una velocidad que puede llegar a ser de 528 MBytes por segundo. Esto significa que, por ejemplo, el contenido completo de un disco fijo de 100 MBytes pasaría por este bus en menos de un quinto de segundo. Esta velocidad de transferencia es superior en más de tres veces al ancho de banda del bus de un 80486 a 50 MHz.

Unidad de redundancia funcional

Es un recurso que emplea diferentes técnicas para la detección de errores tanto externa como internamente, para asegurar la integridad de los datos. Cada octeto del bus de datos, lleva asociado un bit de paridad lo que hace un total de 8 bits de paridad para todo el bus de datos. Los bits de paridad son comprobados por el procesador en cada lectura. A su vez el Pentium genera un bit de paridad por cada octeto de los 64 bits que componen cada escritura hacia el exterior, lo que hace un total de 8 bits de paridad. También el bus de direcciones añade un bit de paridad por octeto; de este modo hay 4 bits de paridad para las direcciones que se generan y comprueban en cada acceso de escritura o lectura respectivamente. Con todo ello, el procesador Pentium es capaz de detectar errores en el bus de direcciones y en el de datos. Por tanto, el Pentium, no sólo detecta que el dato leído o escrito es correcto sino que también es capaz de saber si la dirección de memoria es correcta.

Internamente, también se hacen controles de paridad en la caché interna, en los registros internos y en la memoria ROM que almacena el microcódigo. Hay otro tipo de recursos que aseguran la fiabilidad del procesador. Siempre después de una inicialización se realiza un autodiagnóstico interno que comprueba que al menos un 70% de los dispositivos internos funcionan adecuadamente.

El Pentium implementa un sistema de redundancia funcional de una forma muy sencilla. Basta con poner dos procesadores Pentium en el mismo bus, uno trabajando en modo maestro y otro como comprobador. Los dos procesadores ejecutan las mismas instrucciones en el mismo tiempo. El que hace de comprobador chequea cada resultado obtenido por el maestro con el suyo propio. Si existe diferencia se produce una interrupción de máxima prioridad que detiene el sistema y avisa que los dos procesadores no están de acuerdo en los resultados de la ejecución del programa.

Anuncio / Advertisement

Nuevas Instrucciones

            Contiene una nueva instrucción que funciona con el software del sistema normal; el resto, sirven para controlar el modo de administración de memoria y las instrucciones de serialización. Este conjunto de nuevas instrucciones son:

CMPXCHG8B (compara y cambia ocho bytes):

Compara el valor (64 bits) almacenado en EDX y EAX con el contenido de una posición de memoria o de un par de registros. Sin son iguales… El valor en memoria se reemplaza por el contenido de ECX y EBX; si no, el valor en memoria se carga en EDX y EAX.

CPUID (Regresa al CPU a código de identificación):

Informa al software acerca del microprocesador. El valor cargado en EAX indica qué información debe retornar CPUID. Si EAX = 0… Se carga en EAX un valor igual a 1; entonces, aparece la identificación (“GenuineIntel”) del fabricante, contenido en EBX, ECX y EDX.

RDTSC (Contador de lectura de estampa de tiempo):

            Lee el contenido del TSC y lo coloca en EDX:EAX; TSC, cuenta los ciclos de reloj del CPU desde el momento en que se reinicia el procesador.

RDMSR (Registro de lectura de modelo específico) y

WRMSR (Registro de escritura de modelo específico):

Son registros únicos para el Pentium y se utilizan para rastrear, comprobar el rendimiento, evaluar y comprobar errores del equipo. Utilizan el registro ECX para llevar su número de registro (64 bits) al microprocesador y, EDX y EAX para la lectura o escritura. Nunca se debe utilizar un valor indefinido para ECX antes de las instrucciones RDMSR y WRMSR.

RSM (Interrupción del retorno del sistema administrador)

            El estado del microprocesador se restaura mediante una copia hecha a través del modo de manejo de memoria (SMM); los contenidos de los registros específicos no se afectan. Cuando sale del SMM, retorna el control a la aplicación o sistema operativo interrumpido.

Anuncio / Advertisement
1 0

Sobre el Autor

BitCuco

BitCuco. El Blog para los desarrolladores emergentes.