web-dev-qa-db-fra.com

Que fait un processus CPU inactif?

En regardant la source de strace j'ai trouvé l'utilisation de l'indicateur de clone CLONE_IDLETASK qui y est décrit comme:

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

Après y avoir approfondi, j'ai constaté que, bien que ce drapeau ne soit pas couvert par man clone il est en fait utilisé par le noyau pendant le processus de démarrage pour créer des processus inactifs (qui devraient tous avoir un PID 0) pour chaque CPU de la machine. c'est-à-dire qu'une machine avec 8 CPU aura au moins 7 (voir la question ci-dessous) de tels processus "en cours d'exécution" (notez les guillemets).

Maintenant, cela m'amène à quelques questions sur ce que fait réellement ce processus "inactif". Mon hypothèse est qu'il exécute l'opération NOP en continu jusqu'à la fin de son échéance et que le noyau assigne un processus réel à exécuter ou attribue à nouveau le processus inactif (si le CPU n'est pas utilisé). Pourtant, c'est une supposition complète. Donc:

  1. Sur une machine avec, disons, 8 CPU, 7 de ces processus inactifs seront-ils créés? (et un processeur sera détenu par le noyau lui-même sans aucun travail dans l'espace utilisateur?)

  2. Le processus inactif est-il vraiment juste un flux infini d'opérations NOP? (ou une boucle qui fait de même).

  3. L'utilisation du processeur (par exemple uptime) est-elle simplement calculée en fonction de la durée du processus d'inactivité sur le processeur et de la durée pendant laquelle il n'a pas été présent pendant une certaine période de temps?


P.S. Il est probable qu'une bonne partie de cette question soit due au fait que je ne comprends pas complètement comment fonctionne un CPU. c'est-à-dire que je comprends l'assemblage, les délais et les interruptions mais je ne sais pas comment, par exemple, un CPU peut utiliser plus ou moins d'énergie en fonction de ce qu'il exécute. Je serais reconnaissant si quelqu'un pouvait aussi m'éclairer là-dessus.

75
grochmal

La tâche inactive est utilisée pour la comptabilité des processus et également pour réduire la consommation d'énergie. Sous Linux, une tâche inactive est créée pour chaque processeur et verrouillée sur ce processeur; chaque fois qu'il n'y a aucun autre processus à exécuter sur ce processeur, la tâche inactive est planifiée. Le temps passé dans les tâches inactives apparaît comme du temps "inactif" dans des outils tels que top. (La disponibilité est calculée différemment.)

Unix semble avoir toujours eu une boucle inactive quelconque (mais pas nécessairement une tâche inactive réelle, voir réponse de Gilles ), et même dans V1 il utilisait un WAIT instruction qui a arrêté le processeur jusqu'à ce qu'une interruption se produise (il représentait "attendre l'interruption"). Certains autres systèmes d'exploitation utilisaient des boucles occupées, DOS, OS/2 , et les premières versions de Windows en particulier. Depuis assez longtemps, les CPU utilisent ce type d'instruction "d'attente" pour réduire leur consommation d'énergie et leur production de chaleur. Vous pouvez voir diverses implémentations de tâches inactives, par exemple dans Arch/x86/kernel/process.c dans le noyau Linux: le basique appelle juste HLT , qui arrête le processeur jusqu'à ce qu'une interruption se produise (et active le mode d'économie d'énergie C1), l'autre les implémentations gèrent divers bogues ou inefficacités ( par exemple en utilisant MWAIT au lieu de HLT sur certains CPU).

Tout cela est complètement distinct des états inactifs dans les processus, lorsqu'ils attendent un événement (E/S, etc.).

88
Stephen Kitt

Dans la conception classique d'un ordonnanceur de processus, si l'ordonnanceur n'a aucun processus à planifier (c'est-à-dire si tous les processus sont bloqués, en attente d'entrée), alors l'ordonnanceur attend une interruption du processeur. L'interruption peut indiquer une entrée à partir d'un périphérique (action de l'utilisateur, paquet réseau, lecture terminée à partir d'un disque, etc.) ou peut être une interruption de temporisation qui déclenche une temporisation dans un processus.

L'ordonnanceur de Linux n'a pas de code spécial pour un cas rien à faire. Au lieu de cela, il code le cas de rien à faire en tant que processus spécial, le processus inactif. Le processus inactif n'est planifié que si aucun autre processus n'est planifiable (il a effectivement une priorité infiniment basse). Le processus inactif fait en fait partie du noyau: c'est un thread du noyau, c'est-à-dire un thread qui exécute du code dans le noyau, plutôt que du code dans un processus. (Plus précisément, il existe un tel thread pour chaque CPU.) Lorsque le processus inactif s'exécute, il effectue l'opération d'attente d'interruption.

Le fonctionnement de l'attente d'interruption dépend des capacités du processeur. Avec la conception de processeur la plus basique, ce n'est qu'une boucle occupée -

nothing:
    goto nothing

Le processeur continue d'exécuter une instruction de branche pour toujours, ce qui ne fait rien. La plupart des systèmes d'exploitation modernes ne font cela que s'ils fonctionnent sur un processeur où il n'y a rien de mieux, et la plupart des processeurs ont quelque chose de mieux. Plutôt que de dépenser de l'énergie sans rien faire d'autre que chauffer la pièce, le processeur devrait idéalement être éteint. Ainsi, le noyau exécute du code qui demande au processeur de s'éteindre lui-même, ou du moins de désactiver la plupart du processeur. Il doit y avoir au moins une petite pièce qui reste sous tension, le contrôleur d'interruption. Lorsqu'un périphérique déclenche une interruption, le contrôleur d'interruption enverra un signal de réveil au processeur principal (partie) du processeur.

Dans la pratique, les processeurs modernes tels que Intel/AMD et ARM ont de nombreux paramètres de gestion de l'alimentation complexes. Le système d'exploitation peut estimer la durée pendant laquelle le processeur restera en mode veille et choisira différents modes de faible consommation d'énergie. en fonction de cela. Les modes offrent différents compromis entre la consommation d'énergie en mode inactif et le temps nécessaire pour entrer et sortir du mode inactif. Sur certains processeurs, le système d'exploitation peut également réduire la fréquence d'horloge du processeur lorsqu'il constate que les processus ne sont pas consommant beaucoup de temps CPU.

Non, une tâche inactive ne gaspille pas les cycles CPU. Le planificateur ne sélectionne tout simplement pas un processus inactif pour l'exécution. Un processus inactif attend qu'un événement se produise pour pouvoir continuer. Par exemple, il peut être en attente de saisie dans un appel système read().

Soit dit en passant, le noyau n'est pas un processus distinct. Le code du noyau est toujours exécuté dans le contexte d'un processus (enfin, sauf dans le cas spécial d'un thread du noyau), il n'est donc pas correct de dire "et un processeur sera détenu par le noyau lui-même sans aucun travail dans l'espace utilisateur".

0
Johan Myréen