Durante la ricerca degli stati di alimentazione della CPU Core 2 (" stati C "), in realtà sono riuscito a implementare il supporto per la maggior parte dei processori Intel Core / Core 2 legacy. L'implementazione completa (patch Linux) con tutte le informazioni di base è documentata qui.
Man mano che accumulavo maggiori informazioni su questi processori, è diventato evidente che gli stati C supportati nei modelli Core 2 sono molto più complessi di quelli dei processori precedenti e successivi. Questi sono noti come stati C migliorati (o " CxE "), che coinvolgono il pacchetto, i singoli core e altri componenti sul chipset (ad es. Memoria). Al momento del intel_idle
rilascio del driver, il codice non era particolarmente maturo e numerosi processori Core 2 erano stati rilasciati con supporto in stato C in conflitto.
Alcune informazioni convincenti sul supporto dello stato C Core 2 Solo / Duo sono state trovate in questo articolo dal 2006 . Questo è in relazione al supporto su Windows, tuttavia indica il solido supporto hardware C-state su questi processori. Le informazioni relative a Kentsfield sono in conflitto con il numero di modello attuale, quindi credo che in realtà si riferiscano a un Yorkfield di seguito:
... il processore quad-core Intel Core 2 Extreme (Kentsfield) supporta tutte e cinque le tecnologie di prestazioni e risparmio energetico: Intel SpeedStep (EIST), Thermal Monitor 1 (TM1) e Thermal Monitor 2 (TM2) migliorati, vecchio orologio su richiesta Modulazione (ODCM) e Enhanced C States (CxE). Rispetto ai processori Intel Pentium 4 e Pentium D 600, 800 e 900, che sono caratterizzati solo dallo stato Enhanced Halt (C1), questa funzione è stata ampliata nei processori Intel Core 2 (così come i processori Intel Core Solo / Duo) per tutti i possibili stati di inattività di un processore, inclusi Stop Grant (C2), Deep Sleep (C3) e Deeper Sleep (C4).
Questo articolo del 2008 delinea il supporto per stati C per core su processori Intel multi-core, inclusi Core 2 Duo e Core 2 Quad (ulteriori utili letture di base sono state trovate in questo white paper di Dell ):
Uno stato C centrale è uno stato C hardware. Esistono diversi stati di inattività principali, ad esempio CC1 e CC3. Come sappiamo, un moderno processore all'avanguardia ha più core, come i processori mobili Core Duo T5000 / T7000 rilasciati di recente, noti come Penryn in alcuni ambienti. Ciò che eravamo soliti pensare come una CPU / processore, in realtà ha più CPU per scopi generici al suo fianco. L'Intel Core Duo ha 2 core nel chip del processore. Intel Core-2 Quad ha 4 core di questo tipo per chip del processore. Ognuno di questi core ha il suo stato inattivo. Questo ha senso in quanto un core potrebbe essere inattivo mentre un altro è al lavoro su un thread. Quindi uno stato C centrale è lo stato inattivo di uno di quei nuclei.
Ho trovato una presentazione 2010 di Intel che fornisce ulteriori informazioni sul intel_idle
driver, ma purtroppo non spiega la mancanza di supporto per Core 2:
Questo driver SPERIMENTALE sostituisce acpi_idle su processori Intel Atom, processori Intel Core i3 / i5 / i7 e processori Intel Xeon associati. Non supporta il processore Intel Core2 o precedente.
La presentazione di cui sopra indica che il intel_idle
driver è un'implementazione del regolatore di menu "menu", che ha un impatto sulla configurazione del kernel Linux (cioè, CONFIG_CPU_IDLE_GOV_LADDER
vs. CONFIG_CPU_IDLE_GOV_MENU
). Le differenze tra i regolatori ladder e menu sono brevemente descritte in questa risposta .
Dell ha un utile articolo che elenca la compatibilità C-state da C0 a C6:
Le modalità da C1 a C3 funzionano sostanzialmente tagliando i segnali di clock utilizzati all'interno della CPU, mentre le modalità da C4 a C6 riducono la tensione della CPU. Le modalità "avanzate" possono fare entrambe le cose contemporaneamente.
Mode Name CPUs
C0 Operating State All CPUs
C1 Halt 486DX4 and above
C1E Enhanced Halt All socket LGA775 CPUs
C1E — Turion 64, 65-nm Athlon X2 and Phenom CPUs
C2 Stop Grant 486DX4 and above
C2 Stop Clock Only 486DX4, Pentium, Pentium MMX, K5, K6, K6-2, K6-III
C2E Extended Stop Grant Core 2 Duo and above (Intel only)
C3 Sleep Pentium II, Athlon and above, but not on Core 2 Duo E4000 and E6000
C3 Deep Sleep Pentium II and above, but not on Core 2 Duo E4000 and E6000; Turion 64
C3 AltVID AMD Turion 64
C4 Deeper Sleep Pentium M and above, but not on Core 2 Duo E4000 and E6000 series; AMD Turion 64
C4E/C5 Enhanced Deeper Sleep Core Solo, Core Duo and 45-nm mobile Core 2 Duo only
C6 Deep Power Down 45-nm mobile Core 2 Duo only
Da questa tabella (che in seguito ho scoperto di essere errata in alcuni casi), sembra che ci fossero una varietà di differenze nel supporto dello stato C con i processori Core 2 (Notare che quasi tutti i processori Core 2 sono Socket LGA775, ad eccezione di Core 2 Solo SU3500, che sono processori Socket BGA956 e Merom / Penryn. I processori Solo / Duo "Intel Core" sono uno dei socket PBGA479 o PPGA478).
Un'eccezione aggiuntiva alla tabella è stata trovata in questo articolo :
Il Core 2 Duo E8500 di Intel supporta gli stati C C2 e C4, mentre il Core 2 Extreme QX9650 no.
È interessante notare che il QX9650 è un processore Yorkfield (famiglia Intel 6, modello 23, stepping 6). Per riferimento, il mio Q9550S è la famiglia Intel 6, modello 23 (0x17), stepping 10, che presumibilmente supporta lo stato C C4 (confermato attraverso la sperimentazione). Inoltre, il Core 2 Solo U3500 ha un CPUID identico (famiglia, modello, stepping) al Q9550S ma è disponibile in un socket non LGA775, il che confonde l'interpretazione della tabella sopra.
Chiaramente, il CPUID deve essere usato almeno fino allo stepping per identificare il supporto dello stato C per questo modello di processore, e in alcuni casi che potrebbe essere insufficiente (non determinato in questo momento).
La firma del metodo per l'assegnazione delle informazioni di inattività della CPU è:
#define ICPU(model, cpu) \
{ X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (unsigned long)&cpu }
Dove model
è elencato in asm / intel-family.h . Esaminando questo file di intestazione, vedo che alle CPU Intel sono assegnati identificatori a 8 bit che sembrano corrispondere ai numeri di modello della famiglia Intel 6:
#define INTEL_FAM6_CORE2_PENRYN 0x17
Da quanto sopra, abbiamo Intel Family 6, Modello 23 (0x17) definito come INTEL_FAM6_CORE2_PENRYN
. Ciò dovrebbe essere sufficiente per definire gli stati di inattività per la maggior parte dei processori modello 23, ma potrebbe potenzialmente causare problemi con QX9650 come indicato sopra.
Quindi, in minima parte, ciascun gruppo di processori che ha un set di stati C distinto dovrebbe essere definito in questo elenco.
Zagacki e Ponnala, Intel Technology Journal 12 (3): 219-227, 2008 indicano che i processori di Yorkfield supportano effettivamente C2 e C4. Sembrano anche indicare che la specifica ACPI 3.0a supporta solo le transizioni tra gli stati C C0, C1, C2 e C3, che presumo possano anche limitare il acpi_idle
driver Linux alle transizioni tra quell'insieme limitato di stati C. Tuttavia, questo articolo indica che potrebbe non essere sempre il caso:
Tieni presente che è lo stato ACPI C, non quello del processore, quindi ACPI C3 potrebbe essere HW C6, ecc.
Da notare anche:
Oltre al processore stesso, poiché C4 è uno sforzo sincronizzato tra i principali componenti di silicio nella piattaforma, il chipset Intel Q45 Express ottiene un miglioramento della potenza del 28 percento.
Il chipset che sto usando è davvero un chipset Intel Q45 Express.
La documentazione Intel sugli stati di MWAIT è concisa ma conferma il comportamento ACPI specifico del BIOS:
Gli stati C specifici del processore definiti nelle estensioni MWAIT possono essere mappati ai tipi di stato C definiti ACPI (C0, C1, C2, C3). La relazione di mappatura dipende dalla definizione di uno stato C per implementazione del processore ed è esposta a OSPM dal BIOS usando la tabella _CST definita da ACPI.
La mia interpretazione della tabella sopra (combinata con una tabella di Wikipedia , asm / intel-family.h e degli articoli precedenti) è:
Modello 9 0x09 ( Pentium M e Celeron M ):
- Banias: C0, C1, C2, C3, C4
Modello 13 0x0D ( Pentium M e Celeron M ):
- Dothan, Stealey: C0, C1, C2, C3, C4
Modello 14 0x0E INTEL_FAM6_CORE_YONAH ( Enhanced Pentium M , Enhanced Celeron M o Intel Core ):
- Yonah ( Core Solo , Core Duo ): C0, C1, C2, C3, C4, C4E / C5
Modello 15 0x0F INTEL_FAM6_CORE2_MEROM (alcuni Core 2 e Pentium Dual-Core ):
- Kentsfield, Merom, Conroe, Allendale ( E2xxx / E4xxx e Core 2 Duo E6xxx, T7xxxx / T8xxxx , Core 2 Extreme QX6xxx , Core 2 Quad Q6xxx ): C0, C1, C1E, C2, C2E
Modello 23 0x17 INTEL_FAM6_CORE2_PENRYN ( Core 2 ):
- Merom-L / Penryn-L:?
- Penryn ( Core 2 Duo 45-nm mobile ): C0, C1, C1E, C2, C2E, C3, C4, C4E / C5, C6
- Yorkfield ( Core 2 Extreme QX9650 ): C0, C1, C1E, C2E ?, C3
- Wolfdale / Yorkfield ( Core 2 Quad , C2Q Xeon , Core 2 Duo E5xxx / E7xxx / E8xxx , Pentium Dual-Core E6xxx , Celeron Dual-Core ): C0, C1, C1E, C2, C2E, C3, C4
Dalla quantità di diversità nel supporto dello stato C all'interno della sola linea di processori Core 2, sembra che la mancanza di un supporto coerente per gli stati C possa essere stata la ragione per non tentare di supportarli completamente tramite il intel_idle
driver. Vorrei completare completamente l'elenco sopra per l'intera linea Core 2.
Questa non è davvero una risposta soddisfacente, perché mi chiedo quanta energia non necessaria viene utilizzata e il calore in eccesso è stato (ed è tuttora) generato non utilizzando completamente i solidi stati C MWAIT a risparmio energetico su questi processori.
Chattopadhyay et al. 2018, Processori ad alte prestazioni ad alta efficienza energetica: i recenti approcci per la progettazione di Green Performance Performance Computing meritano attenzione per il comportamento specifico che sto cercando nel chipset Q45 Express:
Pacchetto C-state (PC0-PC10) - Quando i domini di calcolo, Core e Graphics (GPU) sono inattivi, il processore ha l'opportunità di ulteriori risparmi energetici a livello di uncore e piattaforma, ad esempio, svuotando il LLC e attivando controller di memoria e DRAM IO, e in alcuni stati, l'intero processore può essere spento mentre il suo stato viene mantenuto su un dominio di alimentazione sempre attivo.
Come test, ho inserito quanto segue in linux / drivers / idle / intel_idle.c linea 127:
static struct cpuidle_state conroe_cstates[] = {
{
.name = "C1",
.desc = "MWAIT 0x00",
.flags = MWAIT2flg(0x00),
.exit_latency = 3,
.target_residency = 6,
.enter = &intel_idle,
.enter_s2idle = intel_idle_s2idle, },
{
.name = "C1E",
.desc = "MWAIT 0x01",
.flags = MWAIT2flg(0x01),
.exit_latency = 10,
.target_residency = 20,
.enter = &intel_idle,
.enter_s2idle = intel_idle_s2idle, },
// {
// .name = "C2",
// .desc = "MWAIT 0x10",
// .flags = MWAIT2flg(0x10),
// .exit_latency = 20,
// .target_residency = 40,
// .enter = &intel_idle,
// .enter_s2idle = intel_idle_s2idle, },
{
.name = "C2E",
.desc = "MWAIT 0x11",
.flags = MWAIT2flg(0x11),
.exit_latency = 40,
.target_residency = 100,
.enter = &intel_idle,
.enter_s2idle = intel_idle_s2idle, },
{
.enter = NULL }
};
static struct cpuidle_state core2_cstates[] = {
{
.name = "C1",
.desc = "MWAIT 0x00",
.flags = MWAIT2flg(0x00),
.exit_latency = 3,
.target_residency = 6,
.enter = &intel_idle,
.enter_s2idle = intel_idle_s2idle, },
{
.name = "C1E",
.desc = "MWAIT 0x01",
.flags = MWAIT2flg(0x01),
.exit_latency = 10,
.target_residency = 20,
.enter = &intel_idle,
.enter_s2idle = intel_idle_s2idle, },
{
.name = "C2",
.desc = "MWAIT 0x10",
.flags = MWAIT2flg(0x10),
.exit_latency = 20,
.target_residency = 40,
.enter = &intel_idle,
.enter_s2idle = intel_idle_s2idle, },
{
.name = "C2E",
.desc = "MWAIT 0x11",
.flags = MWAIT2flg(0x11),
.exit_latency = 40,
.target_residency = 100,
.enter = &intel_idle,
.enter_s2idle = intel_idle_s2idle, },
{
.name = "C3",
.desc = "MWAIT 0x20",
.flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 85,
.target_residency = 200,
.enter = &intel_idle,
.enter_s2idle = intel_idle_s2idle, },
{
.name = "C4",
.desc = "MWAIT 0x30",
.flags = MWAIT2flg(0x30) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 100,
.target_residency = 400,
.enter = &intel_idle,
.enter_s2idle = intel_idle_s2idle, },
{
.name = "C4E",
.desc = "MWAIT 0x31",
.flags = MWAIT2flg(0x31) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 100,
.target_residency = 400,
.enter = &intel_idle,
.enter_s2idle = intel_idle_s2idle, },
{
.name = "C6",
.desc = "MWAIT 0x40",
.flags = MWAIT2flg(0x40) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 200,
.target_residency = 800,
.enter = &intel_idle,
.enter_s2idle = intel_idle_s2idle, },
{
.enter = NULL }
};
alla intel_idle.c
linea 983:
static const struct idle_cpu idle_cpu_conroe = {
.state_table = conroe_cstates,
.disable_promotion_to_c1e = false,
};
static const struct idle_cpu idle_cpu_core2 = {
.state_table = core2_cstates,
.disable_promotion_to_c1e = false,
};
alla intel_idle.c
linea 1073:
ICPU(INTEL_FAM6_CORE2_MEROM, idle_cpu_conroe),
ICPU(INTEL_FAM6_CORE2_PENRYN, idle_cpu_core2),
Dopo una rapida compilazione e riavvio dei miei nodi PXE, dmesg
ora mostra:
[ 0.019845] cpuidle: using governor menu
[ 0.515785] clocksource: acpi_pm: mask: 0xffffff max_cycles: 0xffffff, max_idle_ns: 2085701024 ns
[ 0.543404] intel_idle: MWAIT substates: 0x22220
[ 0.543405] intel_idle: v0.4.1 model 0x17
[ 0.543413] tsc: Marking TSC unstable due to TSC halts in idle states deeper than C2
[ 0.543680] intel_idle: lapic_timer_reliable_states 0x2
E ora PowerTOP sta mostrando:
Package | CPU 0
POLL 2.5% | POLL 0.0% 0.0 ms
C1E 2.9% | C1E 5.0% 22.4 ms
C2 0.4% | C2 0.2% 0.2 ms
C3 2.1% | C3 1.9% 0.5 ms
C4E 89.9% | C4E 92.6% 66.5 ms
| CPU 1
| POLL 10.0% 400.8 ms
| C1E 5.1% 6.4 ms
| C2 0.3% 0.1 ms
| C3 1.4% 0.6 ms
| C4E 76.8% 73.6 ms
| CPU 2
| POLL 0.0% 0.2 ms
| C1E 1.1% 3.7 ms
| C2 0.2% 0.2 ms
| C3 3.9% 1.3 ms
| C4E 93.1% 26.4 ms
| CPU 3
| POLL 0.0% 0.7 ms
| C1E 0.3% 0.3 ms
| C2 1.1% 0.4 ms
| C3 1.1% 0.5 ms
| C4E 97.0% 45.2 ms
Ho finalmente accesso agli stati C Core 2 avanzati e sembra che ci sia un calo misurabile nel consumo di energia - il mio contatore su 8 nodi sembra avere una media di almeno il 5% inferiore (con un nodo ancora in esecuzione il vecchio kernel) , ma proverò a scambiare nuovamente i kernel come test.
Una nota interessante riguardo al supporto C4E - Il mio processore York95 Q9550S sembra supportarlo (o qualche altro stato secondario del C4), come evidenziato sopra! Questo mi confonde, perché il foglio dati Intel sul processore Core 2 Q9000 (sezione 6.2) menziona solo gli stati C Normale (C0), HALT (C1 = 0x00), Extended HALT (C1E = 0x01), Stop Grant (C2 = 0x10) , Extended Stop Grant (C2E = 0x11), Sleep / Deep Sleep (C3 = 0x20) e Deeper Sleep (C4 = 0x30). Che cos'è questo ulteriore stato 0x31? Se abilito lo stato C2, viene utilizzato C4E anziché C4. Se disabilito lo stato C2 (forza stato C2E), viene utilizzato C4 anziché C4E. Sospetto che ciò possa avere qualcosa a che fare con i flag MWAIT, ma non ho ancora trovato la documentazione per questo comportamento.
Non sono sicuro di cosa pensare: lo stato C1E sembra essere usato al posto di C1, C2 è usato al posto di C2E e C4E è usato al posto di C4. Non sono sicuro se C1 / C1E, C2 / C2E e C4 / C4E possano essere utilizzati insieme intel_idle
o se siano ridondanti. Ho trovato una nota in questa presentazione del 2010 di Intel Labs Pittsburgh che indica che le transizioni sono C0 - C1 - C0 - C1E - C0 e afferma inoltre:
C1E viene utilizzato solo quando tutti i core sono in C1E
Credo che debba essere interpretato come lo stato C1E viene inserito su altri componenti (ad es. Memoria) solo quando tutti i core sono nello stato C1E. Prendo anche questo per applicarlo in modo equivalente agli stati C2 / C2E e C4 / C4E (Sebbene C4E sia indicato come "C4E / C5", quindi non sono sicuro se C4E sia un sotto-stato di C4 o se C5 sia un sub- stato di C4E. Il test sembra indicare che C4 / C4E è corretto). Posso forzare l'uso di C2E commentando lo stato C2 - tuttavia, ciò fa sì che venga utilizzato lo stato C4 anziché C4E (potrebbe essere necessario più lavoro qui). Si spera che non ci siano processori modello 15 o modello 23 a cui manca lo stato C2E, poiché tali processori sarebbero limitati a C1 / C1E con il codice sopra riportato.
Inoltre, i valori di flag, latenza e residenza potrebbero probabilmente essere messi a punto, ma il solo fatto di ipotizzare in base ai valori inattivi di Nehalem sembra funzionare bene. Per apportare miglioramenti saranno necessarie ulteriori letture.
Ho provato questo su un Core 2 Duo E2220 ( Allendale ), un Dual Core Pentium E5300 ( Wolfdale ), Core 2 Duo E7400 , Core 2 Duo E8400 ( Wolfdale ), Core 2 Quad Q9550S ( Yorkfield ) e Core 2 Extreme QX9650 e I non sono stati rilevati problemi oltre la suddetta preferenza per lo stato C2 / C2E e C4 / C4E.
Non coperto da questa modifica del driver:
- I Core Solo / Core Duo originali ( Yonah , non Core 2) sono la famiglia 6, modello 14. Ciò è positivo perché supportavano gli stati C C4E / C5 (Enhanced Deep Sleep) ma non gli stati C1E / C2E e avrebbero bisogno del loro propria definizione inattiva.
Gli unici problemi che mi vengono in mente sono:
- Core 2 Solo SU3300 / SU3500 (Penryn-L) sono la famiglia 6, modello 23 e saranno rilevati da questo driver. Tuttavia, non sono socket LGA775, pertanto potrebbero non supportare lo stato C Halt Enhanced C1E. Allo stesso modo per il Core 2 Solo ULV U2100 / U2200 ( Merom-L ). Tuttavia, il
intel_idle
driver sembra scegliere il C1 / C1E appropriato in base al supporto hardware dei sottostati.
- Secondo quanto riferito, Core 2 Extreme QX9650 (Yorkfield) non supporta C-state C2 o C4. L'ho confermato acquistando un processore Optiplex 780 e QX9650 Extreme usato su eBay. Il processore supporta gli stati C C1 e C1E. Con questa modifica del driver, la CPU è inattiva nello stato C1E anziché C1, quindi si presume che si verifichi un certo risparmio energetico. Mi aspettavo di vedere C-state C3, ma non è presente quando si utilizza questo driver, quindi potrebbe essere necessario esaminare ulteriormente questo.
Sono riuscito a trovare una diapositiva da una presentazione Intel del 2009 sulle transizioni tra gli stati C (ovvero Deep Power Down):
In conclusione, si è scoperto che non vi era alcun motivo reale per la mancanza di supporto Core 2 nel intel_idle
driver. Ora è chiaro che il codice originale dello stub per "Core 2 Duo" gestiva solo gli stati C1 e C2, che sarebbero stati molto meno efficienti della acpi_idle
funzione che gestisce anche lo stato C3. Una volta saputo dove cercare, implementare il supporto è stato facile. I commenti utili e le altre risposte sono stati molto apprezzati e se Amazon sta ascoltando, sai dove inviare l'assegno.
Questo aggiornamento è stato affidato a github . Presto invierò una patch via e-mail a LKML.
Aggiornamento : sono anche riuscito a scavare un Socket T / LGA775 Allendale ( Conroe ) Core 2 Duo E2220, che è la famiglia 6, modello 15, quindi ho aggiunto anche il supporto per quello. Questo modello non supporta C-state C4, ma supporta C1 / C1E e C2 / C2E. Questo dovrebbe funzionare anche con altri chip basati su Conroe ( E4xxx / E6xxx ) e possibilmente tutti i processori Kentsfield e Merom (non Merom-L).
Aggiornamento : ho finalmente trovato alcune risorse di ottimizzazione MWAIT. Questa scrittura Power vs. Performance e questo Deeper più profondo e un post di blog sulla latenza aumentata contengono entrambi alcune informazioni utili sull'identificazione delle latenze inattive della CPU. Sfortunatamente, questo riporta solo quelle latenze di uscita codificate nel kernel (ma, cosa interessante, solo quegli stati hardware supportati dal processore):
# cd /sys/devices/system/cpu/cpu0/cpuidle
# for state in `ls -d state*` ; do echo c-$state `cat $state/name` `cat $state/latency` ; done
c-state0/ POLL 0
c-state1/ C1 3
c-state2/ C1E 10
c-state3/ C2 20
c-state4/ C2E 40
c-state5/ C3 20
c-state6/ C4 60
c-state7/ C4E 100
acpi_idle
e dei vari regolatori delle prestazioni. Quali statipowertop
mostra sul tuo sistema?