Cosa fa un processo CPU inattivo?


73

Osservando la fonte straceho trovato l'uso della bandiera del clone CLONE_IDLETASKche è descritta lì come:

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

Dopo aver esaminato più a fondo, ho scoperto che, sebbene quel flag non sia coperto man clone, viene effettivamente utilizzato dal kernel durante il processo di avvio per creare processi inattivi (che dovrebbero avere tutti PID 0) per ogni CPU sulla macchina. cioè una macchina con 8 CPU avrà almeno 7 (vedi domanda sotto) tali processi "in esecuzione" (virgolette).

Ora, questo mi porta a un paio di domande su cosa faccia effettivamente quel processo "inattivo". La mia ipotesi è che esegue l'operazione NOP continuamente fino al termine del suo periodo di tempo e il kernel assegna un processo reale per eseguire o assegnare nuovamente il processo inattivo (se la CPU non viene utilizzata). Eppure, è un'ipotesi completa. Così:

  1. Su una macchina con, diciamo, 8 CPU verranno creati 7 processi inattivi? (e una CPU sarà gestita dal kernel stesso mentre non si esegue alcun lavoro nello spazio utente?)

  2. Il processo inattivo è davvero solo un flusso infinito di operazioni NOP? (o un ciclo che fa lo stesso).

  3. L'utilizzo della CPU (diciamo uptime) è semplicemente calcolato da quanto tempo è rimasto il processo inattivo sulla CPU e da quanto tempo non è stato presente in un determinato periodo di tempo?


PS È probabile che buona parte di questa domanda sia dovuta al fatto che non capisco fino in fondo come funziona una CPU. cioè capisco l'assemblaggio, i tempi e gli interrupt ma non so come, ad esempio, una CPU possa usare più o meno energia a seconda di ciò che sta eseguendo. Le sarei grato se qualcuno potesse illuminarmi anche su questo.


17
Ho dovuto resistere alla tentazione di scrivere "Niente affatto" quando ho visto il titolo.
Valità,

4
La maggior parte delle CPU moderne ridurrà in modo dinamico la frequenza di clock e il consumo di energia quando è inattivo o a basso carico ( ridimensionamento dinamico della frequenza , ad esempio SpeedStep per CPU Intel). Se overclocchi una CPU, di solito disabiliterà questo comportamento, facendo sì che la CPU mantenga la frequenza di clock massima anche quando è inattiva.
Nat

2
Vedi anche "Stati di alimentazione ACPI": ci sono vari modi in cui un processore può smettere di eseguire le istruzioni ma essere comunque riattivabile.
pjc50,

Risposte:


85

L'attività inattiva viene utilizzata per la contabilità di processo e anche per ridurre il consumo di energia. In Linux, viene creata un'attività inattiva per ogni processore e bloccata su quel processore; ogni volta che non c'è nessun altro processo da eseguire su quella CPU, l'attività inattiva è programmata. Il tempo impiegato nelle attività inattive viene visualizzato come tempo di inattività in strumenti come top. (Il tempo di attività viene calcolato in modo diverso.)

Unix sembra aver sempre avuto un ciclo di inattività di qualche tipo (ma non necessariamente un vero e proprio compito di inattività, vedi la risposta di Gilles ), e anche in V1 usava WAITun'istruzione che fermava il processore fino a quando si verificava un interruzione (stava per "wait for interrompere"). Alcuni altri sistemi operativi utilizzavano in particolare loop di occupato, DOS, OS / 2 e versioni precedenti di Windows. Da molto tempo ormai, le CPU hanno usato questo tipo di istruzioni di "attesa" per ridurre il consumo di energia e la produzione di calore. Puoi vedere varie implementazioni di task inattivi ad esempio nel arch/x86/kernel/process.ckernel di Linux: quello di base chiamaHLT, che arresta il processore fino a quando non si verifica un interruzione (e abilita la modalità di risparmio energetico C1), le altre implementazioni gestiscono vari bug o inefficienze ( ad es. utilizzando MWAITinvece che HLTsu alcune CPU).

Tutto ciò è completamente separato dagli stati inattivi nei processi, quando sono in attesa di un evento (I / O ecc.).


3
Heh, lo vedo ora, grazie. play_dead()è un bel nome mnemonico per l'esecuzione di HALT. Non ci sarebbe il rischio di inviare HALT a ogni CPU e di conseguenza bloccarsi? (vale a dire raggiungere questa situazione, HALT ogni CPU, sarebbe un bug nel kernel corretto?)
grochmal

30
La CPU si sveglia da HALT tramite un interrupt.
Johan Myréen,

1
@ JohanMyréen - Fantastico, ha senso. In tal caso, anche un interrupt IRQ da un dispositivo di input lo riattiva. Grazie.
grochmal

15
O in modo più affidabile, il timer si interrompe ... (La gestione senza tick è un altro bollitore di pesce.)
Stephen Kitt,

3
@EJP in effetti, è un'istruzione abbastanza comune, anche se ha nomi diversi in architetture diverse.
user253751

50

Nella progettazione del manuale di uno scheduler di processo, se lo scheduler non ha alcun processo da pianificare (cioè se tutti i processi sono bloccati, in attesa di input), allora lo scheduler attende un interruzione del processore. L'interruzione può indicare l'input da una periferica (azione dell'utente, pacchetto di rete, lettura completata da un disco, ecc.) O può essere un interruzione del timer che attiva un timer in un processo.

Lo scheduler di Linux non ha un codice speciale per un caso niente da fare. Invece, codifica il caso nulla da fare come un processo speciale, il processo inattivo. Il processo inattivo viene pianificato solo quando nessun altro processo è programmabile (ha effettivamente una priorità infinitamente bassa). Il processo inattivo è in realtà parte del kernel: è un thread del kernel, ovvero un thread che esegue il codice nel kernel, piuttosto che il codice in un processo. (Più precisamente, esiste un thread di questo tipo per ogni CPU.) Quando viene eseguito il processo inattivo, esegue l'operazione di attesa per l'interruzione.

La modalità di attesa dell'interruzione dipende dalle capacità del processore. Con il design del processore più semplice, questo è solo un loop occupato:

nothing:
    goto nothing

Il processore continua a eseguire un'istruzione di ramo per sempre, che non compie nulla. La maggior parte dei sistemi operativi moderni non lo fa a meno che non sia in esecuzione su un processore in cui non c'è niente di meglio e la maggior parte dei processori ha qualcosa di meglio. Invece di spendere energia senza fare altro che riscaldare la stanza, idealmente, il processore dovrebbe essere spento. Quindi il kernel esegue il codice che indica al processore di spegnersi, o almeno di spegnere la maggior parte del processore. Ci deve essere almeno una piccola parte che rimane accesa, il controller di interrupt. Quando una periferica attiva un interrupt, il controller di interruzione invierà un segnale di riattivazione al processore (parte del) principale.

In pratica, le moderne CPU come Intel / AMD e ARM hanno molte e complesse impostazioni di gestione dell'alimentazione. Il sistema operativo può stimare per quanto tempo il processore rimarrà in modalità inattiva e sceglierà diverse modalità a basso consumo a seconda di ciò. Le modalità offrono diversi compromessi tra il consumo di energia mentre è inattivo e il tempo necessario per entrare e uscire dalla modalità di inattività. Su alcuni processori il sistema operativo può anche abbassare la frequenza di clock del processore quando rileva che i processi non consumano molto tempo della CPU.


5
Si noti che anche le CPU embedded più basilari come i microcontrollori basati su AVR hanno un'istruzione WFI (Wait For Interrupt), anche se tale istruzione può essere equivalente a NOP a seconda del modello esatto.
Jonas Schäfer,

@JonasWielicki Pensavo che in genere avresti fatto un circuito ristretto se non avessi nulla da fare, o potresti andare in uno stato a bassa potenza e aspettare che l'interrupt ti metta fuori gioco (gli stati di potenza inferiore di solito richiedono più " metallo "interrompe).
Nick T,

1
@JonasWielicki Le architetture progettate per i sistemi embedded hanno a cuore la gestione dell'alimentazione, quindi WFI è importante lì. Molte architetture più vecchie non hanno nulla del genere. L'architettura originale 8086 no, AFAIR. 68k ha WFI? È una funzionalità standard su MIPS? La mia familiarità con la programmazione di basso livello è principalmente su ARM, dove il basso consumo energetico è una cosa ovvia e WFI è solo la punta dell'iceberg della gestione dell'alimentazione.
Gilles 'SO- smetti di essere malvagio' il

1
@Gilles 8086 ha avuto un'istruzione di arresto. Vedi en.m.wikipedia.org/wiki/HLT_(x86_instruction) Le istruzioni includevano funzionalità di risparmio energetico solo dall'80486 DX4. Guardando indietro alla storia, HLT era già nell'8080 e derivati ​​(come Z80).
pabouk,

1
@pabouk HLTpotrebbe spegnere le varianti SL dei 386 e 486, prima che uscisse il DX4 (l'articolo di Wikipedia non è corretto).
Stephen Kitt,

0

No, un'attività inattiva non spreca i cicli della CPU. Lo scheduler semplicemente non seleziona un processo inattivo per l'esecuzione. Un processo inattivo attende che si verifichi un evento in modo che possa continuare. Ad esempio, può essere in attesa di input in una read()chiamata di sistema.

A proposito, il kernel non è un processo separato. Il codice del kernel viene sempre eseguito nel contesto di un processo (beh, ad eccezione del caso speciale di un thread del kernel), quindi non è corretto dire "e una CPU verrà mantenuta dal kernel stesso mentre non viene eseguito alcun lavoro nello spazio utente".


3
Hmmm ... Non penso che sia il tipo di processo inattivo creato da CLONE_IDLETASK. Se lo fosse stato, non sarebbe stato necessario crearlo affatto, ovvero se lo scheduler avesse ignorato i processi inattivi del kernel sulle CPU non avrebbe avuto bisogno di creare alcun processo durante l'avvio. (il DW non è mio però :))
grochmal

Un po 'di googling rivela che CLONE_IDLETASK è un flag interno al kernel che è stato introdotto intorno alla versione 2.5.14 del kernel nel 2002 e successivamente rimosso nel 2004.
Johan Myréen

"un" processo inattivo ma non " il " processo inattivo.
user253751
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.