¿Las computadoras ejecutan una instrucción a la vez? Si hay cuatro procesos en un momento dado, ¿eso significa que la computadora ejecuta cuatro instrucciones o ejecuta una?

Esta es una pregunta muy complicada, con varias capas de respuestas. Dibujaré lo que todo puede estar sucediendo simultáneamente en un momento dado. Nota: lo que esbozo a continuación es el caso ideal: en la práctica, los procesadores pierden tiempo, por ejemplo, esperando que los datos provengan de la memoria, de un caché coherente, etc.

  1. Múltiples núcleos son como computadoras separadas, por lo que tener 4 núcleos significa que tiene (al menos) 4 instrucciones trabajando al mismo tiempo.
  2. Los hilos son menos claros. En parte son una construcción de software, por lo que puede crear 100 subprocesos, y claramente su CPU no ejecutará cien instrucciones simultáneamente: simplemente cambiará muy rápidamente entre ellas.
  3. Sin embargo, algunos procesadores (por ejemplo, Intel Xeon Phi, y creo que algunos de los próximos procesadores posteriores a Haswell) tienen “hilos de hardware”: en realidad pueden hacer que algunos de los hilos de software se ejecuten simultáneamente.
  4. Como se indica en algunas otras respuestas: los procesadores tienen canalización. Si tiene una secuencia de instrucciones idénticas, pasan por una línea de ensamblaje que se completará parcialmente. Si una instrucción toma 6 ciclos, y la tubería tiene 6 etapas, entonces, en cualquier ciclo de reloj, tendrá 5 instrucciones completadas parcialmente, y una entregada. Entonces, en cierto modo, hay 5 o 6 instrucciones trabajando simultáneamente, solo en diferentes grados de progreso.
  5. Los procesadores a menudo tienen unidades de suma y multiplicación separadas. Si su programa está escrito de tal manera que el compilador puede encontrar una suma y una multiplicación que no dependen entre sí, el procesador puede ejecutarlas simultáneamente. (Con Haswell y versiones posteriores, Intel es en realidad algo ligeramente diferente: solo hay unidades FMA ‘fusionadas-sumar’ que pueden hacer “x = ax + y” en un ciclo. Para hacer una multiplicación de la suma, establezca “y = 0” o “a = 1” respectivamente. Esa es una forma ligeramente diferente de tener más de una operación, aunque es solo una instrucción).
  6. Finalmente, las unidades de coma flotante a menudo tienen “carriles SIMD”: en lugar de operar en un solo par de operandos, operan en registros de 2 operandos de ancho (SSE clásico), 4 de ancho (Intel Haswell) o incluso 8 de ancho (Intel Xeon Fi). Y por “operando” me refiero a un número de coma flotante de 8 bytes. Mi sesgo de HPC se está mostrando.

Entonces, en un chip como el Xeon Phi, tendrá 60 núcleos, cada uno con 4 hilos de hardware, con unidades de suma y multiplicación independientes, cada una de 8 de ancho. ¡Dando 60 veces 4 veces 2 veces 8! ¡Uy dividido por 2 debido a un tecnicismo! = cerca de 2000 instrucciones activas en cada ciclo de reloj.

¿No es eso algo …? Por supuesto, tendrás un diablo escribiendo un programa que se ejecute con ese tipo de rendimiento.

Por el momento, consideremos un solo núcleo. También voy a ignorar las GPU, ya que también son bastante diferentes.

El recuento de todos los recursos informáticos en una CPU moderna es divertido e incluso a veces interesante, pero (en el mejor de los casos) por lo general solo le informa sobre un número máximo teórico de instrucciones que podrían estar “en vuelo” en un momento dado.

Esto es principalmente una métrica engañosa. No te dice mucho sobre lo que realmente está sucediendo. Ni siquiera te dice mucho sobre lo que teóricamente podría suceder como regla general.

El simple hecho es que, no importa cuánto haga en paralelo, un procesador típico tiene un par de cosas al principio y al final de la tubería que generalmente suceden en orden. La CPU comienza con las instrucciones de decodificación. Luego, las instrucciones se colocan en un búfer, y las unidades de ejecución ejecutan las instrucciones en función de la disponibilidad de los recursos que cada una necesita usar (por ejemplo, si una instrucción lee para un registro, no puede ejecutarse hasta después de cualquier instrucción anterior que escriba en ese mismo registro). Una vez que las unidades de ejecución se completan con una instrucción, la instrucción se “retira”.

Los números engañosos provienen de mirar la parte media, las unidades de ejecución. Como regla general, es mucho más significativo mirar el principio y el final de la tubería: las unidades de descodificación de instrucción y retiro de instrucciones. De los dos, la capacidad de la unidad de jubilación es a menudo la más significativa (pero los dos a menudo tienen la misma capacidad total, por lo que mirar a ambos es casi equivalente).

En la mayoría de las CPU, estas se limitan a alrededor de 3 instrucciones por ciclo. Eso proporciona un límite superior en la cantidad máxima de instrucciones que incluso puede esperar que el núcleo pueda ejecutar por ciclo de manera sostenida. No importa qué otros recursos estén disponibles, no importa cuán impresionantes suenen (o realmente sean, y realmente lo sean), el número de instrucciones que puede retirar por ciclo de reloj sigue siendo el límite superior en el número de instrucciones que puede ejecutar.

La cantidad mucho mayor de otros recursos en realidad solo trata de mantener la CPU lo más cerca posible de ese máximo. Para ser completamente honesto, sin embargo, generalmente fallan. Se necesita un código bastante raro (y escrito con mucho cuidado) para realmente acercarse al límite durante mucho tiempo. La mayoría de las veces, hace menos que eso. El número real suele ser entre la mitad y las dos terceras partes de ese número, como regla general, figura 1.8 instrucciones por ciclo (en promedio).

Depende del procesador. Con un procesador de un solo núcleo, generalmente esperaría que se ejecute una instrucción a la vez. Si el sistema operativo sysrem permite múltiples subprocesos o procesos, le da a cada uno un corto período de tiempo para ejecutarse, luego cambia la CPU al siguiente subproceso o proceso. Esto se llama segmentación de tiempo.

En un procesador con 4 núcleos, básicamente hay 4 CPU que trabajan juntas en el mismo chip, por lo que hay 4 instrucciones de ejecución a la vez. Un proceso o subproceso está programado para ejecutarse en un núcleo durante un período de tiempo, y otro subproceso se ejecuta en otro núcleo, y así sucesivamente.

Se vuelve un poco más complicado cuando se considera el efecto de la canalización, que es una forma de permitir que múltiples instrucciones estén en algún lugar del proceso de ejecución en un núcleo al mismo tiempo. Error en este caso, simplemente dice que el núcleo “comienza” una instrucción a la vez.

Esta es una de esas preguntas que parece simple en su cara, pero que rápidamente se mete en la maleza. Las personas que están más íntimamente familiarizadas con el diseño y la historia del procesador no podrán sacar el máximo provecho de esta historia que les voy a contar, pero está bien, porque esto se vuelve realmente complicado, muy rápido.

En términos generales, como regla general: sí, un procesador con cuatro núcleos puede ejecutar cuatro instrucciones simultáneamente. O ocho, y posiblemente muchos, muchos más.

Aquí es donde las cosas se ponen horribles.

Cuando una computadora arranca, el sistema operativo calcula cuántos núcleos puede ver, porque eso determina cuántos subprocesos puede ejecutar simultáneamente. Un hilo por núcleo … ¡excepto que las CPU modernas son mentirosas y sinvergüenzas del peor tipo!

Tomemos una CPU Intel moderna con dos núcleos, como la de mi computadora portátil. Cuando se inicia, le dice al sistema operativo que tiene cuatro, y en lo que respecta al sistema operativo, admitirá cuatro subprocesos simultáneos de ejecución, aunque solo haya dos núcleos reales. Los núcleos reales están muy ocupados tratando de hacer el uso más eficiente de sus grupos individuales de ALU y FPU.

ALU? FPU?

Entonces, las ALU y las FPU son los componentes lógicos que realmente hacen el trabajo duro de su procesador. Matemáticas, etc. Ingenuamente, suponemos que un núcleo tiene una ALU y una FPU, porque no es más que un núcleo y no puede estar haciendo dos cosas a la vez. ¿Correcto?

Así es como funcionó durante mucho tiempo hasta que las instrucciones SIMD entraron en la imagen.

SIMD: instrucción única, envío múltiple. En otras palabras, el núcleo de la CPU ahora era capaz de hacer un truco como “ejecutar la instrucción ADD (Instrucción única) contra estos 8 valores diferentes (Despacho múltiple) simultáneamente.

Entonces, los núcleos físicos evolucionaron para tener grupos de ALU y FPU, y comenzaron a usar el concepto de núcleos virtuales para mantenerse lo más ocupados posible. Quiero decir, si tienes ocho ALU y cuatro FPU en un solo núcleo de CPU, ¿por qué no agregar un poco de virtualización y falsificarla?

Pero espera, ¡esto mejora!

Mira, las instrucciones que envías a una CPU moderna no son en realidad las instrucciones que se ejecutan. Se descomponen en un conjunto de instrucciones internas que se envían de diferentes maneras: en algunos casos, se ejecutan en ciclos de reloj intercalados (o en el borde anterior o posterior de esos ciclos), o se quedan sin orden y se vuelven a montar, o se ejecutan en paralelo y luego ser expulsado por completo cuando el código se bifurca desde una ruta prevista.

… No entraré en las complejidades de la latencia de la memoria, la inconsistencia semántica en las operaciones concurrentes, y … y … y …

Así que sí. Una CPU con múltiples núcleos puede ejecutar un montón de instrucciones al mismo tiempo. ¿Cuántos? Bueno, eso es difícil de decir …

Para los procesadores x86 desde 8086 a través del chip Intel 486, los procesadores ejecutaron las instrucciones de una en una. Al conocer la frecuencia del reloj y el número de ciclos de reloj que tomó cada instrucción en lenguaje de máquina, podría predecir bastante bien cuánto tiempo tomaría un conjunto de instrucciones. Las mejoras en estos procesadores se centraron en reducir la cantidad de ciclos de reloj por instrucción, acelerar el reloj y acelerar el acceso a la memoria. Intel también lanzó 8087-487 “coprocesadores matemáticos” para estos chips que aumentaron la velocidad de las operaciones matemáticas de coma flotante. A pesar del nombre, los coprocesadores no permitieron la ejecución paralela de instrucciones.

Los procesadores originales Intel Pentium P5 cambiaron este patrón. Utilizaron el procesamiento Superscalar, lo que los convirtió en la primera generación de procesadores x86 que podían ejecutar pequeños conjuntos de instrucciones en múltiples conjuntos de datos simultáneamente. El Pentium Pro / II / III (P6) agregó otra técnica de paralelismo llamada ejecución fuera de orden. Esto le permite al procesador mirar hacia adelante para identificar las instrucciones que se le puede pedir que realice. Filtra esas instrucciones para identificar las instrucciones que se pueden realizar simultáneamente sin afectar los datos utilizados por otras instrucciones. Pre-ejecuta esas instrucciones antes de que el puntero de la instrucción realmente las alcance. Pentium 4 * y los chips más nuevos han vuelto a centrarse en una ejecución más rápida y un acceso más rápido a la memoria, y ahora incluyen múltiples procesadores en un solo Chip.

Las técnicas de procesamiento en paralelo mencionadas anteriormente son en gran medida transparentes para el sistema operativo y los programas en ejecución. Los chips multiprocesador (o placas base con múltiples chips) funcionan de manera diferente. Requieren que el sistema operativo mantenga una cola de instrucciones separada para cada procesador. Realmente operan “en paralelo”, permitiendo que cada procesador acceda a la memoria y los dispositivos IO de forma independiente.

Sin embargo, esa es solo la CPU. Hay muchos otros procesadores en una PC moderna. Los chips Northbridge, los chips Southbridge, los controladores IO, los discos duros y las unidades de CD-Rom ahora tienen sus propios procesadores funcionando en sus propias frecuencias de reloj ejecutándose de manera completamente independiente de la CPU principal. Las tarjetas de video también merecen una mención; No es raro que una buena tarjeta de video para juegos tenga cientos o miles de procesadores que puedan funcionar en paralelo.

HTH
Greene

* Advertencia: la vida sucedió en la era Pentium III y dejé de prestar mucha atención. Puede haber otras cosas interesantes que he echado de menos en las generaciones posteriores.

PD Publique un comentario si desea una explicación de subprocesos también. Interpreté la pregunta como un enfoque en el hardware.

Los sistemas multinúcleo son similares a tener múltiples CPU en su computadora (la única diferencia principal es que están en el mismo dado y también pueden beneficiarse de eso). Como resultado, cada núcleo se ejecuta “independientemente” del otro, el único punto común principal es que utilizan la misma fuente de energía y el mismo reloj para ejecutar, pero sí, cada núcleo que ejecuta su propio conjunto de instrucciones significa que la CPU puede ejecutar tantas instrucciones ” al mismo tiempo “ya que tiene núcleos.

Como Conrad Herrmann mencionó la canalización, o lo que a Intel le gusta llamar “hiper-threading” es un poco más complejo. Esto reside en un solo núcleo que solo puede ejecutar una secuencia de instrucciones. La cosa es que:

  1. la instrucción a menudo toma más de 1 ciclo ya que tienen que pasar por diferentes partes de procesamiento de la CPU
  2. muchas veces, el sistema operativo, al implementar tareas múltiples, puede dar un conjunto de instrucciones para que se ejecute a continuación (en lugar de solo el siguiente; tenga en cuenta que a veces incluso puede ser solo en el proceso en sí, donde alguna secuencia de instrucciones no es estricta en en cuyo caso ni siquiera se debe al sistema operativo, sino solo al compilador), por lo tanto, dejar la voz a la CPU para elegir qué hacer a continuación

Utilizando algoritmos de predicción complejos (implementados en la propia CPU), la CPU puede decidir cuál es la siguiente instrucción para comenzar, incluso si la anterior aún no se completó. Esto es más parecido a su intuición de “ilusión”. El procesamiento lleva tiempo, nada prohíbe que la CPU sea inteligente al iniciar una nueva instrucción, incluso cuando la anterior aún no se ha completado. Esto le da un poco de velocidad a medida que toda la tubería se deposita de manera más efectiva que “comenzar a ejecutar, esperar a que se complete, ejecutar el siguiente”.

Aún así, como puede ver en cualquier administrador de tareas del sistema operativo, su computadora ejecuta muchos más procesos (e incluso más subprocesos que deseen estos procesos) de los que tiene en su CPU (o incluso hiperprocesos). y para esto es solo una ilusión que el sistema operativo maneja. El sistema operativo gestiona la mayor parte del cambio entre subprocesos y procesos y, al hacerlo, da la ilusión a cada subproceso y procesos de que se ejecutan continuamente, mientras que, de hecho, a menudo se interrumpen para dar paso a otros subprocesos.

Para un procesador multinúcleo, es cierto que un conjunto de transistores está cambiando de estado para procesar y calcular una instrucción al mismo tiempo que otro conjunto de transistores está cambiando de estado para procesar y calcular otra instrucción.

De hecho, en arquitecturas ‘canalizadas’, incluso un solo núcleo está procesando múltiples instrucciones a la vez. Mientras una instrucción pasa por la etapa 3 de la tubería, otra instrucción puede estar en la etapa 2 y otra instrucción puede estar en la etapa 1.

Manteniéndolo simple.
En las CPU de varios núcleos, cada núcleo tiene algo de caché que contiene instrucciones y datos. Cuando esas instrucciones y datos están en uso, cada núcleo opera de manera bastante independiente de los demás. Un procesador de cuatro núcleos puede ser, y a menudo ejecuta cuatro programas e instrucciones al mismo tiempo.

Edite, por si acaso, y manténgalo simple: Caché significa una copia local de la memoria principal guardada dentro de la CPU. Una CPU de cuatro núcleos tiene cuatro cachés, uno para cada núcleo. Mantener el caché correcto y actualizado es bastante difícil y está más allá del alcance de la pregunta.