FreeBSD WikiのTuningPowerConsumptionの日本語訳

家鯖の消費電力を下げるべく情報を集めていたところ、FreeBSD WikiのTuningPowerConsumption記事が非常に参考になったので日本語訳してみた。

Alexandar Motin 記す:

FreeBSDでの消費電力削減に関して私の知るところをまとめ、FreeBSD 8.x/9.xで実装されたいくつかの新しい事柄を説明しようと思います。このストーリーの主人公は、C2D T7700 2.4GHz CPU、965GMチップセット、SATA HDDを搭載した私の12インチAcer TravelMate 6292ラップトップです。

現代のシステム、とりわけラップトップは数多くの省エネ技術を搭載しています。それらのいくつかは自動で機能するものの、その他は効果を発揮するための明示的な設定と特別なシステムチューニング、トレードオフが存在します。

ここから順にみていきます:

CPUはシステム内で最も電力を消費する部分です。 最大負荷時では、CPUだけで40W以上を消費するでしょうが、実際のラップトップ利用において最も重要なのはアイドル時消費電力です。 Core2Duo T7700 CPUは2つのコアを持ち、2.4GHzで駆動し、2400/2000/1600/1200/800MHzのPステートからなるEISTテクノロジに対応し、C1/C2/C3の待機Cステートに加えスロットリングをサポートします。 ではどのようにそれらを使えばいいのでしょうか:

Pステートとスロットリング

powerd(8)を有効にし、システム負荷に応じたCPU周波数の調整により消費電力を抑えます。

r265329以前では、周波数はEISTとスロットリング技術を混合して制御されていました。 前者がコア周波数と電圧の両方を制御し、後者はコア周波数のみを制御します。 両技術は電力削減に良い影響をもたらしますが、スロットリングの効果は小さく、C2ステートを使うことで完全に隠れてしまうでしょう。 そんなわけで、/boot/loader.confに設定を追加しスロットリング制御を無効化することをお勧めします:

<conf code> hint.p4tcc.0.disabled=1 hint.acpi_throttle.0.disabled=1 </code>

これ以後、sysctlはEIST周波数のみを表示します:

dev.cpu.0.freq_levels: 2400/35000 2000/28000 1600/22000 1200/16000 800/14000

新規インストールにおいて、ACPIとP4TCCスロットリングは、今やデフォルトで無効になっています。

Intel TurboBoost動作の制御のため、ACPIは公称周波数より1MHz高い追加の性能レベルを表示するかもしれません。 例えばCore i7-870では以下のように見えるでしょう:

dev.cpu.0.freq_levels: 2934/106000 2933/95000 2800/82000 ...

値の2933は2.93GHzを意味しますが、2934は状況に依存し3.2~3.6GHzを意味します。

私のケースでは、周波数/電圧制御により約5Wのアイドル電力を削減しました。

Cステート

C1ステートはCPUが活動していない間、コアのいくつかの部分のクロックを停止します。 これは安全で、性能へのインパクトも少なく、昔からCPUでサポートされています。 システムは標準でC1ステートを使います。

C2ステートは待機時にCPUの全コアクロックの停止を可能にします。 これもまた安上がりですが、利用にあたりACPI/チップセット/CPU間の正確な協調動作が求められます。 C2ステートの有効化は/etc/rc.confに以下の記述を追加します:

performance_cx_lowest="Cmax"
economy_cx_lowest="Cmax"

powerdの利用時は、本ステートの影響はそれほど大きくありませんが、依然として注目に値します。

C3ステートは、CPUの完全な内部クロック停止、電圧の削減、そしてシステムバスからの切り離しを可能にします。 このステートは更なる省エネ効果をもたらすものの、安上がりではなく、トレードオフが求められます。 C3ステートでCPUが完全に止まるや否や、FreeBSDがSMP環境でイベントソースとして利用する各CPUコア内のローカルAPICタイマーは機能しなくなります。システムタイムが止まり、スケジューリングを破壊し、これはシステムを死へと誘います。 この問題に対する唯一の解決策は、いくつかの外部タイマを使う事です。

C1Eとして知られる疑似ステートもあります。 これは、現代的なCPUとCステート非対応のOSとがより良く動くための次善策です。 BIOSで有効にすると、OSからC1ステートが要求された際、CPUはより深いCステートに入れるようになります。

典型的にAMD CPUとBIOSは実際のCステートをOSに見せませんが、かわりにC1Eメカニズムを用いるのみです。 例えば次のように働くでしょう:OSがいくつかのCPUコアにC1を要求するとコアはC2に入りますが、CPUパッケージの全コアがC2である時は、パッケージの全てがC3になるという具合です。 あいにく、この働きはOSから完全に隠蔽されています。

FreeBSD 8.x

もともと、SMP時代以前、FreeBSDはi8254(周波数用)とRTC(ステータス用)のチップセットタイマを使っていました。 FreeBSD 8.xはこれらをSMPシステム用に復活させました。 これらを使うために、/boot/loader.confでローカルAPICタイマを無効化することができます:

hint.apic.0.clock=0

C3の電圧昇降には、もちろんCPUは時間を必要とします(私のシステムでは57マイクロ秒)。 これはつまり、頻繁にアクティブになるシステムにおいて、C3ステートは効率的に利用されないという事です。 非アクティブ期間を増やすため、可能な限り割り込みレートを下げるべきです。loader.confに以下を追加します:

kern.hz=100

システムの応答時間がわずかに増えるかもしれませんが、ラップトップでは重大事ではありません。 同様に、RTCクロックの代わりに静的コレクション用途のi8254タイマーを用いて、スケジューリング精度に必要な1コアあたり秒間128回の追加割り込みを避けるとよいかもしれません。そのためには別の新規オプションを追加します:

hint.atrtc.0.clock=0

結果として、システムはコアあたり100回の割り込みで済み、CPUは効率的にC3を使っています:

%sysctl dev.cpu |grep cx
dev.cpu.0.cx_supported: C1/1 C2/1 C3/57
dev.cpu.0.cx_lowest: C3
dev.cpu.0.cx_usage: 0.00% 0.00% 100.00% last 7150us
dev.cpu.1.cx_supported: C1/1 C2/1 C3/57
dev.cpu.1.cx_lowest: C3
dev.cpu.1.cx_usage: 0.00% 0.00% 100.00% last 2235us

効率的なC3使用の結果、C2+powerdと比べて約2Wの削減です。

AMD CPUにおいてC1Eステートへの突入は、予期せぬ制御不能なC3ステートへ突入しているかもしれず、ローカルAPICタイマーの停止を引き起こす可能性があるため、FreeBSD 8.xはC1E機能を完全にブロックします。

FreeBSD 9.x

FreeBSD 9.xは新イベントタイマーサブシステムeventtimers(4)を含みます。これは、殆どの現代的なチップセットに存在しCPU電源管理のための不変のHPETを含む、より多くの種類のタイマーハードウェアに対応しています。 システムは最適と思われるタイマーを自動的に選択しますが、sysctlを通してタイマーの確認と動的な変更が可能です。

またeventtimers(4)は、何かする必要が出た時にだけ割り込みを生成する、ワンショットタイマー制御モードに対応します。 これによりkern.hz変数値を減らす必要がなくなり、マルチコアシステムでさえアイドル時の秒間合計割り込み数がたった50~100回程度になります。 それでもなおkern.hzの削減は、いくつかの電源効率を考慮せずに作られたアプリケーションに対して有効です。

FreeBSD 9.xでは具体的なCステートと現在のイベントタイマが安全に使えるかどうかのチェックが追加され、場合によってはより安全となるようC2/C3が自動的にブロックされます。 そうはいっても、いくつかのワークロードにおいて性能低下の可能性があるため、Cステートの利用は現在デフォルトでは有効になっておらず、手動で有効にしなければなりません。 それと同時に、より新しいCPUにおいて、深いCステートを有効にすることはTurboBoost技術の利用を可能とし、これはシングルスレッドアプリケーションの性能向上につながります。

AMD CPUの場合、FreeBSD 9.xはローカルAPICタイマが使われている場合のみC1Eステートをブロックします。 起動の時点でローカルAPICタイマが使われていた場合、次回再起動までC1Eはブロックされるでしょう。 C1Eの動作を許可するには、他のタイマが使われるよう強制する必要があるかもしれません。

画面のバックライトは、そこそこ電気を食います。 私のラップトップでは、明るさによって最小1.5W~最大4Wでした。 したがって、明るさを(ハード的またはソフト的に)制御する方法を見つけ、状況に応じて最小限のレベルに合わせるのが良いでしょう。 私の場合、それはハードウェアのボタンで制御されます。 他のいくつかのラップトップでは、明るさ制御をacpi_video(4)でサポートされるsysctlhw.acpi.video.lcd0.brightnessを通して制御できます。 グラフィックチップは使うドライバやその設定に応じて、著しい量の電力を消費する可能性があります。

Intel GPU

SandyBridge/IvyBridge CPUのラップトップのグラフィックスについて、新しいKMSべースの“intel”ドライバは“vesa”ドライバと比べて消費電力が3W増加するかもしれません。 /boot/loader.confに以下の行を追加します:

drm.i915.enable_rc6=7

電力を抑えるGPUの待機ステートの使用を有効化し、消費電力を削減します。

このヒントは最近のシステムには時代遅れかもしれません。sysctl -d -a | grep rc6を実行し、変数名が変わってないか確認してください。

参考:

NVIDIA Optimus

NVIDIA Optimus対応GPU搭載のラップトップを持っており、BIOSでGPUオフができなければ、単体NVIDIA GPUの無効化に使われる全ての基地のACPIコールを調査するお手製スクリプトがあります:

% fetch https://people.freebsd.org/~xmj/turn_off_gpu.sh
% make -C /usr/ports/sysutils/acpi_call install clean
% vim turn_off_gpu.sh  # read it before executing!
% sh turn_off_gpu.sh   # as root user

成功したACPIコールは、以下に格納されます。

/root/.gpu_method

そして後続の処理で使用されます。 ASUSのウルトラブックにおいて、これは6~8Wを節約し、バッテリー駆動時間を少なくとも3時間延ばします。 起動時にGPUを無効化するために、rc.localあるいは他のカスタムrc.dスクリプトに入れることができます。 上述のIntel GPUセクションに加えて/boot/loader.confで利用することもできます。

このラップトップは2枚の1GB DDR2-667 SODIMMメモリモジュールが組み込まれています。 そのうち1枚を取ることで約1Wの節約、2枚の1GBモジュールを1枚の2GBモジュールに置き換えることでも約0.5Wの節約です。

PCIバスはデバイスの電源管理手法を提供します。 たとえば、私は全く使わないFireWireコントローラと殆ど使うことがないEHCI USBコントローラを持っています。 これらを無効化することで3Wの電力削減ができます。 全ての不要なPCIデバイスの無効化のために、それらのドライバを外したカーネルをビルドし、loader.confに以下の行を追加するべきです:

hw.pci.do_power_nodriver=3

デバイスを再び有効化するために必要なことは、それらのドライバをモジュールとして単に読み込むだけです。 8.xの新しいEHCI USBドライバは以前のものよりも消費電力が少なくなっています。

WiFiとBluetoothアダプタは、使用時(私の場合iwn(4) WiFiが接続されている時で最大2W)ないし単に有効にしただけ(0.5W)でも無視できない電力を消費します

ある種のWiFiアダプタ(私のiwm(4)のように)は省エネモードに対応し、非アクティブ時に無線通信を停止します。 これは

powersave

オプションをifconfigインタフェースを追加することで有効になります。 わずかな接続レイテンシの増加と引き換えに、大幅なWiFi消費電力を削減するでしょう。

私は驚いたのですが、内蔵HDAモデムは使用していなくとも約1Wの電力を消費していました。 私は最も過激な解決策、すなわちソケットから物理的に取り外す選択をしました。 モデムがあった場所のケース表面温度は下がりました。

サウンドが生成する割り込み数を減らすため、loader.confに以下を追加しました:

hw.snd.latency=7

2012-03-10のFreeBSD 9-STABLE以前では、最大バッファサイズを増やすことも有益かもしれません:

hint.pcm.0.buffersize=65536
hint.pcm.1.buffersize=65536

まず、よくある推奨方法は一時ファイル用にtmpfsを使う事です。 RAMは消費電力への影響が少なく、速くanyway with you。 待機ドライブの自動スピンダウン設定を試したくなるかもしれませんが、システムドライブしかないのであれば注意すべきです。スピンアップはドライブの寿命を縮めます。 (SATA SSDを買うまでの)数ヵ月間、私は内蔵のPCI sdhciカードリーダをメインファイルシステムとして使う事に成功しました。 ランダムリード要求についてはHDDより高速ですが、ランダムライトは非常に低速です。 加えて、SDカードは殆ど電力を食いません。 USBフラッシュドライブを使う事も可能ですが、EHCI USBコントローラの消費電力に比べれば効果は限定的です。 私の2.5インチ日立製SATA HDDをスピンダウンすると、約1Wの削減です。 完全に取り外すと2Wの削減です。

PATAと比べると、SATAインタフェースはデータ転送に差動シグナルを用います。 正常動作のため、アイドル時でも疑似的なランダムスクランブルシーケンスを転送しなければなりません。 お察しの通り、これは電力を要求します。 しかしSATAは2つの省エネモードを実装しています:PARTIALとSLUMBERです。 これらモードは、ホストとデバイの両方が対応していれば、どちらからでも有効にできます。 PARTIALモードはスクランブル化を止めるだけで、ニュートラルなリンク状態を保ち、復帰時間は50~100マイクロ秒です。 SLUMBERモードはインタフェースの電源を完全に落とし、各復帰時間は3~10ミリ秒です。

ata(4)ドライバはSATA電源管理に対応しています。 hint.ata.X.pm_levelチューニング変数で制御することができます。 1にするとドライブ自身の省エネ状態が開始されます。 2と3で、AHCI互換コントローラが毎コマンド完了後にPARTIAL/SLUMBERへの遷移を許可します。 新しいahci(4)ドライバはhint.ahcich.X.pm_levelチューニング変数も持っています。 これは4と5のモードもサポートし、性能劣化を最小化するモードです。 SATA省エネモードはドライブのホットスワップを困難にすることに留意してください。なぜなら、リンクの電源が落ちている時、コントローラはドライブの存在を検出することが不可能だろうからです。

私の場合、PARTIALモードは0.5W、SLUMBERは0.8Wの削減です。

以下のコマンドを実行することで、USBデバイスは個々に省エネモードの切り替えができます:

# このコマンドはデータトラフィックがない間のUSBデバイスの自動サスペンドを有効にします
usbconfig -d X.Y power_save
# このコマンドは与USBデバイスの省エネモードを無効にします
usbconfig -d X.Y power_on

USBハブを除く全てのデバイスのデフォルト値は“power on”です。 USBデバイスの省エネモードを有効にする前に、デバイスのコンフィギュレーションでスクリプタ、すなわち“bmAttributes”フィールドがデバイスが遠隔起動に対応しているかを確認すべきです。 USBのサスペンド/レジューム遅延を規格に適合させるため、システムタイマーのティック間隔が250Hz未満でUSB省エネモードを有効にするのは非推奨です。 省エネ機能は同様にUSBデバイス/ガジェットモードにも適用可能です。

私は何を得たでしょうか? 実際のシステム消費電力をモニタするため、acpiconf -i0コマンドでACPIバッテリが提供する情報を見てみましょう:

元のシステム:

Design capacity:        4800 mAh
Last full capacity:     4190 mAh
Technology:             secondary (rechargeable)
Design voltage:         11100 mV
Capacity (warn):        300 mAh
Capacity (low):         167 mAh
Low/warn granularity:   32 mAh
Warn/full granularity:  32 mAh
Model number:           Victoria
Serial number:          292
Type:                   LION
OEM info:               SIMPLO
State:                  discharging
Remaining capacity:     93%
Remaining time:         2:24
Present rate:           1621 mA
Voltage:                12033 mV

チューニングしたシステム:

%acpiconf -i0
Design capacity:        4800 mAh
Last full capacity:     4190 mAh
Technology:             secondary (rechargeable)
Design voltage:         11100 mV
Capacity (warn):        300 mAh
Capacity (low):         167 mAh
Low/warn granularity:   32 mAh
Warn/full granularity:  32 mAh
Model number:           Victoria
Serial number:          292
Type:                   LION
OEM info:               SIMPLO
State:                  discharging
Remaining capacity:     94%
Remaining time:         4:47
Present rate:           826 mA
Voltage:                12231 mV

このチューニングにより、なんとバッテリー駆動時間が2倍、デフォルト設定の2時間24分から4時間47分になりました。 冷却ファンは以前は常に動いていましたが、今ではシステムがアイドル時は殆ど待機状態です、 同じシステムのメーカーチューニングされたプリインストールのWindows XPでは、最大3時間20分ということでした。

– Alexander Motin

  • 2019-12-01 原文Rev.#29で翻訳しなおし
  • 2015-03-23 翻訳開始
  • freebsd/tuning_power_consumption.txt
  • 最終更新: 2019-12-01 19:16
  • by Decomo