¿Qué hace un proceso de CPU inactivo?

73

Mirando la fuente de strace, encontré el uso de la bandera de clonación CLONE_IDLETASKque se describe allí como:

#define CLONE_IDLETASK 0x00001000 /* kernel-only flag */

Después de profundizar en él, descubrí que, aunque ese indicador no está cubierto man clone, el núcleo lo usa realmente durante el proceso de arranque para crear procesos inactivos (todos los cuales deberían tener PID 0) para cada CPU en la máquina. es decir, una máquina con 8 CPU tendrá al menos 7 (ver pregunta más abajo) tales procesos "en ejecución" (comillas).

Ahora, esto me lleva a un par de preguntas sobre qué hace realmente ese proceso "inactivo". Mi suposición es que ejecuta la operación NOP continuamente hasta que finaliza su período de tiempo y el núcleo asigna un proceso real para ejecutar o asignar el proceso inactivo una vez más (si la CPU no se está utilizando). Sin embargo, eso es una suposición completa. Entonces:

  1. En una máquina con, digamos, 8 CPU, ¿se crearán 7 procesos inactivos? (¿y el núcleo mismo tendrá una CPU mientras no se realice el trabajo en el espacio del usuario?)

  2. ¿Es el proceso inactivo realmente solo un flujo infinito de operaciones NOP? (o un bucle que hace lo mismo).

  3. ¿El uso de la CPU (por ejemplo uptime) simplemente se calcula por cuánto tiempo estuvo el proceso inactivo en la CPU y cuánto tiempo no estuvo allí durante un cierto período de tiempo?


PD: es probable que buena parte de esta pregunta se deba al hecho de que no entiendo completamente cómo funciona una CPU. es decir, entiendo el ensamblaje, los plazos y las interrupciones, pero no sé cómo, por ejemplo, una CPU puede usar más o menos energía dependiendo de lo que esté ejecutando. Estaría agradecido si alguien me puede iluminar sobre eso también.

grochmal
fuente
17
Tuve que resistir la tentación de escribir "Nada en absoluto" cuando vi el título.
Vality
44
La mayoría de las CPU modernas reducirán dinámicamente su frecuencia de reloj y consumo de energía cuando estén inactivas o bajo baja carga ( escala de frecuencia dinámica , por ejemplo, SpeedStep para CPU de Intel). Si overclockea una CPU, generalmente deshabilitará este comportamiento, haciendo que la CPU mantenga la velocidad de reloj máxima incluso cuando está inactiva.
Nat
2
Consulte también "Estados de alimentación de ACPI": hay varias formas en que un procesador puede dejar de ejecutar instrucciones pero aún así puede activarse.
pjc50

Respuestas:

85

La tarea inactiva se utiliza para la contabilidad de procesos y también para reducir el consumo de energía. En Linux, se crea una tarea inactiva para cada procesador y se bloquea en ese procesador; siempre que no haya otro proceso para ejecutarse en esa CPU, se programa la tarea inactiva. El tiempo dedicado a las tareas inactivas aparece como tiempo "inactivo" en herramientas como top. (El tiempo de actividad se calcula de manera diferente).

Parece que Unix siempre ha tenido un ciclo inactivo de algún tipo (pero no necesariamente una tarea inactiva real, vea la respuesta de Gilles ), e incluso en V1 usó una WAITinstrucción que detuvo el procesador hasta que se produjo una interrupción (significaba "espere interrumpir"). Algunos otros sistemas operativos utilizan bucles ocupados, DOS, OS / 2 y las primeras versiones de Windows en particular. Desde hace bastante tiempo, las CPU han utilizado este tipo de instrucciones de "espera" para reducir su consumo de energía y producción de calor. Puede ver varias implementaciones de tareas inactivas, por ejemplo, arch/x86/kernel/process.cen el kernel de Linux: la básica solo llamaHLT, que detiene el procesador hasta que se produce una interrupción (y habilita el modo de ahorro de energía C1), las otras implementaciones manejan varios errores o ineficiencias ( por ejemplo, el uso en MWAITlugar de HLTen algunas CPU).

Todo esto está completamente separado de los estados inactivos en los procesos, cuando están esperando un evento (E / S, etc.).

Stephen Kitt
fuente
3
Je, lo veo ahora, gracias. play_dead()es un nombre mnemotécnico muy bueno para ejecutar HALT. ¿No habría riesgo de enviar HALT a cada CPU y, en consecuencia, colgarse? (es decir, llegar a esa situación, HALT cada CPU, ¿sería un error en el núcleo correcto?)
grochmal
30
La CPU se activa desde HALT a través de una interrupción.
Johan Myréen
1
@ JohanMyréen - Genial, eso tiene sentido. En tal caso, incluso una interrupción de IRQ desde un dispositivo de entrada lo reactivaría. Gracias.
grochmal
15
O más confiablemente, el temporizador interrumpe ... (El manejo sin garrapatas es otro hervidor de pescado.)
Stephen Kitt
3
@EJP, de hecho, es una instrucción bastante común, a pesar de que tiene diferentes nombres en diferentes arquitecturas.
user253751
50

En el diseño del libro de texto de un planificador de procesos, si el planificador no tiene ningún proceso para programar (es decir, si todos los procesos están bloqueados, esperando la entrada), entonces el planificador espera una interrupción del procesador. La interrupción puede indicar la entrada de un periférico (acción del usuario, paquete de red, lectura completa de un disco, etc.) o puede ser una interrupción del temporizador que activa un temporizador en un proceso.

El planificador de Linux no tiene un código especial para un caso de nada que hacer. En cambio, codifica el caso de nada que hacer como un proceso especial, el proceso inactivo. El proceso inactivo solo se programa cuando ningún otro proceso es programable (tiene una prioridad infinitamente baja). El proceso inactivo es, de hecho, parte del núcleo: es un subproceso del núcleo, es decir, un subproceso que ejecuta código en el núcleo, en lugar de código en un proceso. (Más precisamente, hay un subproceso de este tipo para cada CPU). Cuando se ejecuta el proceso inactivo, realiza la operación de espera de interrupción.

El funcionamiento de la espera de interrupción depende de las capacidades del procesador. Con el diseño de procesador más básico, eso es solo un bucle ocupado:

nothing:
    goto nothing

El procesador sigue ejecutando una instrucción de bifurcación para siempre, que no logra nada. La mayoría de los sistemas operativos modernos no hacen esto a menos que se ejecuten en un procesador donde no hay nada mejor, y la mayoría de los procesadores tienen algo mejor. En lugar de gastar energía haciendo nada más que calentar la habitación, idealmente, el procesador debe estar apagado. Entonces, el kernel ejecuta un código que le indica al procesador que se apague solo, o al menos que apague la mayor parte del procesador. Debe haber al menos una pequeña parte que permanezca encendida, el controlador de interrupción. Cuando un periférico dispara una interrupción, el controlador de interrupción enviará una señal de activación al procesador (parte del) principal.

En la práctica, las CPU modernas como Intel / AMD y ARM tienen muchas configuraciones complejas de administración de energía. El sistema operativo puede estimar cuánto tiempo permanecerá el procesador en modo inactivo y elegirá diferentes modos de baja potencia dependiendo de esto. Los modos ofrecen diferentes compromisos entre el uso de energía mientras está inactivo y el tiempo que lleva entrar y salir del modo inactivo. En algunos procesadores, el sistema operativo también puede reducir la frecuencia de reloj del procesador cuando descubre que los procesos no consumen mucho tiempo de CPU.

Gilles 'SO- deja de ser malvado'
fuente
55
Tenga en cuenta que incluso las CPU integradas más básicas, como los microcontroladores basados ​​en AVR, tienen una instrucción WFI (Wait For Interrupt), aunque esa instrucción puede ser equivalente a NOP según el modelo exacto.
Jonas Schäfer
@JonasWielicki Pensé que por lo general solo entrarías en un circuito cerrado si no tenías nada que hacer, o podrías pasar a un estado de baja potencia y esperar a que la interrupción te elimine (los estados de menor potencia generalmente requieren más " interrupciones de metal ").
Nick T
1
@JonasWielicki Las arquitecturas diseñadas para sistemas integrados se preocupan por la administración de energía, por lo que WFI es importante allí. Muchas arquitecturas antiguas no tienen tal cosa. La arquitectura original 8086 no, AFAIR. ¿68k tiene WFI? ¿Es una característica estándar en MIPS? Mi familiaridad con la programación de bajo nivel se basa principalmente en ARM, donde el bajo consumo de energía es algo normal y WFI es solo la punta del iceberg de administración de energía.
Gilles 'SO- deja de ser malvado'
1
@Gilles 8086 tuvo una instrucción de alto. Ver en.m.wikipedia.org/wiki/HLT_(x86_instruction) La instrucción incluyó la funcionalidad de ahorro de energía solo desde 80486 DX4. Mirando hacia atrás en la historia, HLT ya estaba en 8080 y derivados (como Z80).
pabouk
1
@pabouk HLTpodría apagar las variantes SL del 386 y 486, antes de que saliera el DX4 (el artículo de Wikipedia es incorrecto).
Stephen Kitt
0

No, una tarea inactiva no desperdicia los ciclos de la CPU. El planificador simplemente no selecciona un proceso inactivo para su ejecución. Un proceso inactivo está esperando que ocurra algún evento para que pueda continuar. Por ejemplo, puede estar esperando la entrada en una read()llamada al sistema.

Por cierto, el núcleo no es un proceso separado. El código del kernel siempre se ejecuta en el contexto de un proceso (bueno, excepto en el caso especial de un hilo del kernel), por lo que no es correcto decir "y una CPU estará en el kernel mientras no se realice el trabajo en el espacio del usuario".

Johan Myréen
fuente
3
Hmmm ... no creo que sea el tipo de proceso inactivo creado por CLONE_IDLETASK. Si hubiera sido así, no necesitaría crearse en absoluto, es decir, si el programador hubiera ignorado los procesos inactivos del kernel en las CPU, no necesitaría crear ningún proceso para ellos durante el arranque. (el DW no es mío :))
grochmal
Una pequeña búsqueda en Google revela que CLONE_IDLETASK es un indicador interno del núcleo que se introdujo alrededor de la versión 2.5.14 del núcleo en 2002 y luego se eliminó en 2004.
Johan Myréen
"un" proceso inactivo pero no " el " proceso inactivo.
user253751