MIPS (PIC32): rama contra rama probable

6

Ha pasado un tiempo desde que observé los recientes procesadores Microchip & He estado tratando de aprender un poco sobre el conjunto de instrucciones PIC32 MIPS. Noté que hay dos conjuntos de instrucciones de rama; La guía de programación dice esto:

  

4.1.3.2 Retrasos de ramificación y la ranura de retardo de ramificación

     

Todas las ramas tienen un retraso arquitectónico de una instrucción. La instrucción que sigue inmediatamente a una rama se dice que es   en la ranura de retardo de rama. Si se coloca una instrucción de bifurcación o salto en la ranura de retardo de bifurcación, la operación de ambos   Las instrucciones no están definidas.

     

Por convención, si una excepción o interrupción impide la finalización de una instrucción en la ranura de retardo de bifurcación, el   la secuencia de instrucciones continúa al volver a ejecutar la instrucción de bifurcación. Para permitir esto, las ramas deben ser reiniciables;   las llamadas de procedimiento no pueden usar el registro en el que se almacena el enlace de retorno (generalmente GPR 31) para determinar el objetivo de la rama   dirección.

     

4.1.3.3 Sucursal y sucursal probable

     
  • Las instrucciones de bifurcación ejecutan la instrucción en la ranura de retardo.

  •   
  • Las instrucciones probables de bifurcación no ejecutan la instrucción en la ranura de retardo si no se toma la bifurcación (se dice que   anule la instrucción en la ranura de retardo).

  •   

Aunque las instrucciones de Branch Likely están incluidas en esta especificación, se recomienda encarecidamente el software   evitar el uso de las instrucciones de Branch Likely, ya que se eliminarán de una futura revisión del MIPS   Arquitectura.

¿Podría alguien aclarar lo que están diciendo aquí? ¿Difieren en el número de ciclos de CPU tomados en cada caso?

Estoy acostumbrado a las arquitecturas de bifurcación de los PIC de 8 y 16 bits ("salto de bifurcación") donde ejecutas o saltas sobre una instrucción (esto suena como Branch Likely), y estoy acostumbrado a la arquitectura de bifurcación de los DSP de TI C2000 (donde todo lo que obtiene es una bifurcación o bifurcación condicional a una dirección). Pero no entiendo bien cómo asignar las instrucciones de la rama MIPS a mis conocimientos existentes.

    
pregunta Jason S

1 respuesta

10

MIPS es una de varias arquitecturas RISC (computadoras con conjunto de instrucciones reducido) que están diseñadas para ejecutar una instrucción por ciclo de reloj. Para lograr esto, los procesadores MIPS originales tenían un canal de cinco etapas:

Lasabreviaturasqueseencuentranenlafiguradearribason:IF(recuperacióndeinstrucción),RD(lecturadelarchivoderegistro),ALU(instruccióndeejecuciónenunidaddelógicaaritmética),MEM(accesodememoriadelectura/escritura),WB(Escrituraatráspararegistrararchivo).Elejeverticalesinstruccionessucesivas;Elejehorizontaleseltiempo.

DebidoaquelaetapaMEMseproducedespuésdelaetapaALU,lasmáquinasRISCcomoMIPSnorealizanoperacionesaritméticasológicasenlamemoria,sinosoloenlosregistros.Porestarazón,tambiénselesconocecomoarquitecturasdecarga/almacenamiento.

Hayvariascondicionesderiesgoenlasquelatuberíapuededetenerseycausarunapenalizaciónenelvalordelasinstruccionesporciclo(IPC).Unpeligrodedatosocurre,porejemplo,cuandounainstrucciónintentausardatosenunodelosregistrosantesdequesehayacargadoenelregistro.Porejemplo:

lw$3,100($2)add$1,$2,$3

LosdatosnosecarganhastalaetapaMEMdelaprimerainstrucción,queesdemasiadotardeparaqueestédisponibleparalaetapaEXdelasegundainstrucción.

Lospeligrosdecontrolseproducenporqueencualquierramatomada,lainstruccióninmediatamentedespuésdelaramasiempreseobtienedelcachédeinstrucciones.Siseignoraestainstrucción,hayuncicloporpenalizacióndeIPCderamatomada.

LasoluciónparalaarquitecturaMIPSfuela"Ranura de retardo de sucursal": siempre busque la instrucción después de la rama y siempre ejecútela, incluso si se toma la rama. Esto se vuelve un poco extraño al escribir el código de ensamblaje MIPS, porque cuando lo estás leyendo, debes tener en cuenta la instrucción después de que la rama siempre se va a ejecutar. El truco para escribir código eficiente es poner una instrucción que sea útil como parte del bucle que se está ejecutando, pero no haga daño si la rama no se toma.

Los diseñadores de MIPS contaban con escritores de compiladores para escribir generadores de código lo suficientemente inteligentes para manejar esto de manera eficiente. Sin embargo, muchos no lo hacen (incluido el compilador Microchips C32, basado en GCC), y simplemente ponen NOP después de cada rama, desperdiciando tanto el espacio de código como los ciclos.

Por lo tanto, en la arquitectura R4000, MIPS agregó instrucciones de rama probable que aún siempre obtienen la instrucción después de la rama de la caché de instrucciones, pero solo la ejecutan si la rama está tomada (al contrario de lo que uno podría esperar). Los compiladores siempre pueden llenar el espacio de retardo de sucursal en dicha sucursal.

Un bucle como:

loop:
    first instruction
    second instruction
    ...
    blez t0, loop
    nop

se puede convertir en:

loop:
    first instruction
loop2:   
    second instruction
    ...
    blez t0, loop2
    first instruction

La "primera instrucción" repetida después de la bifurcación siempre se ejecuta si se toma la bifurcación (y se convierte en parte de la próxima vuelta al bucle. Esta instrucción se ignora si la bifurcación es no tomada (incurriendo en una leve penalización de IPC).

Sin embargo, resulta que tratar de incluir esta característica en diseños de alto rendimiento ha sido un dolor de cabeza debido a la complejidad para deshacerse del resultado de la instrucción ignorada. Por lo tanto, ha sido desaprobado.

    
respondido por el tcrosley

Lea otras preguntas en las etiquetas