Por supuesto, la condición se verifica cada vez. Pero para el momento en que se verifica, está muy avanzado en la tubería de la CPU. Mientras tanto, otras instrucciones también han entrado en la tubería, y se encuentran en diversas etapas de ejecución.
Por lo general, una condición es seguida inmediatamente por una instrucción de bifurcación condicional, que se bifurca si la condición se evalúa como VERDADERA o falla si la condición se evalúa como FALSA. Esto significa que hay dos flujos diferentes de instrucciones que pueden cargarse en la tubería después de la instrucción de condición y la instrucción de derivación, dependiendo de si la condición se evalúa como VERDADERA o FALSA. Desafortunadamente, inmediatamente después de cargar la instrucción de condición y la instrucción de bifurcación, la CPU aún no sabe a qué se evaluará la condición, pero aún tiene que seguir cargando cosas en la tubería. Por lo tanto, elige uno de los dos conjuntos de instrucciones basándose en una suposición sobre lo que la condición evaluará.
Más adelante, a medida que la instrucción de condición viaja por la tubería, es hora de ser evaluada. En ese momento, la CPU descubre si su suposición fue correcta o incorrecta.
Si la suposición resulta correcta, entonces la rama fue al lugar correcto y las instrucciones correctas se cargaron en la tubería. Si resulta que la suposición fue incorrecta, entonces todas las instrucciones que se cargaron en la tubería después de la instrucción de ramificación condicional fueron incorrectas, deben descartarse, y la recuperación de instrucciones debe comenzar nuevamente desde el lugar correcto.
Enmienda
En respuesta al comentario de StarWeaver, para dar una idea de lo que la CPU tiene que hacer para ejecutar una sola instrucción:
Considere algo tan simple como MOV AX,[SI+10]
lo que los humanos pensamos ingenuamente como "cargar AX con la palabra en SI más 10". Aproximadamente, la CPU tiene que:
- emitir el contenido de la PC (el "registro del contador del programa") al bus de direcciones;
- lea el código de operación de instrucciones del bus de datos;
- PC incremental;
- decodifica el código de operación para saber qué hacer con él;
- emitir el contenido de la PC al bus de direcciones;
- lea el operando de instrucción (en este caso 10) del bus de datos;
- PC incremental;
- alimentar el operando y SI al sumador;
- emitir el resultado del sumador al bus de direcciones;
- lea AX desde el bus de datos.
Esta es la friolera de 10 pasos. Algunos de estos pasos se optimizarán incluso en CPU no interconectadas, por ejemplo, la CPU casi siempre incrementará la PC en paralelo con el siguiente paso, lo cual es algo fácil de hacer porque la PC es un registro muy, muy especial que es nunca se utiliza para ningún otro trabajo, por lo que no hay posibilidad de disputa entre diferentes partes de la CPU para acceder a este registro en particular. Pero aún así, nos quedan 8 pasos para una instrucción tan simple, y tenga en cuenta que ya estoy asumiendo cierto grado de sofisticación en nombre de la CPU, por ejemplo, supongo que no habrá necesidad de un paso adicional completo para el sumador para llevar a cabo la adición antes de que se pueda leer el resultado,
Ahora, considere que existen modos de direccionamiento más complicados, como MOV AX, [DX+SI*4+10]
, e incluso instrucciones mucho más complicadas, como las MUL AX, operand
que realmente realizan bucles dentro de la CPU para calcular su resultado.
Entonces, mi punto aquí es que la metáfora del "nivel atómico" está lejos de ser adecuada para el nivel de instrucción de la CPU. Puede ser adecuado para el nivel de paso de la tubería, si no desea ir demasiado lejos al nivel real de la puerta lógica.