En las unidades centrales de procesamiento de las computadoras , las microoperaciones (también conocidas como microoperaciones o μops , históricamente también como microacciones [2] ) son instrucciones detalladas de bajo nivel que se utilizan en algunos diseños para implementar instrucciones de máquina complejas (a veces denominadas macroinstrucciones en este contexto). [3] : 8–9
Por lo general, las microoperaciones realizan operaciones básicas sobre datos almacenados en uno o más registros , incluyendo la transferencia de datos entre registros o entre registros y buses externos de la unidad central de procesamiento (CPU), y la realización de operaciones aritméticas o lógicas en registros. En un ciclo típico de búsqueda-decodificación-ejecución , cada paso de una macroinstrucción se descompone durante su ejecución de modo que la CPU determina y recorre paso a paso una serie de microoperaciones. La ejecución de microoperaciones se realiza bajo el control de la unidad de control de la CPU , que decide sobre su ejecución mientras realiza varias optimizaciones como reordenamiento, fusión y almacenamiento en caché. [1]
Varias formas de μops han sido durante mucho tiempo la base de las rutinas de microcódigo tradicionales utilizadas para simplificar la implementación de un diseño de CPU particular o quizás solo la secuenciación de ciertas operaciones de múltiples pasos o modos de direccionamiento. Más recientemente, las μops también se han empleado de una manera diferente para permitir que los procesadores CISC modernos manejen más fácilmente la ejecución paralela y especulativa asincrónica: al igual que con el microcódigo tradicional, se realizan una o más búsquedas de tabla (o equivalentes) para localizar la secuencia de μop adecuada según la codificación y la semántica de la instrucción de la máquina (el paso de decodificación o traducción); sin embargo, en lugar de tener secuencias de μop rígidas que controlen la CPU directamente desde una ROM de microcódigo , las μops se almacenan dinámicamente en búfer para su reprogramación antes de ejecutarse. [4] : 6–7, 9–11
Este almacenamiento en búfer significa que las etapas de búsqueda y decodificación pueden estar más separadas de las unidades de ejecución de lo que es factible en un diseño microcodificado (o cableado) más tradicional. Como esto permite un grado de libertad con respecto al orden de ejecución, hace posible cierta extracción de paralelismo a nivel de instrucción de un programa normal de un solo subproceso (siempre que se verifiquen las dependencias, etc.). Abre la posibilidad de realizar más análisis y, por lo tanto, también de reordenar las secuencias de código para optimizar dinámicamente el mapeo y la programación de μops en los recursos de la máquina (como las ALU , las unidades de carga/almacenamiento, etc.). Como esto sucede en el nivel de μop, las suboperaciones de diferentes instrucciones de máquina (macro) a menudo pueden entremezclarse en una secuencia de μop particular, formando instrucciones de máquina parcialmente reordenadas como consecuencia directa del envío desordenado de microinstrucciones desde varias instrucciones macro. Sin embargo, esto no es lo mismo que la fusión de microoperaciones , que apunta al hecho de que una microinstrucción más compleja puede reemplazar algunas microinstrucciones más simples en ciertos casos, generalmente para minimizar los cambios de estado y el uso de la cola y el espacio del búfer de reordenamiento , reduciendo así el consumo de energía. La fusión de microoperaciones se utiliza en algunos diseños de CPU modernos. [3] : 89–91, 105–106 [4] : 6–7, 9–15
La optimización de la ejecución ha ido aún más lejos; los procesadores no sólo traducen muchas instrucciones de máquina en una serie de μops, sino que también hacen lo contrario cuando es apropiado; combinan ciertas secuencias de instrucciones de máquina (como una comparación seguida de un salto condicional) en un μop más complejo que se ajusta mejor al modelo de ejecución y, por lo tanto, se puede ejecutar más rápido o con menos recursos de la máquina involucrados. Esto también se conoce como fusión de macrooperaciones . [3] : 106–107 [4] : 12–13
Otra forma de intentar mejorar el rendimiento es almacenar en caché las microoperaciones decodificadas en una caché de microoperaciones , de modo que si se ejecuta de nuevo la misma macroinstrucción, el procesador pueda acceder directamente a las microoperaciones decodificadas desde la caché, en lugar de decodificarlas de nuevo. La caché de seguimiento de ejecución que se encuentra en la microarquitectura Intel NetBurst ( Pentium 4 ) es un ejemplo extendido de esta técnica. [5] El tamaño de esta caché puede expresarse en términos de cuántos miles (o estrictamente múltiplos de 1024) de microoperaciones puede almacenar: Kμops . [6]