¿Podría una instrucción de bifurcación ARM (ARM7TDMI) tomar 6 ciclos?

4

Parece que una instrucción de rama ARM parece tardar 6 ciclos en ejecutarse en un procesador ARM7TDMI. Parece que no debería estar sucediendo porque en todas las referencias que he encontrado, una instrucción de bifurcación ARM7TDMI debería tomar solo 3 ciclos. Pero:

La función C:

start_time = TC;
for (int i=0; i<120; i++) {
  __asm("NOP");
}
end_time = TC;

El desmontaje muestra el bucle como: (Actualización: direcciones de instrucciones agregadas):

0x120             MOV R1, 0
0x124             B LOC0
            start:    
0x128             NOP
0x12C             ADD R1, R1, 1
            LOC0:     
0x130             CMP R1, 120
0x134             BLT start

Ahora el resultado muestra que el bucle toma 1080 ciclos (convertido de un contador de temporizador colocado en TC), es decir, 9 ciclos por núcleo de bucle. Como NOP , ADD , CMP son todas instrucciones de un solo ciclo, BLT tiene que ser de 6 ciclos.

Una vez sospecho que mi método de sincronización tiene fallas. Pero si agrego 1 NOP en el kernel de bucle, el aumento de tiempo equivaldría exactamente a 1 ciclo.

¿Qué está mal aquí?

(Actualización: solución: el código de desensamblado original se escribe incorrectamente ADD R1, R1, 1 como ADD R1, R1 )

Actualización: respuesta aceptada: el bloqueo de acceso Flash provoca los 3 ciclos adicionales

Gracias a todos por las respuestas y comentarios útiles, especialmente @supercat, @Dzarda, @DaveTweed, @IgorSkochinsky, @WoutervanOoijen. Estoy ejecutando el código de flash. La CPU es una LPC23xx. De acuerdo con el Manual del usuario, sí incluye un Módulo de aceleración de memoria (MAM) para el acceso de flash con buffer. Y los ciclos de captura de flash sugeridos bajo la velocidad de mi CPU son exactamente 3 ciclos.

El start en el núcleo del ciclo penalizado anterior se está alineando con un límite de 8 bytes. Si cambio la alineación de start al límite de 16 bytes, desaparecerá la penalización de 3 ciclos adicionales. Esto se puede explicar por el tamaño del búfer de captura previa de flash de 128 bits (16 bytes) de mi CPU.

(@WoutervanOoijen) Tenga en cuenta que el tiempo de recuperación instantánea de MAM de 3 ciclos no lo realiza la CPU ARM, sino el módulo MAM que realiza una búsqueda previa de los datos flash en paralelo con la CPU. Así que en mi código con start alineado en el límite de 8 bytes, CMP es la primera instrucción en el búfer de búsqueda previa de MAM de 128 bits (4 instrucciones). Cuando la CPU ARM ejecuta BLT , el primer ciclo tarda en "entender" la instrucción. Luego intenta obtener la instrucción NOP que no está en el búfer de búsqueda previa de MAM. Ese debería ser el momento en que los 3 ciclos adicionales ocurren cuando el MAM accede al flash. Cuando la instrucción NOP está en el búfer (junto con otras 3 instrucciones en la línea flash de 32 bytes), la CPU ARM puede volver a llenar la tubería al obtener NOP (quinto ciclo) y decodificar NOP ( 6º ciclo). De ahí provienen los 6 ciclos totales.

Entonces, la respuesta a mi pregunta es Sí, una instrucción de derivación de 6 ciclos es posible si hay un puesto de acceso flash.

Pregunta final sin resolver

Como señala @WoutervanOoijen, el razonamiento anterior tiene una falla. El módulo de aceleración de memoria de LPC23xx tiene un búfer de Branch Trail adicional que se supone que evita este tipo de ramas repetidas de bucle de recuperación. El LPC23XX User Manual indica:

  

El búfer de Branch Trail captura la línea en la que se produce una ruptura no secuencial. Si se vuelve a tomar la misma rama, la siguiente instrucción se toma del búfer de Trail Trail

Esta declaración no parece ser muy clara sobre lo que se está poniendo exactamente en el búfer de Branch Trail. Podría ser la última línea de flash precargada, o la última línea de flash de destino de rama. En cualquier caso, la penalización de acceso de flash no debería haber ocurrido porque la línea de flash (0x120 ~ 0x12F) que incluye la instrucción de destino de bifurcación ( NOP ) ya debería estar en el búfer Trail Trail cuando se está ejecutando BLT a partir de la segunda vez).

(Por cierto, verifiqué que MAM se puso en modo Totalmente Habilitado, es decir, MAM_mode_control es 2)

Actualizaré esta pregunta cuando encuentre más información sobre esto. Y lo apreciaré si tiene algún comentario sobre lo que podría estar sucediendo aquí, o qué prueba se puede hacer para buscar pistas.

    
pregunta Penghe Geng

2 respuestas

7

¿Está ejecutando código desde RAM o desde flash? Los procesadores ARM que ejecutan código desde flash a menudo requieren estados de espera en al menos algunas circunstancias; tales procesadores a menudo incluyen hardware que puede eliminar la mayoría de los estados de espera en el código común, pero dicho hardware puede ser tan simple como un búfer de una línea que permite un acceso a la misma línea de flash que el acceso anterior para evitar el estado de espera. Si el objetivo de la rama es la última palabra de una línea de destello, entonces el destello requeriría dos o tres ciclos para obtener esa palabra, y dos o tres ciclos para obtener la siguiente palabra. Si uno de los ciclos se realiza simultáneamente con alguna otra operación de la CPU, eso dejaría una penalización de tres ciclos.

    
respondido por el supercat
1

Eche un vistazo a el centro de información ARM, figura 2 , teniendo en cuenta que está trabajando con el gasoducto ARM7 y no con el gasoducto M3 de 3 etapas. El punto sigue siendo válido.

Puede haber ciclos entre la captura y la ejecución. Es muy difícil contar los tics del reloj para los ciclos de instrucción en un núcleo moderno canalizado. No estoy seguro de que sea siquiera determinista

Me pregunto si el pipleline debe comenzar de nuevo en cada rama. Podría considerar apilar un montón de estos NOP en lugar de bifurcarse para ver si su comportamiento resultante es más determinista como paso de depuración.

De hecho, me han advertido sobre el uso de NOP para retrasos precisos en las plataformas ARM por este motivo.

    
respondido por el Scott Seidman

Lea otras preguntas en las etiquetas