Core 2 CPUの電力状態(「Cステート」)を調査している間、実際には、ほとんどのレガシーIntel Core / Core 2プロセッサーのサポートを実装することができました。すべての背景情報を含む完全な実装(Linuxパッチ)がここに文書化されています。
これらのプロセッサに関する情報を蓄積するにつれて、Core 2モデルでサポートされているCステートは、以前のプロセッサと後のプロセッサの両方よりもはるかに複雑であることが明らかになり始めました。これらはエンハンストCステート(または「CxE」)と呼ばれ、パッケージ、個々のコア、およびチップセット上の他のコンポーネント(メモリなど)を含みます。intel_idle
ドライバーがリリースされた時点では、コードは特に成熟しておらず、Cステートのサポートが競合するいくつかのCore 2プロセッサーがリリースされていました。
Core 2 Solo / Duo C-stateサポートに関するいくつかの説得力のある情報が2006年のこの記事で見つかりました。これはWindowsでのサポートに関連していますが、これらのプロセッサでの堅牢なハードウェアCステートサポートを示しています。Kentsfieldに関する情報は実際のモデル番号と矛盾するため、以下のヨークフィールドを実際に参照していると思います。
...クアッドコアIntel Core 2 Extreme(Kentsfield)プロセッサーは、5つのパフォーマンスと省電力テクノロジーをすべてサポートします— Intel SpeedStep(EIST)、Thermal Monitor 1(TM1)およびThermal Monitor 2(TM2)、古いオンデマンドクロック変調(ODCM)、および拡張C状態(CxE)。Enhanced Halt(C1)状態のみを特徴とするIntel Pentium 4およびPentium D 600、800、900プロセッサと比較して、この機能はIntel Core 2プロセッサ(およびIntel Core Solo / Duoプロセッサ)で拡張されています。 Stop Grant(C2)、Deep Sleep(C3)、Deeper Sleep(C4)を含む、プロセッサの考えられるすべてのアイドル状態。
2008年のこの記事では、Core 2 DuoやCore 2 Quadを含むマルチコアIntelプロセッサでのコアごとのCステートのサポートについて説明しています(Dellのこのホワイトペーパーには、追加の有用な背景資料があります)。
コアCステートはハードウェアCステートです。CC1やCC3など、いくつかのコアアイドル状態があります。ご存じのように、最近リリースされたCore Duo T5000 / T7000モバイルプロセッサなど、一部のサークルではPenrynとして知られている最新のプロセッサには複数のコアがあります。以前はCPU /プロセッサと考えていたものに、実際には複数の汎用CPUが側面にあります。Intel Core Duoのプロセッサチップには2つのコアがあります。Intel Core-2 Quadには、プロセッサチップごとに4つのコアがあります。これらの各コアには、独自のアイドル状態があります。これは、1つのコアがアイドル状態で、別のコアがスレッドでの作業に苦労している可能性があるためです。したがって、コアCステートは、これらのコアのいずれかのアイドル状態です。
ドライバーに関する追加の背景を提供する2010年のIntelのプレゼンテーションを見つけましたintel_idle
が、残念ながらCore 2のサポートの欠如については説明していません。
この実験ドライバーは、Intel Atomプロセッサー、Intel Core i3 / i5 / i7プロセッサー、および関連するIntel Xeonプロセッサーのacpi_idleに優先します。Intel Core2プロセッサ以前はサポートしていません。
上記のプレゼンテーションは、intel_idle
ドライバーが「メニュー」CPUガバナーの実装であることを示しています。これはLinuxカーネル構成に影響を及ぼします(CONFIG_CPU_IDLE_GOV_LADDER
vs.などCONFIG_CPU_IDLE_GOV_MENU
)。ラダーとメニューガバナーの違いはこの回答で簡潔に説明されています。
デルには、CステートC0からC6への互換性をリストした役立つ記事があります。
モードC1〜C3は基本的にCPU内で使用されるクロック信号をカットすることで機能し、モードC4〜C6はCPU電圧を下げることで機能します。「拡張」モードでは、両方を同時に実行できます。
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
この表(後でいくつかのケースで間違っていることがわかりました)から、Core 2プロセッサーでのC状態のサポートにはさまざまな違いがあったようです(Coreを除くほとんどすべてのCore 2プロセッサーがSocket LGA775であることに注意してください) 2ソケットBGA956およびMerom / PenrynプロセッサであるSolo SU3500「Intel Core」Solo / Duoプロセッサは、Socket PBGA479またはPPGA478のいずれかです。
この記事には、テーブルの追加の例外が見つかりました。
IntelのCore 2 Duo E8500はCステートC2およびC4をサポートしていますが、Core 2 Extreme QX9650はサポートしていません。
興味深いことに、QX9650はヨークフィールドプロセッサー(Intelファミリー6、モデル23、ステッピング6)です。参考までに、私のQ9550SはIntelファミリー6、モデル23(0x17)、ステップ10で、CステートC4をサポートしていると思われます(実験により確認済み)。さらに、Core 2 Solo U3500はQ9550Sと同じCPUID(ファミリ、モデル、ステッピング)を持っていますが、非LGA775ソケットで使用できるため、上記の表の解釈が混乱します。
明らかに、このプロセッサモデルのCステートサポートを識別するために、少なくともステップ実行までCPUIDを使用する必要があり、場合によっては不十分な場合があります(現時点では未定)。
CPUアイドル情報を割り当てるためのメソッドシグネチャは次のとおりです。
#define ICPU(model, cpu) \
{ X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (unsigned long)&cpu }
where model
はasm / intel-family.hに列挙されています。このヘッダーファイルを調べると、IntelのCPUには、Intelファミリ6のモデル番号と一致するように見える8ビットの識別子が割り当てられていることがわかります。
#define INTEL_FAM6_CORE2_PENRYN 0x17
上記から、Intelファミリ6、モデル23(0x17)がとして定義されていINTEL_FAM6_CORE2_PENRYN
ます。これは、ほとんどのモデル23プロセッサのアイドル状態を定義するには十分ですが、上記のようにQX9650で問題を引き起こす可能性があります。
したがって、最低限、別個のC状態セットを持つプロセッサの各グループをこのリストで定義する必要があります。
Zagacki and Ponnala、Intel Technology Journal 12(3):219-227、2008は、ヨークフィールドプロセッサが実際にC2とC4をサポートしていることを示しています。また、ACPI 3.0a仕様はC状態C0、C1、C2、C3の間の遷移のみをサポートしていることを示しているようですacpi_idle
。ただし、この記事では、常にそうであるとは限らないことを示しています。
プロセッサの状態ではなく、ACPI Cの状態であることに注意してください。したがって、ACPI C3はHW C6などになる可能性があります。
また注意事項:
プロセッサ自体を超えて、C4はプラットフォームの主要なシリコンコンポーネント間で同期された作業であるため、Intel Q45 Expressチップセットは28%の電力改善を達成します。
私が使用しているチップセットは、確かにIntel Q45 Expressチップセットです。
MWAITのインテルの資料は述べて簡潔ですが、BIOS固有のACPIの動作を確認しました。
MWAIT拡張で定義されたプロセッサ固有のC状態は、ACPIで定義されたC状態タイプ(C0、C1、C2、C3)にマップできます。マッピング関係は、プロセッサー実装によるCステートの定義に依存し、ACPI定義の_CSTテーブルを使用してBIOSによってOSPMに公開されます。
上記の表(ウィキペディアの表、asm / intel-family.h、および上記の記事と組み合わせて)の私の解釈は次のとおりです。
モデル9 0x09(Pentium MおよびCeleron M):
モデル13 0x0D(Pentium MおよびCeleron M):
モデル14 0x0E INTEL_FAM6_CORE_YONAH(Enhanced Pentium M、Enhanced Celeron MまたはIntel Core):
- Yonah(コアソロ、Core Duoプロセッサ):C0、C1、C2、C3、C4、C4E / C5
モデル15 0x0F INTEL_FAM6_CORE2_MEROM(一部のコア2およびPentiumデュアルコア):
- Kentsfield、Merom、Conroe、Allendale(E2xxx / E4xxxおよびCore 2 Duo E6xxx、T7xxxx / T8xxxx、Core 2 Extreme QX6xxx、Core 2 Quad Q6xxx):C0、C1、C1E、C2、C2E
モデル23 0x17 INTEL_FAM6_CORE2_PENRYN(コア2):
- Merom-L / Penryn-L:?
- Penryn(Core 2 Duo 45-nm mobile):C0、C1、C1E、C2、C2E、C3、C4、C4E / C5、C6
- ヨークフィールド(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
Core 2プロセッサのみでのC状態サポートの多様性から、C状態の一貫したサポートの欠如が、intel_idle
ドライバーを介してそれらを完全にサポートしようとしない理由である可能性があります。上記のリストをCore 2ライン全体について完全に完成させたいと思います。
これらのプロセッサで堅牢な省電力MWAIT Cステートを完全に利用していないために、どのくらいの不要な電力が使用され、過剰な熱が発生している(まだ発生しているのか)ので、これは本当に満足のいく答えではありません。
Chattopadhyay 等。2018年、エネルギー効率の高い高性能プロセッサ:グリーン高性能コンピューティングを設計するための最近のアプローチは、Q45 Expressチップセットで求めている特定の動作に注目する価値があります。
パッケージC状態(PC0-PC10)-計算ドメイン、コアおよびグラフィックス(GPU)がアイドル状態の場合、プロセッサは、LLCをフラッシュしたり、メモリコントローラーとDRAM IO、およびある状態では、常時オンの電源ドメインでその状態が保持されている間、プロセッサ全体をオフにすることができます。
テストとして、linux / drivers / idle / intel_idle.c行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 }
};
でintel_idle.c
行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,
};
でintel_idle.c
行1073:
ICPU(INTEL_FAM6_CORE2_MEROM, idle_cpu_conroe),
ICPU(INTEL_FAM6_CORE2_PENRYN, idle_cpu_core2),
PXEノードをすばやくコンパイルして再起動すると、次のdmesg
ように表示されます。
[ 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
そして今、PowerTOPは以下を示しています。
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
最終的にEnhanced Core 2 Cステートにアクセスしましたが、消費電力が測定可能なほど低下しているように見えます-8つのノード上のメーターは少なくとも5%低いようです(1つのノードがまだ古いカーネルを実行しています) 、しかし、テストとしてカーネルを再度交換してみます。
C4Eのサポートに関する興味深いメモ-My Yorktown Q9550Sプロセッサーは、上記で証明されているように、それをサポートしているようです(またはC4の他のサブステート)。Core 2 Q9000プロセッサー(セクション6.2)のIntelデータシートには、 C状態Normal(C0)、HALT(C1 = 0x00)、Extended HALT(C1E = 0x01)、Stop Grant(C2 = 0x10)のみが記載されているため、これは混乱を招きます、拡張ストップ許可(C2E = 0x11)、スリープ/ディープスリープ(C3 = 0x20)、ディープスリープ(C4 = 0x30)。この追加の0x31状態は何ですか?状態C2を有効にすると、C4の代わりにC4Eが使用されます。状態C2を無効にすると(強制的に状態C2E)、C4Eの代わりにC4が使用されます。これはMWAITフラグと関係があるのではないかと思いますが、この動作に関するドキュメントはまだ見つかりません。
これをどうすればよいかわかりません:C1E状態はC1の代わりに使用されるように見え、C2はC2Eの代わりに使用され、C4EはC4の代わりに使用されます。C1 / C1E、C2 / C2E、およびC4 / C4Eを併用できるintel_idle
かどうか、またはそれらが冗長であるかどうかは不明です。Intel 2010のピッツバーグによる2010年のプレゼンテーションで、移行がC0-C1-C0-C1E-C0であり、さらに次のように述べているメモを見つけました。
C1Eは、すべてのコアがC1Eにある場合にのみ使用されます
すべてのコアがC1E状態にある場合にのみ、C1E状態が他のコンポーネント(メモリなど)に入力されると解釈されるはずです。また、これをC2 / C2E状態とC4 / C4E状態にも同様に適用します(C4Eは「C4E / C5」と呼ばれますが、C4EがC4のサブ状態であるか、C5がサブ状態であるかは不明です。 C4Eの状態。テストではC4 / C4Eが正しいことを示しているようです。C2状態をコメント化することでC2Eを強制的に使用できます-ただし、これによりC4Eの代わりにC4状態が使用されます(ここでさらに作業が必要になる場合があります)。状態C2Eを欠くモデル15またはモデル23のプロセッサーがないことを願っています。これらのプロセッサーは上記のコードではC1 / C1Eに制限されるためです。
また、フラグ、待機時間、および常駐値はおそらく微調整される可能性がありますが、Nehalemアイドル値に基づいた経験に基づいた推測を行うだけでうまくいくようです。改善するには、さらに読む必要があります。
これをCore 2 Duo E2220(Allendale)、Dual Core Pentium E5300(Wolfdale)、Core 2 Duo E7400、Core 2 Duo E8400(Wolfdale)、Core 2 Quad Q9550S(Yorkfield)、Core 2 Extreme QX9650、およびIでテストしました前述の状態C2 / C2EおよびC4 / C4Eの優先度を超える問題は見つかりませんでした。
このドライバーの変更の対象外:
- オリジナルのCore Solo / Core Duo(Yonah、非Core 2)はファミリー6、モデル14です。これは、C1E / C2E状態ではなくC4E / C5(Enhanced Deep Sleep)C状態をサポートしており、その必要があるためです。独自のアイドル定義。
私が考えることができる唯一の問題は次のとおりです。
- Core 2 Solo SU3300 / SU3500(Penryn-L)はファミリー6、モデル23であり、このドライバーによって検出されます。ただし、これらはSocket LGA775ではないため、C1E Enhanced Halt Cステートをサポートしない場合があります。Core 2 Solo ULV U2100 / U2200(Merom-L)についても同様です。ただし、
intel_idle
ドライバーは、サブ状態のハードウェアサポートに基づいて適切なC1 / C1Eを選択するようです。
- Core 2 Extreme QX9650(ヨークフィールド)は、CステートC2またはC4をサポートしていないと報告されています。eBayで中古のOptiplex 780およびQX9650 Extremeプロセッサーを購入することでこれを確認しました。プロセッサは、CステートC1およびC1Eをサポートします。このドライバーの変更により、CPUはC1ではなくC1E状態でアイドル状態になるため、おそらくいくらかの電力節約があります。CステートC3が表示されると予想していましたが、このドライバーを使用するときには表示されないため、これをさらに調べる必要があります。
2009年のインテルのCステート間の遷移に関するプレゼンテーション(つまり、ディープパワーダウン)からスライドを見つけることができました。
結論として、intel_idle
ドライバーにCore 2のサポートがないという本当の理由はなかったことがわかりました。「Core 2 Duo」の元のスタブコードは、CステートC1とC2のみを処理し、C acpi_idle
ステートC3も処理する関数よりもはるかに効率が悪かったことが明らかです。どこを見ればよいかがわかれば、サポートの実装は簡単でした。有益なコメントやその他の回答は大歓迎でした。Amazonがリッスンしている場合は、小切手をどこに送るべきかを知っています。
この更新はgithubにコミットされています。LKMLへのパッチをすぐにメールで送信します。
更新:ファミリ6、モデル15であるSocket T / LGA775 Allendale(Conroe)Core 2 Duo E2220 も掘り下げたので、そのサポートも追加しました。このモデルは、CステートC4のサポートはありませんが、C1 / C1EおよびC2 / C2Eをサポートしています。これは、他のConroeベースのチップ(E4xxx / E6xxx)およびおそらくすべてのKentsfieldおよびMerom(非Merom-L)プロセッサーでも動作するはずです。
更新:ようやくMWAITチューニングリソースが見つかりました。このPower vs. Performanceの記事と、Deeper Cの状態とレイテンシの増加に関するブログ投稿には、CPUのアイドルレイテンシの特定に関する有用な情報が含まれています。残念ながら、これはカーネルにコーディングされた終了レイテンシのみを報告します(興味深いことに、プロセッサがサポートするハードウェアの状態のみ)。
# 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
。powertop
システムに表示される状態は何ですか?