1. Reenvío de datos (bypass):
* Mecanismo: Este es el método más común y eficiente. Si la instrucción en una etapa anterior necesita el resultado de una instrucción en una etapa posterior de la tubería, el resultado se reenvía directamente desde la etapa posterior hasta la etapa anterior, sin pasar por el acceso a la memoria.
* Ejemplo: Digamos que la instrucción I1 escribe para registrar R1, y la instrucción I2 dice de R1. El reenvío de datos enviaría el valor escrito por I1 directamente a I2, evitando un puesto a pesar de que I1 no ha completado su escritura a la memoria.
* Efectividad: Altamente efectivo para resolver los peligros sin procesar (leer después de escribir) donde la dependencia es entre las instrucciones de escritura y luego leer el mismo registro.
2. Stalling (inserción de burbujas):
* Mecanismo: Si el reenvío de datos no es posible (por ejemplo, la dependencia está demasiado separada en la tubería o implica acceso a la memoria), la tubería se detiene insertando "burbujas"-instrucciones sin OP-hasta que los datos estén listos.
* Ejemplo: I1 escribe a la memoria, e I2 se lee desde esa ubicación de memoria. El reenvío de datos no es factible ya que la escritura de I1 debe completarse antes de que I2 pueda leer. La tubería se detiene hasta que I1 completa su escritura.
* Efectividad: Más simple de implementar que el reenvío pero reduce significativamente el rendimiento de la tubería.
3. Registre el cambio de nombre:
* Mecanismo: El compilador o hardware asigna diferentes registros a las instrucciones que podrían tener una dependencia de datos. Esto elimina los peligros de guerra (escribir después de leer) y Waw (escribir después de escribir). Por ejemplo, si dos instrucciones usan el mismo registro, el hardware puede cambiar el nombre de uno de ellos a un registro diferente, resolviendo así el conflicto.
* Ejemplo: Dos instrucciones quieren escribir en R1. REGISTRO Rename asigna la segunda instrucción un registro temporal diferente, resolviendo el peligro de WAW.
* Efectividad: Altamente efectivo para eliminar los peligros de guerra y WAW, pero implica complejidad de hardware. A menudo utilizado junto con el reenvío de datos.
4. Optimizaciones del compilador:
* Mecanismo: Los compiladores pueden analizar el código para dependencias de datos y reordenar las instrucciones para minimizar los peligros. Esto puede implicar la programación de instrucciones para separar las instrucciones que dependen entre sí, reduciendo así la necesidad de estancar o reenviar.
* Ejemplo: El compilador podría reordenar instrucciones para mover instrucciones que lean datos más lejos de las instrucciones que escriben esos datos, lo que le da a la tubería más tiempo para finalizar antes de que la instrucción dependiente lo necesite.
* Efectividad: Reduce la frecuencia de los peligros en el nivel del código fuente, pero la efectividad depende de las capacidades del compilador.
La elección de la técnica de mitigación depende de la arquitectura específica del procesador. Los procesadores modernos generalmente utilizan una combinación de reenvío de datos, renombro de registro y optimizaciones de compiladores para un manejo eficiente de riesgos de datos. El estancamiento a menudo se usa como último recurso cuando otras técnicas son insuficientes.