¿Por qué las arquitecturas de CPU utilizan un registro de banderas (ventajas)?

15

Algunas CPU tienen un registro de banderas (ARM, x86, ...), otras no (MIPS, ...). ¿Cuál es la ventaja de tener una instrucción CMP para actualizar el registro de banderas seguido de una instrucción de bifurcación en lugar de usar un registro cero y bifurcaciones condicionales para verificar signos, desbordamientos, etc.?

mundo modelo
fuente

Respuestas:

11

En las microarquitecturas modernas con cambio de nombre de registro, el costo de implementación para banderas o no banderas es bastante similar. La principal diferencia que se me ocurre es que algunos indicadores indican las características de un valor (¿Es el valor negativo? ¿Es el valor cero? ¿El valor tiene paridad par o impar?), Mientras que algunos representan un evento que ocurrió durante una operación anterior (¿la instrucción de agregar se realizó o se desbordó?) Esto condujo a una situación menos que ideal en el MIPS cuando deseaba simular la adición de 64 bits en la arquitectura de 32 bits (o la adición de 128 bits en el Arquitectura de 64 bits.) En la mayoría de las arquitecturas con una bandera de acarreo hay un especialadd-with-carryinstrucción, que incluye el indicador de acarreo de la instrucción de agregar anterior. Esto hace que la simulación de aritmética de precisión múltiple sea relativamente económica en muchas arquitecturas con registros de banderas.

Por otro lado, probar un registro de N bits para cero o no cero es en realidad sorprendentemente costoso. Para probar un registro de N bits para cero, debe realizar una operación NOR de N bits, que requiere niveles de lógica para calcular. En arquitecturas con registros de banderas, la lógica adicional para el cálculo de cero / no cero al final de la etapa ALU puede hacer que el reloj funcione más lento (o forzar a la ALU a tener dos operaciones de ciclo). Por esta razón, creo, algunos arquitecturas, como SPARC, tenían dos versiones de cada operación aritmética, una que establecía banderas y otra que no.O(Iniciar sesiónnorte)

Pero MIPS no guarda nada aquí. Simplemente trasladaron el problema a otro lugar. En MIPS hay una branch-on-equalinstrucción. Esto significa que la instrucción de bifurcación debe tener una etapa ALU (que incluye algo como una xoroperación bit a bit seguida de una norpara reducir al bit único igual / no igual) antes de determinar en qué dirección va la bifurcación.

La arquitectura DEC Alpha intentó dividir la diferencia usando un truco. DEC Alpha no tenía registros de banderas, pero tampoco tenía branch-on-equalinstrucciones. En cambio, las instrucciones de la rama miran el estado de un único registro de propósito general. Hay branch-on-zero, branch-on-not-zero, branch-on-less-than-zero, etc. El truco es que se puede dar a cada propósito general registra un bit número 65 extra que le indica si los otros 64 bits son todos cero o no. Esto lo hace más parecido a tener un registro de banderas: todas las instrucciones de la rama miran un solo bit (que ya está calculado) para tomar su decisión, pero ahora vuelven a descubrir cómo calcular ese bit indicador cero adicional durante una ALU normal ciclo. (Y aún no puede hacer aritmética de precisión múltiple con solo mirar el indicador de acarreo de la operación anterior).

Lógica Errante
fuente
2
Las operaciones de configuración que no son CC fueron (por lo que entiendo) una optimización del compilador , lo que permitió al compilador programar las instrucciones de configuración CC temprano sin que el valor se vea afectado por estas últimas instrucciones. El PowerPC750 colocó los registros de condición (8 registros de 4 bits) más cerca del extremo frontal de modo que una rama tomada golpee el caché de instrucciones de destino de la rama y tenga la condición disponible lo suficientemente temprano como para resolver una rama tomada sin penalización. (CRISP de AT&T también explotó la resolución inicial de sucursales). La pequeña cantidad y especialización de CC lo hace más práctico.
Paul A. Clayton
Un detalle: todos los cálculos de banderas no son iguales. Imagine que su CPU tiene las tradicionales banderas NZVC. Si se permiten todas las instrucciones de ALU para actualizar las banderas, debe colocar la generación de banderas después del sumador / sustractor y algunos muxes. El indicador negativo es fácil, es solo el MSB, mientras que el indicador cero es costoso y depende de cada bit. Ahora, si restringe los indicadores a las instrucciones de comparación (y prueba de bits), los indicadores de cero se pueden calcular con XOR paralelos en los operandos de origen, sin esperar el resultado de la resta. Calcular la bandera Z después de una adición es casi inútil.
TEMLIB
7

1 Desde una perspectiva ISA

  1. Tener instrucciones de prueba que establezcan solo los indicadores es solo una forma de reducir la presión de registro en arquitecturas de registro hambrientos. Si tiene suficientes registros, simplemente modifique uno de ellos e ignore el resultado. El truco de tener un registro 0 con el valor de entrada 0 es solo un truco de codificación conveniente cuando tienes suficientes registros para fijar uno de ellos en 0 es mejor que aumentar el número de instrucciones. Es conveniente usarlo también como objetivo (reduce el número de dependencias falsas).

  2. Codificando de nuevo. Si codifica la condición en saltos, tendrá saltos con 3 operandos (los dos para comparar y el objetivo de salto), dos de los cuales le gustaría ser valores inmediatos, uno que le gustaría ser tan grande como posible (los saltos suelen tener su propio formato de codificación para que el objetivo pueda utilizar tantos bits como sea posible). O dejas caer las posibilidades.

  3. El uso de banderas te brinda más oportunidades para configurarlas. No son solo las operaciones de comparación las que pueden establecer las banderas, sino lo que quieras. (Con la advertencia de que cuantas más operaciones tenga que establezcan banderas, más cuidado deberá tener para asegurarse de que la última operación que establezca las banderas sea la que desea). Si tiene banderas, puede probar el número de condiciones (a menudo 16) multiplicado por la cantidad de instrucciones que pueden establecer las banderas (si no está usando banderas, terminará con tantos saltos condicionales como desee). tiene cosas para probar o hay cosas que no permite probar con tanta facilidad (por ejemplo, cargar o desbordar).

2 Desde la perspectiva del implementador

  1. Probar banderas es fácil y se puede hacer rápidamente. Cuanto más compleja sea su prueba, más efecto tendrá sobre el tiempo del ciclo (o la estructura de la tubería si está conectado). Eso es especialmente cierto para implementaciones más simples, cuando se llega a un procesador de alta gama que utiliza todos los trucos del libro, el efecto es bastante mínimo.

  2. Tener banderas significa que muchas instrucciones tienen múltiples resultados (el resultado natural y cada una de las banderas modificadas). Y a partir de un punto de vista de microarquitectura, los resultados múltiples son malos (debe realizar un seguimiento de su asociación). Cuando solo tiene un conjunto de indicadores, que introducen dependencias (innecesarias si el indicador no se usa), debe manejar de una forma u otra. Nuevamente, eso es especialmente cierto para implementaciones más simples, cuando llegas a un procesador de alta gama utilizando todos los trucos del libro, el resto del procesador empeora las dificultades adicionales.

Un programador
fuente
2

En una máquina de 32 bits, una instrucción de "agregar con acarreo" utilizada como parte de una secuencia de suma de precisión múltiple necesita aceptar 65 bits de operandos y calcular una suma de 33 bits. Las especificaciones del registro de origen identificarán de dónde deberían provenir 64 bits de operando, y la especificación del registro de destino indicará a dónde deben ir los 32 bits inferiores del resultado, pero qué hacer con el operando "agregar un extra" o el bit superior del resultado? Ser permitido moderar como parte de la instrucción de dónde debe venir el operando adicional y hacia dónde debe ir el bit de resultado adicional sería moderadamente útil, pero generalmente no sería tan útil como para justificar un campo adicional en el código de operación. Tener una "ubicación" fija para manejar la bandera de transporte puede ser un poco incómodo desde una perspectiva de programación de instrucciones, pero '

Si uno intentara diseñar un conjunto de instrucciones para permitir la aritmética de precisión múltiple pero cada instrucción se limitara a dos operandos de 32 bits y un operando de destino de 32 bits, uno podría implementar un "agregar" de 64 bits en cuatro instrucciones: "conjunto r5 a 1 si r0 + r2 llevaría o cero de otra manera; calcule r4 = r1 + r3; calcule r5 = r4 + r5; calcule r4 = r0 + r2 ", pero ir más allá requeriría tres instrucciones para cada palabra adicional. Tener una bandera de transporte disponible como fuente y destino suplementarios reduce el costo a una instrucción por palabra.

Tenga en cuenta, por cierto, que tener un bit de instrucción controla si la instrucción actualiza el registro de bandera puede facilitar la ejecución fuera de orden, ya que las instrucciones que usan o modifican los bits de bandera deben mantener su secuencia entre sí, pero las instrucciones que no pueden ser reorganizado libremente. Dada la secuencia:

ldr  r0,[r1]
add  r0,r0,r2
eors r4,r5,r6

una unidad de ejecución podría reconocer con bastante facilidad que la tercera instrucción podría ejecutarse sin tener que esperar a que se lean los datos [r1], pero si la segunda instrucción hubiera sido adds r0,r0,r2así, solo sería posible si la unidad de ejecución pudiera garantizar que para cuando algo intentara usar las banderas, la bandera cero mantendría el valor establecido en la tercera instrucción pero la bandera de acarreo mantendría el valor en la segunda.

Super gato
fuente
1
"bit de instrucción controla si la instrucción actualiza el registro de marca": disponible por ejemplo en PowerPC, SPARC.
TEMLIB
MIPS usa "r5 = r1 + r2; establezca r6 si r6 es menor que r1; r7 = r3 + r4; r5 = R5 + R6;". Algunas extensiones SIMD podrían usar comparaciones que establecen todos los bits en cero o uno (es decir, cero o -1 dos enteros complementarios) para encontrar el acarreo y la resta para aplicar el acarreo.
Paul A. Clayton
@ PaulA.Clayton: Creo que quisiste decir "si r5 es menor que r1". ¿Cómo manejaría MIPS las matemáticas más largas? ¿Requiere tres, más de tres o menos de tres instrucciones por palabra?
supercat
@supercat Sí, ¡eso debería haberse "configurado r6 si r5 es menor que r1"!
Paul A. Clayton
@ PaulA.Clayton: ¿Cómo se podría agregar, por ejemplo, dos números de 64 palabras (2048 bits) en un MIPS de 32 bits? ¿Hay alguna forma eficiente de manejar los acarreos dentro y fuera de las etapas intermedias?
supercat
0

Respuesta simple ... operación de memoria rápida y barata que no requiere absolutamente ningún uso de bus interno, excepto la instrucción en sí. Se puede usar como una pila bool sin una pila o un bit de proceso, sin memoria.

SkipBerne
fuente
1
Esta respuesta es bastante ligera en los detalles. Las respuestas largas no son necesariamente necesarias, pero algo más desarrollado sería una mejora clara.
David Richerby
establecer un indicador o comparar un valor de indicador es una sola instrucción sin ninguna otra información en forma de argumentos que se incluirían en el código de ensamblaje. Los indicadores también son el resultado de la operación o prueba del uprocessor y se pueden utilizar de manera eficiente para bifurcar. son el bit real que se alterna o establece cuando se comparan dos valores en los registros.
SkipBerne