Extraer la instrucción opcodes del programa de la memoria con suficiente antelación se conoce como la obtención previa y es servido mediante el uso de cola de entrada de captación previa (PAA) .El precargaron instrucciones se almacenan en la estructura de datos - es decir, una cola . La búsqueda de códigos de operación con mucha anticipación, antes de su necesidad de ejecución, aumenta la eficiencia general del procesador aumentando su velocidad. El procesador ya no tiene que esperar a que se completen las operaciones de acceso a la memoria para que se complete el código de operación de la instrucción subsiguiente. Esta arquitectura se utilizó de forma destacada en el microprocesador Intel 8086 .
Introducción
La canalización se puso a la vanguardia del diseño de arquitectura informática durante la década de 1960 debido a la necesidad de una informática más rápida y eficiente. La canalización es el concepto más amplio y la mayoría de los procesadores modernos cargan sus instrucciones algunos ciclos de reloj antes de ejecutarlas. Esto se logra cargando previamente el código de la máquina desde la memoria en una cola de entrada de captación previa .
Este comportamiento [ aclaración necesaria ] sólo se aplica a las computadoras von Neumann (es decir, no a las computadoras de la arquitectura Harvard ) que pueden ejecutar código auto modificable y tener algún tipo de canalización de instrucciones . Casi todas las computadoras modernas de alto rendimiento cumplen estos tres requisitos. [1]
Por lo general, el comportamiento de búsqueda previa del PIQ es invisible para el modelo de programación de la CPU. Sin embargo, hay algunas circunstancias en las que el comportamiento de PIQ es visible y el programador debe tenerlo en cuenta.
Cuando el procesador x86 cambia de modo de modo real a modo protegido y viceversa, el PIQ debe vaciarse o, de lo contrario, la CPU continuará traduciendo el código de máquina como si estuviera escrito en su último modo. Si el PIQ no se vacía, el procesador puede traducir sus códigos incorrectamente y generar una excepción de instrucción no válida .
Al ejecutar un código de modificación automática , un cambio en el código del procesador inmediatamente delante de la ubicación actual de ejecución podría no cambiar la forma en que el procesador interpreta el código, ya que ya está cargado en su PIQ. Simplemente ejecuta su copia anterior ya cargada en el PIQ en lugar de la versión nueva y alterada del código en su RAM y / o caché .
Este comportamiento del PIQ se puede utilizar para determinar si el código se está ejecutando dentro de un emulador o directamente en el hardware de una CPU real. [ cita requerida ] La mayoría de los emuladores probablemente nunca simularán este comportamiento. Si el tamaño de PIQ es cero (los cambios en el código siempre afectan el estado del procesador inmediatamente), se puede deducir que el código se está ejecutando en un emulador o el procesador invalida el PIQ al escribir en direcciones cargadas en el PIQ. .
Evaluación del desempeño basada en la teoría de las colas
Fue AK Erlang (1878-1929) quien concibió por primera vez una cola como solución a la congestión del tráfico telefónico. Se proponen diferentes modelos de colas para simular aproximadamente los sistemas de colas en tiempo real, de modo que puedan analizarse matemáticamente para diferentes especificaciones de rendimiento.
Los modelos de cola se pueden representar usando la notación de Kendall :
- A1 / A2 / A3 / A4
dónde:
- A1 es la distribución del tiempo entre dos llegadas
- A2 es la distribución del tiempo de servicio
- A3 es el número total de servidores
- A4 es la capacidad del sistema
- Modelo M / M / 1 (Single Queue Single Server / Markovian ): En este modelo, los elementos de la cola se sirven por orden de llegada. Dadas las tasas medias de llegada y servicio, las tasas reales varían alrededor de estos valores promedio de forma aleatoria y, por lo tanto, deben determinarse utilizando una función de distribución de probabilidad acumulada . [2]
- Modelo M / M / r : Este modelo es una generalización del modelo básico M / M / 1 donde varios servidores operan en paralelo. Este tipo de modelo también puede modelar escenarios con usuarios impacientes que abandonan la cola inmediatamente si no reciben el servicio. Esto también se puede modelar utilizando un proceso de Bernoulli que tiene solo dos estados, éxito y fracaso. El mejor ejemplo de este modelo son nuestros sistemas regulares de telefonía fija. [3]
- Modelo M / G / 1 ( modelo de entrada finita de Takacs): este modelo se utiliza para analizar casos avanzados. Aquí, la distribución del tiempo de servicio ya no es un proceso de Markov . Este modelo considera el caso de más de una máquina averiada reparada por un solo reparador. En este caso, el tiempo de servicio para cualquier usuario aumentará. [4]
Generalmente, en aplicaciones como la cola de entrada de captación previa, el modelo M / M / 1 se usa popularmente debido al uso limitado de las funciones de la cola. En este modelo de acuerdo con microprocesadores, el usuario asume el papel de la unidad de ejecución y el servidor es la unidad de interfaz del bus.
Cola de instrucciones
El procesador ejecuta un programa obteniendo las instrucciones de la memoria y ejecutándolas. Por lo general, la velocidad de ejecución del procesador es mucho más rápida que la velocidad de acceso a la memoria. La cola de instrucciones se utiliza para obtener las siguientes instrucciones en un búfer separado mientras el procesador está ejecutando la instrucción actual.
Con una canalización de cuatro etapas , la velocidad a la que se ejecutan las instrucciones puede ser hasta cuatro veces mayor que la de la ejecución secuencial. [5]
El procesador generalmente tiene dos unidades separadas para obtener las instrucciones y para ejecutarlas. [6] [7]
La implementación de una arquitectura de tubería solo es posible si la unidad de interfaz de bus y la unidad de ejecución son independientes. Mientras la unidad de ejecución está decodificando o ejecutando una instrucción que no requiere el uso de los buses de datos y direcciones , la unidad de interfaz de bus obtiene códigos de operación de instrucción de la memoria.
Este proceso es mucho más rápido que enviar una dirección, leer el código de operación y luego decodificarlo y ejecutarlo. Obtener la siguiente instrucción mientras se decodifica o ejecuta la instrucción actual se denomina canalización. [8]
La arquitectura 8086 tiene una canalización de instrucciones de captación previa de seis bytes, mientras que el 8088 tiene una captación previa de cuatro bytes. A medida que la unidad de ejecución ejecuta la instrucción actual, la unidad de interfaz de bus lee hasta seis (o cuatro) bytes de códigos de operación por adelantado de la memoria. Las longitudes de las colas se eligieron basándose en estudios de simulación. [9]
Se encuentra una excepción cuando la unidad de ejecución encuentra una instrucción de bifurcación , es decir, una instrucción de salto o de llamada. En este caso, se debe volcar toda la cola y el contenido al que apunta el puntero de instrucción debe recuperarse de la memoria.
Inconvenientes
Los procesadores que implementan el algoritmo de captación previa de la cola de instrucciones son bastante avanzados técnicamente. La complejidad del nivel de diseño de la CPU de estos procesadores es mucho mayor que la de los procesadores normales. Esto se debe principalmente a la necesidad de implementar dos unidades separadas, BIU y EU , que operen por separado.
A medida que aumenta la complejidad de estos chips, también aumenta el costo. Estos procesadores son relativamente más costosos que sus contrapartes sin la cola de entrada de captación previa.
Sin embargo, estas desventajas se compensan en gran medida con la mejora en el tiempo de ejecución del procesador. Después de la introducción de la cola de instrucciones de captación previa en el procesador 8086, todos los procesadores sucesivos han incorporado esta característica.
código de ejemplo x86
code_starts_here: mov bx , ah ead mov word ptr cs : [ bx ], 9090h forward : jmp near to_the_end ; Algún otro código para_the_end:
Este programa de modificación automática sobrescribirá el jmp to_the_end con dos NOP (que está codificado como 0x9090 ). El salto jmp cerca de to_the_end se ensambla en dos bytes de código de máquina, por lo que los dos NOP simplemente sobrescribirán este salto y nada más. (Es decir, el salto se reemplaza con un código de no hacer nada).
Debido a que el código de máquina del salto ya se lee en el PIQ, y probablemente también ya lo ejecuta el procesador (los procesadores superescalares ejecutan varias instrucciones a la vez, pero "fingen" que no lo hacen debido a la necesidad de compatibilidad con versiones anteriores ), el cambio de código no tendrá ningún cambio en el flujo de ejecución.
Programa de ejemplo para detectar el tamaño
Este es un ejemplo NASM - sintaxis auto-modificable x86 - algoritmo en lenguaje ensamblador que determina el tamaño del PIQ:
code_starts_here: xor bx , bx ; registro cero bx xor ax , ax ; eje de registro cero mov dx , cs mov [ segmento_código ], dx ; "calcular" codeseg en el salto lejano a continuación (edx aquí también)alrededor: cmp ax , 1 ; compruebe si el hacha ha sido alterada je found_size ; 0x90 = código de operación "nop" (sin operación) byte mov [ nop_field + bx ], 0x90 inc bx db 0xEA ; 0xEA = código de operación "salto lejano" dw flush_queue ; debe ir seguido de offset (rm = "dw", pm = "dd") code_segment: dw 0 ; y luego el segmento de código (calculado anteriormente) flush_queue: ; 0x40 = código de operación "inc hacha" (aumento ax) mov byte [ nop_field + bx ], 0x40 nop_field: veces 256 nop JMP alrededor found_size: ; ; el registro bx ahora contiene el tamaño del PIQ ; este código es para [[modo real]] y [[modo protegido de 16 bits]], pero podría cambiarse fácilmente a ; ejecutándose también para [[modo protegido de 32 bits]]. simplemente cambie el "dw" por ; el desplazamiento a "dd". también necesita cambiar dx a edx en la parte superior como ; bien. (dw y dx = direccionamiento de 16 bits, dd y edx = direccionamiento de 32 bits) ;
Lo que hace este código es básicamente que cambia el flujo de ejecución y determina por fuerza bruta qué tan grande es el PIQ. "¿A qué distancia tengo que cambiar el código que tengo delante para que me afecte?" Si está demasiado cerca (ya está en el PIQ) la actualización no tendrá ningún efecto. Si está lo suficientemente lejos, el cambio del código afectará al programa y el programa habrá encontrado el tamaño del PIQ del procesador. Si este código se está ejecutando en un sistema operativo multitarea, el cambio de contexto puede llevar a un valor incorrecto.
Referencias
- ^ "Centro de información de ARM" . Artículos de conocimiento de soporte técnico de ARM .
- ^ Hayes, John (1998). Arquitectura y organización de computadoras (Segunda ed.). McGraw-Hill.
- ^ Feller, William (1968). Introducción a la teoría de la probabilidad y sus aplicaciones (Segunda ed.). John Wiley e hijos.
- ^ Papoulis, Athanasios; S. Unnikrishna Pillai (2008). Probabilidad, variables aleatorias y procesos estocásticos (Cuarta ed.). McGraw-Hill. págs. 784 a 800.
- ^ Zaky, Safwat; V. Carl Hamacher; Zvonko G. Vranesic (1996). Organización informática (Cuarta ed.). McGraw-Hill. págs. 310–329 . ISBN 0-07-114309-2.
- ^ "Diagrama de bloques de la CPU 8086" .
- ^ Hall, Douglas (2006). Microprocesadores e Interfaces . Tata McGraw-Hill. pag. 2.12. ISBN 0-07-060167-4.
- ^ Hall, Douglas (2006). Microprocesadores e Interfaces . Nueva Delhi: Tata McGraw-Hill. págs. 2.13–2.14. ISBN 0-07-060167-4.
- ^ McKevitt, James; Bayliss, John (marzo de 1979). "Nuevas opciones de chips grandes". Espectro IEEE : 28–34.