Gestione dell'alimentazione, parte 1: definizione degli stati ACPI

Introduzione

Questo è il primo di una serie di articoli riguardanti le tecniche utilizzate dalle case produttrici di pc per gestire il sistema di alimentazione nei loro dispositivi. Quanto scritto fa riferimento all'elettronica presente nei laptop ma, a livello teorico, non si discosta di molto ciò che avviene anche nei desktop; mentre a livello pratico le cose posso essere abbastanza diverse, infatti i desktop verranno trattati più avanti.

Nel corso degli anni le maggiori case produttrici hanno sviluppato in comune accordo standard di gestione energetica al fine di avere una maggiore compatibilità tra i loro dispositivi. Nel 1992 venne introdotto lo standard APM (Advanced Power Management), tuttavia presto diventato obsoleto a causa di una sempre maggiore necessità di risparmio energetico. Venne infatti rimpiazzato dalla specifica ACPI (Advanced Configuration and Power Interface), di cui si occupa questo articolo e che permette un controllo completo dell'alimentazione direttamente dal sistema operativo, a differenza del precedente metodo che ne permetteva la gestione solo attraverso il BIOS.

La specifica ACPI definisce, tra le altre cose, degli stati che descrivono il comportamento delle principali componenti del computer in base al risparmio energetico desiderato. Quindi di fatto la specifica definisce ogni componente, nonché l'intero computer, come una macchina a stati finiti, dal punto di vista della gestione energetica.
In generale gli stati 0 (G0, S0, D0, etc...) sono stati attivi, in cui il sistema è disponibile all'utente, mentre gli altri sono stati "addormentati", dove un numero più alto corrisponde a minori consumi e maggiore tempo per tornare allo stato attivo.

La specifica ACPI fa riferimento in vari punti al contesto del sistema (system context) e al contesto del dispositivo (device context): questi non sono altro che "dati variabili" memorizzati nel dispositivo e necessari al suo immediato funzionamento. Ad esempio, su una CPU il contesto potrebbe indicare il contenuto dei registri, su un dispositivo USB il suo indirizzo sul bus, e così via. La specifica stabilisce in quali stati i contesti devono essere mantenuti, in quali possono essere persi, e in quali vengono persi dall'hardware ma è richiesto al sistema operativo di implementare un metodo per salvarli in modo permanente.

Stati G (Sistema Globale)

Sono stati che descrivono la percezione che ha l'utente finale del sistema complessivo, cioè del computer.

Stati S

Sono stati che descrivono cosa accade a livello di sistema. S0 è associato a G0, S1-S4 si trovano all'interno di G1 e S5 è associato a G2.

Stati addizionali

Stati C

Descrivono il comportamento della CPU. Si trovano tutti all'interno dello stato G0.

Il passaggio dallo stato C0 a C1 avviene, nei processori x86, tramite l'istruzione HLT (halt) che interrompe l'esecuzione di ulteriori istruzioni fino alla ricezione di una richiesta di interrupt, che riporta il processore nello stato C0.
Linux talvolta utilizza le istruzioni MWAIT o MWAITX, ma a grandi linee il funzionamento è lo stesso.
Il firmware ACPI indica al sistema operativo la latenza di caso peggiore per tornare dagli stati C2 e C3 allo stato C0, mentre per lo stato C1 la specifica richiede che sia così bassa da "non preoccuparsene": è il sistema operativo a decidere quale passare a questi stati, in base al carico di lavoro e alla massima latenza accettabile.

Negli stati C1 e successivi di solito viene effettuato clock gating per interrompere la distribuzione del clock, e quindi azzerare il consumo di potenza dinamico dei transistor, su tutte le parti del processore ad eccezione di quelle che devono rilevare interrupt o altri eventi esterni.
Nello stato C3 non viene più distribuito segnale di clock all'interno della CPU.
La differenza tra C1 e C2 è che il primo viene raggiunto tramite un'istruzione macchina, mentre il secondo con altri meccanismi che di solito si traducono nell'inviare un segnale a un piedino del processore, oltre al fatto che lo stato C2 ha consumi più bassi e latenza di uscita più alta rispetto al C1.

Esempio pratico

Su Linux è possibile visualizzare il tempo speso dal processore nei vari stati tramite il comando cpupower.
Ad esempio, cpupower monitor -i 10 restituisce queste informazioni, relative agli ultimi 10 secondi:

    |Mperf               || Idle_Stats         
CPU | C0   | Cx   | Freq || POLL | C1   | C2   
   0|  9,17| 90,83|  1772||  0,00|  7,92| 83,15
   1|  4,18| 95,82|  1457||  0,00|  4,74| 91,20
   2|  7,72| 92,28|  1591||  0,00|  7,69| 84,80
   3|  3,90| 96,10|  1422||  0,00|  3,71| 92,52
   4|  7,32| 92,68|  1413||  0,00|  8,03| 84,86
   5|  8,95| 91,05|  1596||  0,00|  6,63| 84,53
   6| 10,61| 89,39|  1604||  0,00|  8,02| 81,57
   7|  3,39| 96,61|  1495||  0,00|  7,29| 89,43

Gli 8 core del processore sono considerati come processori separati. Prendendo ad esempio il core 0, si può notare che ha passato circa il 9% del tempo nello stato C0, ad una frequenza media di 1.77 GHz (alternando tra 1.4 e 1.9 GHz a causa del Dynamic Frequency Scaling, ma non è indicato dall'output del comando), e circa l'8% e l'83% del tempo negli stati C1 e C2, rispettivamente.

Lo stato C3 non è supportato dal processore in questione, mentre POLL non è un vero stato: si tratta di un ciclo di busy wait, utilizzato dal sistema operativo quando sono imminenti altre operazioni e la latenza per entrare e uscire dallo stato C1 sarebbe troppo alta, ma ciò non fa parte della specifica ACPI.

Sempre su Linux, all'interno della directory /sys/devices/system/cpu/cpu0/cpuidle/state0 e successive si trovano inoltre alcuni "file" con informazioni sull'uso degli stati C, divisi per core (a partire da cpu0). La documentazione del kernel indica quali dati sono disponibili e come interpretarli.

Poiché la latenza di uscita è indicata dal firmware ACPI per tutti gli stati successivi a C1, si possono leggere da quella directory i valori rilevati dal kernel. Utilizzando il comando cat /sys/devices/system/cpu/cpu0/cpuidle/state*/{name,latency} e formattando l'output in una tabella si può vedere che:

Stato Latenza
POLL 0
C1 0
C2 100

I valori sono espressi in microsecondi.

Su un computer portatile recente si possono avere risultati più interessanti, ad esempio:

    |Idle_Stats                                                    
CPU | POLL | C1-S | C1E- | C3-S | C6-S | C7s- | C8-S | C9-S | C10- 
   0|  0,00| 16,08|  0,49|  0,04|  0,43|  0,00|  6,40|  0,00| 74,10
   2|  0,00|  0,00|  0,00|  0,00|  0,00|  1,19|  2,53| 11,42| 79,80
   1|  0,00|  0,00|  0,03|  0,00|  0,14|  0,00| 16,22|  0,00| 80,92
   3|  0,00|  0,00|  0,00|  0,00|  0,00|  0,00|  3,09|  0,00| 96,17
Stato Latenza
POLL 0
C1-SKL 2
C1E-SKL 10
C3-SKL 70
C6-SKL 85
C7s-SKL 124
C8-SKL 200
C9-SKL 480
C10-SKL 890

Il suffisso SKL indica che il processore appartiene alla serie Intel Skylake, dettaglio non particolarmente rilevante nella trattazione corrente e che può tranquillamente essere ignorato.

Stati C addizionali

Alcuni processori, soprattutto quelli per laptop, più sensibili alla questione del risparmio energetico, talvolta supportano stati C addizionali. La specifica ACPI non li definisce esplicitamente: per alcuni ammette un metodo con cui la CPU può comunicare quali supporta, mentre altri sono di fatto invisibili al sistema operativo.
Come sempre, più il numero dello stato cresce, più i consumi diminuiscono e la latenza per tornare allo stato C0 aumenta:

Poiché nei dispositivi mobili la CPU è uno dei componenti che consumano di più e che meglio si prestano a complesse operazioni di risparmio energetico (mentre su uno schermo, ad esempio, a parte ridurre la luminosità non si può fare molto), esistono altre sottili differenze e sotto stati, ma esulano dall'ambito di questo articolo e talvolta anche dalla specifica ACPI.

Stati P

Sono stati che si applicano sia alla CPU che ai dispositivi. Sono tutti stati attivi, cioè che possono essere utilizzati solo nello stato C0 o D0.

L'esatto numero di stati P (P0, P1, P2, etc...) è definito dal dispositivo o dalla CPU e non può superare 255.

Servono per aumentare ulteriormente il risparmio energetico, infatti nel caso delle CPU all'aumentare dello stato diminuisce la frequenza interna di lavoro della CPU (Dynamic Frequency Scaling, conosciuto anche come CPU throttling) e di conseguenza il consumo.

Stati D

Sono stati che descrivono il comportamento dei vari dispositivi collegati al sistema.

Gli stati D0 e D3COLD sono definiti e obbligatori per tutti i dispositivi, mentre gli altri sono obbligatori o ammessi solo per alcune classi di dispositivi indicati dalla specifica.

Stati non-ACPI

Anche alcuni dispositivi o bus, come quello PCI e PCIe, per gestire il risparmio energetico utilizzano un sistema di stati simile a quello ACPI, ma non trattato da quella specifica; sono infatti trattati all'interno delle specifiche di ogni singolo standard. Vista la loro importanza soprattutto nei computer portatili verranno accennati qui di seguito.

Stati S0ix

Gli stati S0i1 - S0i3 sono strettamente legati all'ambito dei notebook e sono utilizzati da alcuni SoC Intel. Hanno l'obiettivo di garantire consumi simili agli stati S1 - S3 ma un tempo di risveglio inferiore ed essere selezionabili direttamente dalla CPU quando vengono raggiunte opportune condizioni, senza l'intervento del sistema operativo.

Stati T

Stati ormai obsoleti legati alle funzionalità della CPU, erano necessari con vecchi processori che potevano, in seguito a surriscaldamento, prendere fuoco. L'obiettivo era quello di far "rilassare" la CPU che quindi per una parte di tempo lavorava (circa 78%) mentre nel resto non eseguiva istruzioni permettendo un lieve raffreddamento: questo si ripeteva con intervalli regolari. Oggi sono stati soppiantati dagli stati C e P, nonché dalla capacità della maggior parte delle CPU di rilevare la propria temperatura e spegnersi se viene raggiunta una soglia limite.

Stati B

Descrivono il comportamento del bus PCI. Una cosa importante da tenere presente è che può essere abbandonato lo stato B0 solamente se tutti i dispositivi collegati al bus risultano inattivi.

Stati L

Descrivono il comportamento dell'interfaccia PCIe.

È necessario specificare che ogni dispositivo PCIe è alimentato dall'alimentazione principale, che può essere disattivata per il risparmio energetico, e da un'alimentazione secondaria sempre presente (se non diversamente specificato) di circa 3.3 V. Quest'ultima svolge un ruolo importante in diverse situazioni in cui è necessario mantenere abilitati dei moduli a computer spento, ad esempio per la funzionalità Wake on LAN.

I PLL sono circuiti di controllo molto usati nelle telecomunicazioni che permettono di ottenere, dato un segnale in ingresso, uno in uscita con la stessa fase di quello in entrata. Nei computer di solito vengono utilizzati per ottenere una frequenza più alta da quella di un oscillatore.

Stati RC

RC sta per Render Cpu. Sono equivalenti agli stati C ma validi per le GPU (RC0 - RC5). Raramente è anche presente lo stato RC6. Esistono ulteriori stati (RC6p e RC6pp) dove viene ridotta ulteriormente la tensione di alimentazione, ma sono deprecati.

Sono utilizzati praticamente solo da alcune GPU Intel, quindi non sono disponibili molte informazioni a riguardo.

Riassunto

Tutti gli stati ACPI e PCIe appena descritti sono riassunti nella seguente immagine dove vengono collocati dal "più acceso" al "più spento". Tabella riassuntiva degli stati ACPI e PCIe Nel prossimo articolo si inizierà a vedere come questa specifica viene effettivamente implementata a livello hardware nei notebook.

Autore: Federico Bassignana