He leído que los procesadores Intel modernos usan las instrucciones CISC en la parte superior, que se convierten en instrucciones más simples similares a RISC en forma de microoperaciones en el back-end.
Entonces, si las microoperaciones de Intel son controles de nivel de hardware simples similares a RISC, entonces, ¿qué hacen las microoperaciones ARM?
Debido a que las instrucciones ARM ya son bastante similares a RISC, ¿cómo se vería su forma de microoperaciones?
Todos los microprocesadores y, de hecho, todos los circuitos digitales síncronos funcionan en lo que se denomina un "nivel de transferencia de registro". Básicamente, todo lo que hace cualquier microprocesador es cargar valores en registros de diferentes fuentes. Esas fuentes pueden ser la memoria, otros registros o la ALU (Unidad Lógica Artimática, una calculadora dentro del procesador). Algunos de los registros son registros simples dentro del procesador, algunos registros pueden ser registros de funciones especiales que se encuentran alrededor de la CPU, en 'periféricos' como puertos de E/S, unidad de administración de memoria, unidad de interrupción, esto y aquello.
En este modelo, las 'Instrucciones' son secuencias básicas de transferencias de registros. Normalmente no tiene sentido darle al programador la capacidad de controlar cada transferencia de registro individualmente, porque no todas las posibles combinaciones de transferencia de registros son significativas, por lo que permitir que el programador las exprese todas sería un desperdicio en términos de consumo de memoria. Básicamente, cada procesador declara un conjunto de conjuntos de transferencias de registros que le permite al programador pedirle al procesador que haga, y estos se denominan 'Instrucciones'.
Por ejemplo, ADD A, B, C podría ser una operación en la que la suma de los registros A y B se coloca en el registro C. Internamente, serían tres transferencias de registro: cargar la entrada izquierda del sumador de A, cargar la entrada derecha del sumador de B, luego cargar C desde la salida del sumador. Además, el procesador realiza las transferencias necesarias para cargar el registro de dirección de memoria desde el contador de programa, cargar el registro de instrucción desde el bus de datos de memoria y, finalmente, cargar el contador de programa desde el incrementador de contador de programa.
El 8086 usó una tabla de búsqueda de ROM interna para ver qué transferencias de registro realizan cada instrucción. Los diseñadores de la CPU 8086 programaron libremente el contenido de esa ROM, por lo que eligieron secuencias de instrucciones que parecían útiles para el programador, en lugar de elegir secuencias que serían simples y rápidas de ejecutar por la máquina. Recuerde que en esos días la mayoría del software se escribía en lenguaje ensamblador, por lo que tenía sentido hacerlo lo más fácil posible para el programador. Posteriormente, Intel diseñó el 80286, en el que cometieron, lo que ahora parece, un error crítico. Les quedaba algo de memoria de microcódigo sin usar y pensaron que también podrían llenarlo con algo, y se les ocurrió un montón de instrucciones solo para llenar el microcódigo. Esto los mordió al final, ya que todas esas instrucciones adicionales debían ser respaldadas por el 386, 486,
ARM es un diseño de procesador mucho más nuevo que el 8086 y la gente de ARM tomó una ruta de diseño diferente. Para entonces, las computadoras eran comunes y había muchos compiladores disponibles. Entonces, en lugar de diseñar un conjunto de instrucciones que sea bueno para el programador, eligieron un conjunto de instrucciones que es rápido para que la máquina lo ejecute y eficiente para que el compilador genere código. Y por un tiempo, el X86 y ARM eran diferentes en la forma en que ejecutaban las instrucciones.
Luego pasa el tiempo y las CPU se vuelven cada vez más complejas. Y también los microprocesadores se diseñan usando computadoras y no lápiz y papel. Ya nadie usa microcódigo, todos los procesadores tienen una unidad de control de ejecución cableada (lógica pura). Todos tienen múltiples unidades de cálculo de enteros y múltiples buses de datos. Todos traducen sus instrucciones entrantes, las reprograman y las distribuyen entre las unidades de procesamiento. Incluso los antiguos conjuntos de instrucciones RISC se traducen en nuevos conjuntos de operaciones RISC. Entonces, la vieja pregunta de RISC versus CISC ya no existe. Volvemos de nuevo al nivel de transferencia de registros, los programadores piden a las CPU que realicen operaciones y las CPU las traducen en transferencias de registros. Y si esa traducción se realiza mediante una ROM de microcódigo o una lógica digital cableada, realmente ya no es tan interesante.
La idea de que "hay un RISC dentro del x86 moderno" es bastante engañosa. Tengo la impresión de que Intel lo dijo por primera vez como una estrategia de marketing cuando lanzaron el i486, que fue el primer x86 canalizado y podía ejecutar muchas instrucciones en 1 ciclo, como las CPU RISC contemporáneas.
El problema es que RISC y CISC se tratan de conjuntos de instrucciones (que son visibles para el programador de ensamblaje), no de microarquitectura interna. x86 se ha diseñado como microcodificado (8086), segmentado (80486), OoO con microoperaciones (PentiumPro), VLIW (Transmeta)...
Volviendo a la pregunta.
Las microoperaciones realmente no forman un conjunto de instrucciones, son más bien similares a las señales que atraviesan una tubería, seleccionando registros de lectura y escritura, operaciones ALU...
La mayoría de las instrucciones ARM se pueden ejecutar en un solo paso, mientras que muchas instrucciones x86 deben descifrarse en una secuencia de 2 o más microoperaciones, pero hay poca diferencia.
En las CPU OoO, partes de esta información se almacenan en FIFO y búferes como colas de reserva, búfer de reordenación... Estas partes de las instrucciones son bastante similares en principio entre ARM y x86, pero no hay un "RISC interno".
¡¡Los ARM no usan microoperaciones!!
Wouter van Ooijen
Tipo de serpiente venenosa