¿Cómo puedo tener 1805 subprocesos cuando solo tengo 4 CPU virtuales?

10

Me preguntaba si alguien podría explicarme cómo en mi Monitor de actividad dice que actualmente tengo 1805 hilos Captura de pantalla de OS X Activity Monitor

Pero solo tengo 4 núcleos virtuales en mi computadora (lo que significa que solo debería poder tener 4 hilos). ¿El recuento de subprocesos significa todos los subprocesos que las CPU manejan cuando deciden qué subproceso ejecutar?

EDITAR: La razón por la que creo que solo puede haber 4 hilos en mi máquina proviene de esta respuesta . Creo que mi malentendido proviene de la palabra 'hilo' que se usa en un contexto diferente.

Almohada Amarilla
fuente
Los comentarios no son para discusión extendida; Esta conversación se ha movido al chat .
bmike

Respuestas:

24

Planificación

Sus 1,805 hilos no se ejecutan simultáneamente . Ellos intercambian. Un núcleo ejecuta un poco del hilo, luego lo pone a un lado para ejecutar un poco de otro hilo. Los otros núcleos hacen lo mismo. Vueltas y vueltas, los hilos se ejecutan poco a poco, no todos a la vez.

Una de las principales responsabilidades del sistema operativo (Darwin y macOS) es la programación de qué subproceso se ejecutará en qué núcleo durante cuánto tiempo.

Muchos subprocesos no tienen trabajo que hacer, por lo que quedan inactivos y no programados. Del mismo modo, muchos subprocesos pueden estar esperando algún recurso, como los datos que se recuperarán del almacenamiento, o que se completará una conexión de red o que los datos se cargarán desde una base de datos. Con casi nada que hacer más que verificar el estado del recurso esperado, dichos hilos se programan de manera bastante breve, si es que lo hacen.

El programador de la aplicación puede ayudar a esta operación de programación durmiendo su hilo durante un cierto tiempo cuando sabe que la espera del recurso externo tomará algún tiempo. Y si ejecuta un bucle "apretado" que requiere mucha CPU sin causa para esperar recursos externos, el programador puede insertar una llamada para ofrecerse como voluntario para que se deje de lado brevemente para no acaparar el núcleo y permitir que otros hilos se ejecuten.

Para obtener más detalles, consulte la página de Wikipedia para subprocesos múltiples .

Multi-Threading simultáneo

En cuanto a su pregunta vinculada , los hilos allí son de hecho los mismos que aquí.

Un problema es el costo general de cambiar entre hilos cuando lo programa el sistema operativo. Hay un costo significativo en tiempo para descargar las instrucciones y los datos del hilo actual desde el núcleo y luego cargar las instrucciones y los datos del siguiente hilo programado. Parte del trabajo del sistema operativo es tratar de ser inteligente al programar los subprocesos para optimizar alrededor de este costo general.

Algunos fabricantes de CPU han desarrollado tecnología para reducir este tiempo y hacer que el cambio entre un par de hilos sea mucho más rápido. Intel llama a su tecnología Hyper-Threading . Conocido genéricamente como subprocesamiento múltiple simultáneo (SMT) .

Si bien el par de subprocesos en realidad no se ejecuta simultáneamente, el cambio es tan suave y rápido que ambos subprocesos parecen ser prácticamente simultáneos. Esto funciona tan bien que cada núcleo se presenta como un par de núcleos virtuales para el sistema operativo. Entonces, una CPU habilitada para SMT con cuatro núcleos físicos, por ejemplo, se presentará al sistema operativo como una CPU de ocho núcleos.

A pesar de esta optimización, todavía hay algunos gastos generales para cambiar entre estos núcleos virtuales. Demasiados subprocesos con uso intensivo de la CPU, todos clamando por el tiempo de ejecución que se programará en un núcleo, pueden hacer que el sistema sea ineficiente, ya que ningún subproceso realiza mucho trabajo. Como tres pelotas en un patio de recreo que se comparten entre nueve niños, en comparación con compartir entre novecientos niños donde ningún niño realmente tiene tiempo de juego serio con una pelota.

Por lo tanto, hay una opción en el firmware de la CPU donde un administrador de sistemas puede activar un interruptor en la máquina para deshabilitar SMT si decide que beneficiaría a sus usuarios que ejecutan una aplicación que está inusualmente vinculada a la CPU con muy pocas oportunidades de pausa.

En tal caso, volveremos a su pregunta original: en esta situación especial, de hecho, querría restringir las operaciones para que no tengan más de estos hilos hiperactivos que los núcleos físicos. Pero permítanme repetir: esta es una situación extremadamente inusual que podría ocurrir en algo así como un proyecto especializado de procesamiento de datos científicos, pero que casi nunca se aplicaría a escenarios comerciales / corporativos / empresariales comunes.

Albahaca Bourque
fuente
Los comentarios no son para discusión extendida; Esta conversación se ha movido al chat .
bmike
Además, nadie pone yield()llamadas al sistema en sus hilos intensivos de CPU (a menos que sea un código heredado de la multitarea cooperativa en MacOS clásico). La multitarea preventiva reprograma después de que un subproceso agota su división de tiempo.
Peter Cordes el
Su descripción de hyperthreading es incorrecta. Hilos de hardware! = Hilos de software, son contextos de ejecución / núcleos lógicos. Ambos núcleos lógicos en un núcleo físico realmente ejecutan sus instrucciones al mismo tiempo. El front-end alterna entre hilos (cada ciclo), pero el núcleo de ejecución fuera de orden puede ejecutar instrucciones / uops de ambos hilos en el mismo ciclo. Esto expone el paralelismo a nivel de instrucción de dos subprocesos a la ejecución de OoO para mantener mejor las unidades de ejecución alimentadas con trabajo (este es básicamente el punto de SMT). No es solo "cambio de contexto optimizado".
Peter Cordes el
en.wikipedia.org/wiki/Hyper-threading tiene un diagrama. Ver también el genérico en.wikipedia.org/wiki/Sim simultáneo_multithreading
Peter Cordes
7

En los viejos tiempos, la memoria no estaba virtualizada o protegida y cualquier código podía escribir en cualquier lugar. En aquellos días, un diseño de CPU de un hilo a uno tenía sentido. En las décadas posteriores a eso, la memoria se protegió primero y luego se virtualizó. Piense en los subprocesos como núcleos virtuales, una especie de promesa de que en algún momento cuando sus datos y código estaban listos, ese subproceso es empujado ( o programado como lo llaman los ingenieros y matemáticos de PHD que investigan sobre algoritmos de programación ) en una CPU real para hacer trabajo real

ingrese la descripción de la imagen aquí

Ahora, debido a la magnitud de la diferencia en el tiempo, la CPU y el caché funcionan tan rápido en comparación con la obtención de datos del almacenamiento o la red, que miles de hilos podrían ir y venir mientras un hilo espera que www.google.com entregue un paquete o dos de datos, entonces esa es la razón por la que ve tantos hilos más que la CPU real.

Si convierte las operaciones de subproceso que suceden en la escala de tiempo negro / azul y las convierte a un segundo = 1 ns, las cosas que nos interesan son más como un disco IO que toma 100 microsegundos son como 4 días y un viaje de ida y vuelta a Internet de 200 ms es un Retraso de 20 años si cuenta segundos en la escala de tiempo de la CPU. Al igual que muchas potencias de diez ejercicios , en casi todos los casos, la CPU permanece inactiva durante "meses" esperando un trabajo significativo de un mundo externo muy, muy lento.

Nada parece estar mal en la imagen que publicaste, por lo que quizás no entendamos a qué te estás preguntando sobre los hilos.

Si hace clic con el botón derecho (clic de control) en los hilos de palabras en la fila del encabezado en la parte superior, agregue el estado de la aplicación y verá que la mayoría de los hilos probablemente estén inactivos, inactivos, sin ejecutarse en un momento dado.

bmike
fuente
Los comentarios no son para discusión extendida; Esta conversación se ha movido al chat .
bmike
1

No se hace la pregunta posiblemente más fundamental: "¿Cómo puedo tener 290 procesos cuando mi CPU solo tiene cuatro núcleos?" Esta respuesta es un poco de historia, lo que podría ayudarlo a comprender el panorama general, a pesar de que la pregunta específica ya ha sido respondida. Como tal, no voy a dar una versión TL; DR.

Érase una vez (piense, de 1950 a 1960), las computadoras solo podían hacer una cosa a la vez. Eran muy caros, llenaban habitaciones enteras, y necesitábamos una manera de hacer un uso eficiente de ellos compartiéndolos entre varias personas. La primera forma de hacerlo era el procesamiento por lotes , en el que los usuarios enviaban tareas a la computadora y se ponían en cola, se ejecutaban una tras otra y los resultados se enviaban de vuelta al usuario. Eso estuvo bien, pero significaba que, si deseaba hacer un cálculo que tomaría un par de días, nadie más podría usar la computadora durante ese tiempo.

La siguiente innovación (piense, 1960-70) fue el tiempo compartido . Ahora, en lugar de ejecutar la totalidad de una tarea, luego la totalidad de la siguiente, la computadora ejecutará un poco de una tarea, luego hará una pausa y ejecutará un poco de la siguiente, y así sucesivamente. Por lo tanto, la computadora daría la impresión de que estaba ejecutando múltiples procesos al mismo tiempo. La gran ventaja de esto es que ahora puede ejecutar un cálculo que tomará un par de días y, aunque ahora tomará aún más tiempo, porque se sigue interrumpiendo, otras personas aún pueden usar la máquina durante ese tiempo.

Todo esto fue para enormes computadoras de estilo mainframe. Cuando las computadoras personales comenzaron a ser populares, inicialmente no eran muy potentes y, hey, dado que eran personales , parecía correcto que solo pudieran hacer una cosa & nbdp; ejecutar una aplicación a la vez (piense en la década de 1980). Pero, a medida que se volvieron más poderosos (piense, de los años 90 al presente), la gente también quería que sus computadoras personales compartieran el tiempo.

Así que terminamos con computadoras personales que daban la ilusión de ejecutar múltiples procesos simultáneamente, ejecutándolos uno a la vez por breves períodos y luego pausándolos. Los hilos son esencialmente lo mismo: eventualmente, las personas querían incluso procesos individuales para dar la ilusión de hacer varias cosas al mismo tiempo. Al principio, el escritor de la aplicación tenía que manejar eso: gastar un poco mientras actualizaba los gráficos, pausar eso, gastar un poco mientras calculaba, pausar eso, gastar un poco mientras hacía otra cosa ...

Sin embargo, el sistema operativo ya era bueno en la gestión de múltiples procesos, tenía sentido extenderlo para administrar estos subprocesos, que se denominan subprocesos. Entonces, ahora, tenemos un modelo donde cada proceso (o aplicación) contiene al menos un hilo, pero algunos contienen varios o muchos. Cada uno de estos hilos corresponde a una subtarea algo independiente.

Pero, en el nivel superior, la CPU solo da la ilusión de que todos estos hilos se están ejecutando al mismo tiempo. En realidad, está ejecutando uno por un momento, pausándolo, eligiendo otro para ejecutar por un momento, y así sucesivamente. Excepto que las CPU modernas pueden ejecutar más de un hilo a la vez. Entonces, en la realidad real , el sistema operativo está jugando este juego de "correr por un momento, pausar, ejecutar algo más por un momento, pausar" en todos los núcleos simultáneamente. Por lo tanto, puede tener tantos subprocesos como desee (y los diseñadores de sus aplicaciones), pero, en cualquier momento, todos menos algunos se detendrán.

David Richerby
fuente