Lors de mes recherches sur les états d'alimentation du processeur Core 2 (" états C "), j'ai réussi à implémenter la prise en charge de la plupart des processeurs Intel Core / Core 2 hérités. L'implémentation complète (patch Linux) avec toutes les informations de base est documentée ici.
Alors que j'accumulais plus d'informations sur ces processeurs, il est devenu évident que les états C pris en charge dans les modèles Core 2 sont beaucoup plus complexes que ceux des processeurs précédents et ultérieurs. Celles-ci sont appelées états C améliorés (ou " CxE "), qui impliquent le package, les cœurs individuels et d'autres composants du chipset (par exemple, la mémoire). Au moment où le intel_idle
pilote a été publié, le code n'était pas particulièrement mature et plusieurs processeurs Core 2 avaient été libérés avec une prise en charge conflictuelle de l'état C.
Certaines informations convaincantes sur la prise en charge de l'état Core 2 Solo / Duo C ont été trouvées dans cet article de 2006 . Ceci est en relation avec la prise en charge sur Windows, mais cela indique la prise en charge robuste de l'état C matériel sur ces processeurs. Les informations concernant Kentsfield sont en conflit avec le numéro de modèle réel, donc je pense qu'elles se réfèrent en fait à un Yorkfield ci-dessous:
... le processeur quadricœur Intel Core 2 Extreme (Kentsfield) prend en charge les cinq technologies de performances et d'économie d'énergie - Enhanced Intel SpeedStep (EIST), Thermal Monitor 1 (TM1) et Thermal Monitor 2 (TM2), ancienne horloge à la demande Modulation (ODCM), ainsi que les états C améliorés (CxE). Par rapport aux processeurs Intel Pentium 4 et Pentium D 600, 800 et 900, caractérisés uniquement par l'état Enhanced Halt (C1), cette fonction a été étendue aux processeurs Intel Core 2 (ainsi qu'aux processeurs Intel Core Solo / Duo) pour tous les états inactifs possibles d'un processeur, y compris Stop Grant (C2), Deep Sleep (C3) et Deeper Sleep (C4).
Cet article de 2008 décrit la prise en charge des états C par cœur sur les processeurs Intel multicœurs, y compris Core 2 Duo et Core 2 Quad (une lecture supplémentaire utile a été trouvée dans ce livre blanc de Dell ):
Un état C de base est un état C matériel. Il existe plusieurs états inactifs principaux, par exemple CC1 et CC3. Comme nous le savons, un processeur moderne à la pointe de la technologie possède plusieurs cœurs, tels que les processeurs mobiles Core Duo T5000 / T7000 récemment commercialisés, appelés Penryn dans certains cercles. Ce que nous considérions comme un processeur / processeur, a en fait plusieurs processeurs à usage général à côté. L'Intel Core Duo a 2 cœurs dans la puce du processeur. L'Intel Core-2 Quad dispose de 4 cœurs par puce de processeur. Chacun de ces cœurs a son propre état de veille. Cela a du sens, car un noyau peut être inactif tandis qu'un autre travaille dur sur un thread. Un état C de base est donc l'état inactif de l'un de ces cœurs.
J'ai trouvé une présentation d'Intel en 2010 qui fournit des informations supplémentaires sur le intel_idle
pilote, mais n'explique malheureusement pas le manque de prise en charge de Core 2:
Ce pilote EXPERIMENTAL remplace acpi_idle sur les processeurs Intel Atom, Intel Core i3 / i5 / i7 et les processeurs Intel Xeon associés. Il ne prend pas en charge le processeur Intel Core2 ou antérieur.
La présentation ci-dessus indique que le intel_idle
pilote est une implémentation du gouverneur de CPU "menu", qui a un impact sur la configuration du noyau Linux (c.-à-d. CONFIG_CPU_IDLE_GOV_LADDER
Vs. CONFIG_CPU_IDLE_GOV_MENU
). Les différences entre l'échelle et les gouverneurs de menu sont succinctement décrites dans cette réponse .
Dell a un article utile qui répertorie la compatibilité des états C C0 à C6:
Les modes C1 à C3 fonctionnent en coupant essentiellement les signaux d'horloge utilisés à l'intérieur du CPU, tandis que les modes C4 à C6 fonctionnent en réduisant la tension du CPU. Les modes "améliorés" peuvent faire les deux en même temps.
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
D'après ce tableau (que j'ai constaté par la suite incorrect dans certains cas), il semble qu'il y ait une variété de différences dans la prise en charge de l'état C avec les processeurs Core 2 (Notez que presque tous les processeurs Core 2 sont Socket LGA775, à l'exception de Core 2 Solo SU3500, qui sont des processeurs Socket BGA956 et Merom / Penryn. Les processeurs "Intel Core" Solo / Duo sont l'un des Socket PBGA479 ou PPGA478).
Une exception supplémentaire au tableau a été trouvée dans cet article :
Le Core 2 Duo E8500 d'Intel prend en charge les états C C2 et C4, contrairement au Core 2 Extreme QX9650.
Fait intéressant, le QX9650 est un processeur Yorkfield (famille Intel 6, modèle 23, étape 6). Pour référence, mon Q9550S est la famille Intel 6, modèle 23 (0x17), pas à pas 10, qui prend censément en charge l'état C4 (confirmé par l'expérimentation). De plus, le Core 2 Solo U3500 a un CPUID (famille, modèle, pas à pas) identique au Q9550S mais est disponible dans un socket non LGA775, ce qui confond l'interprétation du tableau ci-dessus.
De toute évidence, le CPUID doit être utilisé au moins jusqu'à l'étape afin d'identifier la prise en charge de l'état C pour ce modèle de processeur, et dans certains cas, cela peut être insuffisant (indéterminé pour le moment).
La signature de méthode pour attribuer des informations inactives au processeur est:
#define ICPU(model, cpu) \
{ X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (unsigned long)&cpu }
Où model
est énuméré dans asm / intel-family.h . En examinant ce fichier d'en-tête, je constate que les processeurs Intel se voient attribuer des identificateurs 8 bits qui semblent correspondre aux numéros de modèle de la famille Intel 6:
#define INTEL_FAM6_CORE2_PENRYN 0x17
D'après ce qui précède, nous avons Intel Family 6, modèle 23 (0x17) défini comme INTEL_FAM6_CORE2_PENRYN
. Cela devrait être suffisant pour définir des états inactifs pour la plupart des processeurs du modèle 23, mais pourrait potentiellement causer des problèmes avec QX9650 comme indiqué ci-dessus.
Ainsi, au minimum, chaque groupe de processeurs qui a un ensemble d'états C distinct devrait être défini dans cette liste.
Zagacki et Ponnala, Intel Technology Journal 12 (3): 219-227, 2008 indiquent que les processeurs Yorkfield prennent effectivement en charge C2 et C4. Ils semblent également indiquer que la spécification ACPI 3.0a prend en charge les transitions uniquement entre les états C C0, C1, C2 et C3, ce qui, je suppose, peut également limiter le acpi_idle
pilote Linux aux transitions entre cet ensemble limité d'états C. Cependant, cet article indique que ce n'est pas toujours le cas:
Gardez à l'esprit que c'est l'état ACPI C, pas celui du processeur, donc ACPI C3 peut être HW C6, etc.
A noter également:
Au-delà du processeur lui-même, puisque C4 est un effort synchronisé entre les principaux composants en silicium de la plate-forme, le chipset Intel Q45 Express atteint une amélioration de 28% de la puissance.
Le chipset que j'utilise est en effet un chipset Intel Q45 Express.
La documentation Intel sur les états MWAIT est concise mais confirme le comportement ACPI spécifique au BIOS:
Les états C spécifiques au processeur définis dans les extensions MWAIT peuvent correspondre à des types d'état C définis par ACPI (C0, C1, C2, C3). La relation de mappage dépend de la définition d'un état C par l'implémentation du processeur et est exposée à OSPM par le BIOS à l'aide de la table _CST définie par ACPI.
Mon interprétation du tableau ci-dessus (combiné avec un tableau de Wikipedia , asm / intel-family.h et les articles ci-dessus) est:
Modèle 9 0x09 ( Pentium M et Celeron M ):
- Banias: C0, C1, C2, C3, C4
Modèle 13 0x0D ( Pentium M et Celeron M ):
- Dothan, Stealey: C0, C1, C2, C3, C4
Modèle 14 0x0E INTEL_FAM6_CORE_YONAH ( Enhanced Pentium M , Enhanced Celeron M ou Intel Core ):
- Yonah ( Core Solo , Core Duo ): C0, C1, C2, C3, C4, C4E / C5
Modèle 15 0x0F INTEL_FAM6_CORE2_MEROM (certains Core 2 et Pentium Dual-Core ):
- Kentsfield, Merom, Conroe, Allendale ( E2xxx / E4xxx et Core 2 Duo E6xxx, T7xxxx / T8xxxx , Core 2 Extreme QX6xxx , Core 2 Quad Q6xxx ): C0, C1, C1E, C2, C2E
Modèle 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
Compte tenu de la diversité de la prise en charge des états C au sein de la gamme de processeurs Core 2, il semble qu'un manque de prise en charge cohérente des états C ait pu être la raison pour ne pas tenter de les prendre en charge entièrement via le intel_idle
pilote. Je voudrais compléter complètement la liste ci-dessus pour toute la gamme Core 2.
Ce n'est pas vraiment une réponse satisfaisante, car cela me fait me demander combien d'énergie inutile est utilisée et la chaleur excessive a été (et est toujours) générée en n'utilisant pas pleinement les robustes états C MWAIT à économie d' énergie sur ces processeurs.
Chattopadhyay et al. 2018, Processeurs haute performance écoénergétiques: approches récentes pour concevoir un calcul haute performance écologique mérite d'être noté pour le comportement spécifique que je recherche dans le chipset Q45 Express:
Package C-state (PC0-PC10) - Lorsque les domaines de calcul, Core et Graphics (GPU) sont inactifs, le processeur a la possibilité d'économiser davantage d'énergie aux niveaux uncore et plate-forme, par exemple, le rinçage du LLC et la mise sous tension du contrôleur de mémoire et DRAM IO, et à un certain état, le processeur entier peut être éteint pendant que son état est préservé sur un domaine d'alimentation toujours allumé.
Comme test, j'ai inséré ce qui suit sur linux / drivers / idle / intel_idle.c ligne 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 }
};
à la intel_idle.c
ligne 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,
};
à la intel_idle.c
ligne 1073:
ICPU(INTEL_FAM6_CORE2_MEROM, idle_cpu_conroe),
ICPU(INTEL_FAM6_CORE2_PENRYN, idle_cpu_core2),
Après une compilation et un redémarrage rapides de mes nœuds PXE, dmesg
affiche maintenant:
[ 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
Et maintenant, PowerTOP montre:
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
J'ai finalement accédé aux états C améliorés du Core 2, et il semble qu'il y ait une baisse mesurable de la consommation d'énergie - mon compteur sur 8 nœuds semble être en moyenne au moins 5% inférieur (avec un nœud exécutant toujours l'ancien noyau) , mais je vais essayer d'échanger à nouveau les noyaux comme test.
Une note intéressante concernant la prise en charge de C4E - Mon processeur Yorktown Q9550S semble la prendre en charge (ou un autre sous-état de C4), comme en témoigne ci-dessus! Cela m'embrouille, car la fiche technique Intel sur le processeur Core 2 Q9000 (section 6.2) ne mentionne que les états C Normal (C0), HALT (C1 = 0x00), HALT étendu (C1E = 0x01), Stop Grant (C2 = 0x10) , Extended Stop Grant (C2E = 0x11), Sleep / Deep Sleep (C3 = 0x20) et Deeper Sleep (C4 = 0x30). Quel est cet état 0x31 supplémentaire? Si j'active l'état C2, alors C4E est utilisé à la place de C4. Si je désactive l'état C2 (forcer l'état C2E), alors C4 est utilisé à la place de C4E. Je soupçonne que cela peut avoir quelque chose à voir avec les indicateurs MWAIT, mais je n'ai pas encore trouvé de documentation pour ce comportement.
Je ne sais pas quoi faire de cela: l'état C1E semble être utilisé à la place de C1, C2 est utilisé à la place de C2E et C4E est utilisé à la place de C4. Je ne sais pas si C1 / C1E, C2 / C2E et C4 / C4E peuvent être utilisés avec intel_idle
ou s'ils sont redondants. J'ai trouvé une note dans cette présentation 2010 d'Intel Labs Pittsburgh qui indique que les transitions sont C0 - C1 - C0 - C1E - C0, et déclare en outre:
C1E n'est utilisé que lorsque tous les cœurs sont en C1E
Je crois que cela doit être interprété comme l'état C1E est entré sur d'autres composants (par exemple la mémoire) uniquement lorsque tous les cœurs sont dans l'état C1E. Je suppose également que cela s'applique de manière équivalente aux états C2 / C2E et C4 / C4E (bien que C4E soit appelé "C4E / C5", je ne suis donc pas certain que C4E soit un sous-état de C4 ou si C5 est un sous-état). état de C4E. Les tests semblent indiquer que C4 / C4E est correct). Je peux forcer l'utilisation de C2E en commentant l'état C2 - cependant, cela entraîne l'utilisation de l'état C4 au lieu de C4E (plus de travail peut être nécessaire ici). Espérons qu'il n'y ait aucun processeur de modèle 15 ou 23 qui ne possède pas l'état C2E, car ces processeurs seraient limités à C1 / C1E avec le code ci-dessus.
En outre, les valeurs des drapeaux, de la latence et de la résidence pourraient probablement être affinées, mais simplement prendre des suppositions éclairées basées sur les valeurs de ralenti de Nehalem semble fonctionner correctement. Plus de lecture sera nécessaire pour apporter des améliorations.
J'ai testé cela sur 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 ) et Core 2 Extreme QX9650 , et I n'ont trouvé aucun problème au-delà de la préférence susmentionnée pour les états C2 / C2E et C4 / C4E.
Non couvert par cette modification de pilote:
- Les Core Solo / Core Duo d'origine ( Yonah , non Core 2) sont de la famille 6, modèle 14. C'est bien parce qu'ils supportaient les états C C4E / C5 (Enhanced Deep Sleep) mais pas les états C1E / C2E et auraient besoin de leur propre définition inactive.
Les seuls problèmes auxquels je peux penser sont:
- Les Core 2 Solo SU3300 / SU3500 (Penryn-L) sont de la famille 6, modèle 23 et seront détectés par ce pilote. Cependant, ils ne sont pas Socket LGA775, ils ne peuvent donc pas prendre en charge l'état C C1E Enhanced Halt. De même pour le Core 2 Solo ULV U2100 / U2200 ( Merom-L ). Cependant, le
intel_idle
pilote semble choisir le C1 / C1E approprié en fonction de la prise en charge matérielle des sous-états.
- Le Core 2 Extreme QX9650 (Yorkfield) ne prendrait pas en charge les états C C2 ou C4. J'ai confirmé cela en achetant un processeur Optiplex 780 et QX9650 Extreme d'occasion sur eBay. Le processeur prend en charge les états C C1 et C1E. Avec cette modification de pilote, le processeur est inactif dans l'état C1E au lieu de C1, il y a donc probablement des économies d'énergie. Je m'attendais à voir l'état C C3, mais il n'est pas présent lors de l'utilisation de ce pilote, je devrai peut-être approfondir cela.
J'ai réussi à trouver une diapositive à partir d'une présentation Intel 2009 sur les transitions entre les états C (c.-à-d. Deep Power Down):
En conclusion, il s'avère qu'il n'y avait aucune raison réelle pour le manque de support Core 2 dans le intel_idle
pilote. Il est clair maintenant que le code de remplacement d'origine pour "Core 2 Duo" ne traitait que les états C C1 et C2, ce qui aurait été beaucoup moins efficace que la acpi_idle
fonction qui gère également l'état C C3. Une fois que je savais où chercher, la mise en œuvre du support était facile. Les commentaires utiles et autres réponses ont été très appréciés, et si Amazon écoute, vous savez où envoyer le chèque.
Cette mise à jour a été validée pour github . Je vais bientôt envoyer un patch au LKML.
Mise à jour : J'ai également réussi à déterrer un Socket T / LGA775 Allendale ( Conroe ) Core 2 Duo E2220, qui est de la famille 6, modèle 15, j'ai donc ajouté un support pour cela également. Ce modèle ne prend pas en charge l'état C4 C, mais prend en charge C1 / C1E et C2 / C2E. Cela devrait également fonctionner pour d'autres puces basées sur Conroe ( E4xxx / E6xxx ) et éventuellement tous les processeurs Kentsfield et Merom (non Merom-L).
Mise à jour : j'ai finalement trouvé des ressources de réglage MWAIT. Cet article Power vs Performance et ces états Deeper C et blog de latence accrue contiennent tous les deux des informations utiles sur l'identification des latences inactives du processeur. Malheureusement, cela ne signale que les latences de sortie qui ont été codées dans le noyau (mais, fait intéressant, seuls les états matériels pris en charge par le processeur):
# 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
et des divers gouverneurs de performances. Quels étatspowertop
apparaissent sur votre système?