web-dev-qa-db-fra.com

Comment l'utilisation du processeur est-elle calculée?

Sur mon bureau, j'ai un petit widget qui me dit mon utilisation actuelle du processeur. Il montre également l'utilisation de chacun de mes deux cœurs. 

Je me suis toujours demandé comment le processeur calcule combien de sa puissance de traitement est utilisée? En outre, si le processeur est suspendu pour effectuer des calculs intenses, comment peut-il (ou quel que soit le système en charge de cette activité) examiner l'utilisation sans utiliser le processus?

63
Chris Laplante

Le processeur ne fait pas les calculs d'utilisation par lui-même. Il peut avoir des fonctionnalités matérielles pour rendre cette tâche plus facile, mais c'est principalement le travail du système d'exploitation. Il est donc évident que les détails des implémentations varieront (en particulier dans le cas de systèmes multicœurs).

L'idée générale est de voir combien de temps la file d'attente des tâches que le processeur doit effectuer est longue. Le système d'exploitation peut consulter périodiquement le planificateur pour déterminer le nombre de tâches à effectuer. 

Ceci est une fonction Linux en (extraite de Wikipedia) qui effectue ledit calcul :

#define FSHIFT   11  /* nr of bits of precision */
#define FIXED_1  (1<<FSHIFT) /* 1.0 as fixed-point */
#define LOAD_FREQ (5*HZ) /* 5 sec intervals */
#define EXP_1  1884  /* 1/exp(5sec/1min) as fixed-point */
#define EXP_5  2014  /* 1/exp(5sec/5min) */
#define EXP_15 2037  /* 1/exp(5sec/15min) */

#define CALC_LOAD(load,exp,n) \
    load *= exp; \
    load += n*(FIXED_1-exp); \
    load >>= FSHIFT;

unsigned long avenrun[3];

static inline void calc_load(unsigned long ticks)
{
    unsigned long active_tasks; /* fixed-point */
    static int count = LOAD_FREQ;

    count -= ticks;
    if (count < 0) {
        count += LOAD_FREQ;
        active_tasks = count_active_tasks();
        CALC_LOAD(avenrun[0], EXP_1, active_tasks);
        CALC_LOAD(avenrun[1], EXP_5, active_tasks);
        CALC_LOAD(avenrun[2], EXP_15, active_tasks);
    }
}

En ce qui concerne la deuxième partie de votre question, la plupart des systèmes d'exploitation modernes sont multi-tâches . Cela signifie que le système d'exploitation ne laissera pas les programmes prendre tout le temps de traitement et n'en ont pas pour lui-même (à moins que vous ne le laissiez faire) . En d’autres termes, même si une application semble bloquée, le système d’exploitation peut still voler du temps pour son propre travail. 

28
In silico

Une tâche spéciale appelée tâche inactive s'exécute lorsqu'aucune autre tâche ne peut être exécutée. Le pourcentage d'utilisation est simplement le pourcentage de temps pendant lequel nous n'exécutons pas la tâche inactive. Le système d'exploitation conservera le total du temps passé à exécuter la tâche inactive:

  • lorsque nous passons à la tâche inactive, définissez t = heure actuelle
  • lorsque nous nous éloignons de la tâche inactive, ajoutons (heure actuelle - t) au total cumulé

Si nous prenons deux échantillons du total cumulé à n secondes d'intervalle, nous pouvons calculer le pourcentage des n secondes passées à exécuter la tâche inactive sous la forme (deuxième échantillon - premier échantillon)/n

Notez que c'est quelque chose que le système d'exploitation fait, pas le processeur. Le concept de tâche n'existe pas au niveau du processeur! (En pratique, la tâche inactive va mettre le processeur en veille avec une instruction HLT afin que le processeur sache quand il n'est pas utilisé.)

Concernant la deuxième question, les systèmes d’exploitation modernes sont multi-tâches préventives, ce qui signifie que le système d’exploitation peut s’écarter de votre tâche à tout moment. Comment le système d'exploitation vole-t-il réellement le processeur de votre tâche? Interruptions: http://en.wikipedia.org/wiki/Interrupt

60
dave

Pour obtenir une utilisation du processeur, spécifiez périodiquement le temps de traitement total et recherchez la différence.

Par exemple, s’il s’agit des temps de calcul du processus 1:

kernel: 1:00:00.0000
user:   9:00:00.0000

Et puis vous les récupérez deux secondes plus tard, et ils sont:

kernel: 1:00:00.0300
user:   9:00:00.6100

Vous soustrayez les durées du noyau (pour une différence de 0.03) et les durées de l'utilisateur (0.61), ajoutez-les ensemble (0.64) et divisez-les par le temps-échantillon de 2 secondes (0.32).

Ainsi, au cours des deux dernières secondes, le processus a utilisé en moyenne 32% de temps processeur.

Les appels système spécifiques nécessaires pour obtenir cette information sont (évidemment) différents sur chaque plate-forme. Sous Windows, vous pouvez utiliser GetProcessTimes ou GetSystemTimes si vous voulez un raccourci vers total utilisé ou le temps CPU inactif.

12
zildjohn01

Une façon de le faire est la suivante:

Choisissez un intervalle d'échantillonnage, par exemple toutes les 5 min (300 secondes) du temps réellement écoulé. Vous pouvez l'obtenir à partir de gettimeofday

Obtenez le temps de traitement que vous avez utilisé en 300 secondes. Vous pouvez utiliser l'appel times() pour l'obtenir. Ce serait le new_process_time - old_process_time, où old_process_time est le temps de traitement que vous avez enregistré à partir du dernier intervalle de temps.

Votre pourcentage de CPU est alors (process_time/elapsed_time)*100.0Vous pouvez définir une alarme pour vous avertir toutes les 300 secondes pour effectuer ces calculs. 

J'ai un processus que je ne veux pas utiliser plus qu'un certain pourcentage de cpu cible. Cette méthode fonctionne plutôt bien et s’accorde bien avec mon moniteur système. Si nous utilisons trop de CPU, nous dormons un peu. 

7
user1725779

Ceci est ma compréhension de base d'avoir un peu d'exposition à un code similaire. Des programmes tels que Task Manager ou vos widgets accèdent à des appels système tels que NtQuerySystemInformation () et utilisent les informations collectées à partir du système d'exploitation pour calculer simplement le pourcentage de temps pendant lequel une CPU est inactive ou utilisée (dans un laps de temps standard). Un CPU sait quand il est inactif et peut donc déterminer quand il ne l'est pas. Ces programmes peuvent en effet se boucher ... Le Gestionnaire des tâches de mon ordinateur portable minable se bloque constamment lors du calcul de l'utilisation du processeur lorsqu'il atteint 100%. 

Vous trouverez sur le site Web de MSDN un bon exemple de code présentant les appels de fonction permettant de calculer l'utilisation du processeur pour un ensemble d'instructions: http://msdn.Microsoft.com/en-us/library/aa364157(VS.85) .aspx

Ce que ces appels système font, c'est accéder au code du noyau, je crois ... ce qui dépasse le cadre de ma compréhension.

2
AndyG

vous pouvez le faire de différentes manières:

Le processeur maintient plusieurs compteurs qui mesurent les performances, vous pouvez y accéder en utilisant l'interface Papi. par exemple, voici une brève introduction: http://blogs.Oracle.com/jonh/entry/performance_counter_generic_events

aussi: http://www.drdobbs.com/tools/184406109

le compteur que vous voudrez peut-être est PAPI_TOT_CYC qui correspond au nombre de cycles occupés (si je me souviens bien)

1
Anycorn

Eh bien, autant que je sache, il y a un géant 

while(true){}

boucle que les systèmes d'exploitation tourne. Votre processus est géré depuis cette boucle. Il permet d'exécuter le code externe directement sur le processeur en morceaux. Sans trop exagérer, il s’agit d’une très grande simplification de la réalité.

0
Gleno
  1. Le processeur ne se bloque pas, il fonctionne simplement à pleine capacité, ce qui signifie qu'il traite autant d'instructions qu'il en est capable physiquement à chaque seconde ... Le processus qui calcule l'utilisation du processeur fait partie de ces instructions. Si les applications tentent d'effectuer des opérations plus rapidement que le processeur ne le permet, elles seront tout simplement retardées, d'où le «blocage».

  2. Le calcul de l'utilisation de l'UC est basé sur l'utilisation totale disponible. Ainsi, si un processeur a deux cœurs, et qu'un cœur utilise 30%, et l'autre 60%, l'utilisation globale est de 45%. Vous pouvez également voir l'utilisation de chaque noyau individuel.

0
Aashishkebab