En la arquitectura de la computadora , un intervalo de retardo es un intervalo de instrucción que se ejecuta sin los efectos de una instrucción anterior. La forma más común es una única instrucción arbitraria ubicada inmediatamente después de una instrucción de bifurcación en una arquitectura RISC o DSP ; esta instrucción se ejecutará incluso si se toma la rama anterior. Por lo tanto, por diseño, las instrucciones parecen ejecutarse en un orden ilógico o incorrecto. Es típico que los ensambladores reordenen automáticamente las instrucciones por defecto, ocultando la incomodidad de los desarrolladores y compiladores de ensamblajes.
Ranuras de retardo de rama
Cuando se trata de una instrucción de bifurcación, la ubicación de la siguiente instrucción de intervalo de retardo en la tubería puede denominarse intervalo de retardo de bifurcación . Las ranuras de retardo de rama se encuentran principalmente en arquitecturas DSP y arquitecturas RISC más antiguas . MIPS , PA-RISC , ETRAX CRIS , SuperH y SPARC son arquitecturas RISC que tienen cada una una única ranura de retardo de rama; PowerPC , ARM , Alpha y RISC-V no tienen ninguno. Las arquitecturas DSP que tienen cada una una única ranura de retardo de bifurcación incluyen VS DSP , μPD77230 y TMS320C3x . El SHARC DSP y MIPS-X utilizan un hueco de retardo rama doble; dicho procesador ejecutará un par de instrucciones siguiendo una instrucción de bifurcación antes de que la bifurcación entre en vigor. El TMS320C4x utiliza una ranura de retardo de triple rama.
El siguiente ejemplo muestra ramas retrasadas en lenguaje ensamblador para SHARC DSP, incluido un par después de la instrucción RTS. Los registros R0 a R9 se borran a cero en orden por número (el registro borrado después de R6 es R7, no R9). Ninguna instrucción se ejecuta más de una vez.
R0 = 0; LLAMAR fn (DB); / * llamar a una función, debajo de la etiqueta "fn" * / R1 = 0; / * primer intervalo de retardo * / R2 = 0; / * segundo intervalo de retardo * / / ***** discontinuidad aquí (el CALL entra en vigor) ***** / R6 = 0; / * el CALL / RTS vuelve aquí, no en "R1 = 0" * / JUMP end (DB); R7 = 0; / * primer intervalo de retardo * / R8 = 0; / * segundo intervalo de retardo * / / ***** discontinuidad aquí (el JUMP entra en vigor) ***** / / * las siguientes 4 instrucciones se llaman desde arriba, como función "fn" * /fn: R3 = 0; RTS (DB); / * volver a la persona que llama, más allá de los espacios de demora de la persona que llama * / R4 = 0; / * primer intervalo de retardo * / R5 = 0; / * segundo intervalo de retardo * / / ***** discontinuidad aquí (el RTS entra en vigor) ***** /final: R9 = 0;
El objetivo de una arquitectura canalizada es completar una instrucción en cada ciclo de reloj. Para mantener esta tasa, la tubería debe estar llena de instrucciones en todo momento. La ranura de retardo de bifurcación es un efecto secundario de las arquitecturas canalizadas debido al peligro de la bifurcación , es decir, el hecho de que la bifurcación no se resolvería hasta que la instrucción haya pasado por la canalización. Un diseño simple insertaría paradas en la tubería después de una instrucción de bifurcación hasta que se calcule y cargue la nueva dirección de destino de la bifurcación en el contador del programa . Cada ciclo en el que se inserta un bloqueo se considera una ranura de retardo de rama. Un diseño más sofisticado ejecutaría instrucciones de programa que no dependen del resultado de la instrucción de bifurcación. Esta optimización se puede realizar en software en tiempo de compilación moviendo instrucciones a ranuras de retardo de rama en el flujo de instrucciones en memoria, si el hardware lo admite. Otro efecto secundario es que se necesita un manejo especial cuando se administran los puntos de interrupción en las instrucciones, así como al realizar la depuración dentro de la ranura de retardo de la rama.
El número ideal de ranuras de retardo de bifurcación en una implementación de tubería en particular está dictado por la cantidad de etapas de la tubería, la presencia de reenvío de registros , en qué etapa de la tubería se calculan las condiciones de la bifurcación, si se utiliza o no un búfer de destino de bifurcación (BTB) y muchos otros factores. Los requisitos de compatibilidad de software dictan que una arquitectura no puede cambiar el número de ranuras de retardo de una generación a la siguiente. Esto inevitablemente requiere que las implementaciones de hardware más nuevas contengan hardware adicional para garantizar que se siga el comportamiento de la arquitectura a pesar de que ya no sea relevante.
Ranura de retardo de carga
Una ranura de retardo de carga es una instrucción que se ejecuta inmediatamente después de una carga (de un registro de la memoria) pero no ve, y no necesita esperar, el resultado de la carga. Las ranuras de demora de carga son muy poco comunes porque las demoras de carga son altamente impredecibles en el hardware moderno. Una carga puede satisfacerse desde la RAM o desde un caché, y puede verse ralentizada por la contención de recursos. Se observaron retrasos en la carga en los primeros diseños de procesadores RISC. El MIPS I ISA (implementado en los microprocesadores R2000 y R3000 ) adolece de este problema.
El siguiente ejemplo es un código ensamblador MIPS I, que muestra tanto una ranura de retardo de carga como una ranura de retardo de bifurcación.
lw v0 , 4 ( v1 ) # cargar palabra desde la dirección v1 + 4 en v0 nop # ranura de retardo de carga desperdiciada jr v0 # saltar a la dirección especificada por v0 nop # ranura de retardo de bifurcación desperdiciada