Cola de entrada de captación previa - Prefetch input queue

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 solo se aplica a las computadoras von Neumann (es decir, no a las computadoras de la arquitectura Harvard ) que pueden ejecutar código que se modifica automáticamente y tienen algún tipo de canalización de instrucciones . Casi todas las computadoras modernas de alto rendimiento cumplen estos tres requisitos.

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. 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 para 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
  1. 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 de inmediato 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 que más de una máquina averiada sea reparada por un solo reparador. En este caso, el tiempo de servicio para cualquier usuario aumentará.

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 usa para precargar 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.

El procesador generalmente tiene dos unidades separadas para obtener las instrucciones y para ejecutarlas.

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.

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.

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 desde el punto de vista técnico. La complejidad del nivel de diseño de la CPU de dichos 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 operan 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, ahead
  mov word ptr cs:[bx], 9090h
ahead:
  jmp near to_the_end
  ; Some other code
to_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                  ; zero register bx
  xor ax, ax                  ; zero register ax

  mov dx, cs
  mov [code_segment], dx      ; "calculate" codeseg in the far jump below (edx here too)

around:
  cmp ax, 1                   ; check if ax has been altered
  je found_size
                              ; 0x90 = opcode "nop" (NO oPeration)
  mov byte [nop_field+bx], 0x90
  inc bx

  db 0xEA                     ; 0xEA = opcode "far jump"
  dw flush_queue              ; should be followed by offset (rm = "dw", pm = "dd")
code_segment:
  dw 0                        ; and then the code segment (calculated above)
flush_queue:
                              ; 0x40 = opcode "inc ax" (INCrease ax)
  mov byte [nop_field+bx], 0x40
nop_field:
  times 256 nop 
  jmp around
found_size:
  ;
  ;    register bx now contains the size of the PIQ
  ;    this code is for [[real mode]] and [[16-bit protected mode]], but it could easily be changed into
  ;    running for [[32-bit protected mode]] as well. just change the "dw" for
  ;    the offset to "dd". you need also change dx to edx at the top as
  ;    well. (dw and dx = 16 bit addressing, dd and edx = 32 bit addressing)
  ;

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

enlaces externos