it-swarm-eu.dev

Come viene calcolato l'utilizzo della CPU?

Sul mio desktop, ho un piccolo widget che mi dice il mio attuale utilizzo della CPU. Mostra anche l'utilizzo per ciascuno dei miei due core. 

Mi sono sempre chiesto, in che modo la CPU calcola quanta parte della sua potenza di elaborazione viene utilizzata? Inoltre, se la CPU è riagganciata facendo alcuni calcoli intensi, come può (o qualsiasi altra cosa gestisca questa attività) esaminare l'utilizzo, senza rimanere appeso?

63
Chris Laplante

La CPU non esegue autonomamente i calcoli di utilizzo. Può avere caratteristiche hardware per rendere più semplice tale compito, ma è soprattutto il lavoro del sistema operativo. Quindi ovviamente i dettagli delle implementazioni varieranno (specialmente nel caso di sistemi multicore).

L'idea generale è di vedere quanto è lunga la coda delle cose che la CPU deve fare. Il sistema operativo può controllare periodicamente lo scheduler per determinare il numero di cose che deve fare. 

Questa è una funzione di Linux in (strappato da Wikipedia) che esegue detto calcolo :

#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);
    }
}

Per quanto riguarda la seconda parte della tua domanda, i sistemi operativi più moderni sono multi-tasking . Ciò significa che il sistema operativo non lascerà che i programmi occupino tutto il tempo di elaborazione e non ne abbiano alcuno per sé (a meno che tu non lo faccia fare) . In altre parole, anche se un'applicazione sembra bloccata, il sistema operativo può ancora rubare un po 'di tempo per il proprio lavoro. 

28
In silico

Esiste un'attività speciale denominata attività inattiva che viene eseguita quando non è possibile eseguire altre attività. L'utilizzo% è solo la percentuale del tempo in cui non eseguiamo l'attività inattiva. Il sistema operativo manterrà un totale parziale del tempo impiegato per eseguire l'attività inattiva:

  • quando passiamo al compito inattivo, impostiamo t = ora corrente
  • quando si passa dall'attività inattiva, aggiungere (ora corrente - t) al totale parziale

Se prendiamo due campioni del totale parziale n secondi tra loro, possiamo calcolare la percentuale di quei n secondi spesi nell'esecuzione dell'attività inattiva come (secondo campione - primo campione)/n

Si noti che questo è qualcosa che fa il sistema operativo, non la CPU. Il concetto di un'attività non esiste a livello di CPU! (In pratica, il task inattivo mette il processore in stop con un'istruzione HLT, quindi la CPU sa quando non viene utilizzata)

Per quanto riguarda la seconda domanda, i sistemi operativi moderni sono prepotentemente multi-tasking, il che significa che il sistema operativo può abbandonare il tuo compito in qualsiasi momento. In che modo il sistema operativo in realtà ruba la CPU dal tuo compito? Interrupt: http://en.wikipedia.org/wiki/Interrupt

60
dave

Per ottenere l'utilizzo della CPU, campionare periodicamente il tempo di elaborazione total e trovare la differenza.

Ad esempio, se questi sono i tempi della CPU per il processo 1:

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

E poi li ottieni di nuovo due secondi dopo, e sono:

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

Sottrai le ore del kernel (per una differenza di 0.03) e le volte utente (0.61), le aggiungi (0.64) e dividi per il tempo di campionamento di 2 secondi (0.32).

Quindi negli ultimi due secondi, il processo ha utilizzato una media del 32% del tempo di CPU.

Le chiamate di sistema specifiche necessarie per ottenere queste informazioni sono (ovviamente) diverse su ogni piattaforma. Su Windows, è possibile utilizzare GetProcessTimes , o GetSystemTimes se si desidera un collegamento a total utilizzato o tempo di CPU inattivo.

12
zildjohn01

Un modo per farlo è il seguente:

Scegli un intervallo di campionamento, diciamo ogni 5 minuti (300 secondi) di tempo reale trascorso. Puoi ottenere questo da gettimeofday

Ottieni il tempo di elaborazione che hai utilizzato in quei 300 secondi. Puoi usare la chiamata times() per ottenere questo. Quello sarebbe il new_process_time - old_process_time, dove old_process_time è il tempo di processo che hai salvato dall'ultimo intervallo di tempo.

La percentuale della CPU è quindi (process_time/elapsed_time)*100.0È possibile impostare un allarme per segnalare ogni 300 secondi di effettuare questi calcoli. 

Ho un processo che non voglio usare più di una determinata percentuale di CPU target. Questo metodo funziona piuttosto bene e concorda bene con il mio monitor di sistema. Se usiamo troppa CPU, dormiamo un po '. 

7
user1725779

Questa è la mia comprensione di base per avere una piccola esposizione a codice simile. Programmi come Task Manager o il tuo sistema di accesso ai widget chiamate come NtQuerySystemInformation () e utilizzano le informazioni raccolte dal sistema operativo per fare il semplice calcolo della percentuale di tempo in cui una CPU è inattiva o in uso (in un intervallo di tempo standard). Una CPU sa quando è inattiva, quindi può determinare quando non è inattiva. Questi programmi possono infatti essere intasati ... Il Task Manager del mio computer portatile scadente si blocca sempre quando calcola l'utilizzo della CPU quando è al 100%. 

Un bel po 'di codice di esempio può essere trovato sul sito Web di MSDN che mostra le chiamate di funzione per il calcolo dell'utilizzo della CPU per una serie di istruzioni: http://msdn.Microsoft.com/en-us/library/aa364157(VS.85) .aspx

Quello che fanno queste chiamate di sistema è l'accesso al codice del kernel, credo ... che va oltre lo scopo della mia comprensione.

2
AndyG

ci sono molti modi in cui puoi farlo:

Il processore mantiene diversi contatori che misurano le prestazioni, è possibile accedervi utilizzando l'interfaccia Papi. per esempio ecco una breve introduzione: http://blogs.Oracle.com/jonh/entry/performance_counter_generic_events

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

il contatore che si desidera è PAPI_TOT_CYC, che è il numero di cicli occupati (se non ricordo male)

1
Anycorn

Bene, per quanto ne so, c'è un gigante 

while(true){}

loop che i sistemi operativi fanno girare. Il tuo processo è gestito da quel ciclo. Permette di eseguire codice esterno direttamente sul processore in blocchi. Senza esagerare troppo, questa è una super semplificazione di ciò che sta realmente accadendo.

0
Gleno
  1. La CPU non si "blocca", funziona semplicemente al massimo della capacità, il che significa che sta elaborando tante istruzioni quanto è fisicamente capace ogni secondo . Il processo che sta calcolando l'utilizzo della CPU è alcune di quelle istruzioni. Se le applicazioni cercano di eseguire operazioni più velocemente di quanto la CPU sia in grado, allora saranno semplicemente posticipate, quindi "riagganciate".

  2. Il calcolo dell'utilizzo della CPU si basa sull'utilizzo totale disponibile. Quindi se una CPU ha due core e un core ha il 30% di utilizzo e l'altro è il 60%, l'utilizzo complessivo è del 45%. Puoi anche vedere l'utilizzo di ogni singolo core.

0
Aashishkebab