動的にCPUクロックや電圧を変更するcpufreqの概要とcpufreqdデーモンについて
Linuxカーネル*1には、CPUが持っている動的なクロック周波数や電圧(対応している場合)の変更機能を利用するためのcpufreqという仕組みがある。
(2014/11/14)本記事の内容は最新ではないため、まとめドキュメントの各セクションを参照。
- CPUドライバ
- カーネルの設定
- クロック周波数の決定
- governorの手動変更
- cpufreqに関する現在の各種状態の取得
- ondemand governorでの動作時において、CPUクロックを上げるCPU使用率のしきい値
- cpufreqdで実用的な動的クロック変更を行う
CPUドライバ
クロックや電圧の変更をする方法はCPUによって違うため、CPUの種類ごとにデバイスドライバが用意されている。cpufreqを使用するには、- 使用しているCPUがクロックや電圧の変更をする機能を持っていて、BIOSでも有効になっている*2
- 使用しているCPUに合ったドライバ(例: acpi-cpufreq, powernow-k8)を読み込む*3
の両方が必要。
(2008/8/18)Linux 2.6.26の時点では
- Intel製CPU(EIST: Enhanced Intel SpeedStep Technology使用): acpi-cpufreq
- AMD製CPU(K8-K10世代): powernow-k8*4
という選択を行うことになる。EIST未対応なPentium4ではp4-clockmodを使うこともでき、他のCPUでもドライバが用意されているものは存在する。
(2010/11/12)AMDのK10(Athlon II,Phenom II)世代のCPUもK8(Athlon 64など)世代と同様のpowernow-k8を用い、「k10」の付いたモジュール名にはなっていない。
カーネルの設定
ディストリ付属のカーネルであれば、cpufreq関連も全てモジュールになっている可能性が高い。自分で設定する場合はhttp://www.gentoo.org/doc/ja/power-management-guide.xml#doc_chap2
を参考に。手元の環境(Athlon64)では
Power management options ---> [*] Power Management support (中略) ACPI (Advanced Configuration and Power Interface) Support ---> [*] ACPI Support (中略) <*> Processor <*> Thermal Zone (以下略) CPU Frequency scaling ---> [*] CPU Frequency scaling [ ] Enable CPUfreq debugging <*> CPU frequency translation statistics [ ] CPU frequency translation statistics details Default CPUFreq governor (userspace) ---> <*> 'performance' governor <*> 'powersave' governor --- 'userspace' governor for userspace frequency scaling <*> 'ondemand' cpufreq policy governor <*> 'conservative' cpufreq governor --- CPUFreq processor drivers <*> AMD Opteron/Athlon64 PowerNow! < > Intel Enhanced SpeedStep (deprecated) < > ACPI Processor P-States driver --- shared options [ ] /proc/acpi/processor/../performance interface (deprecated)
のようにしている(全て組み込み)。「Default CPUFreq governor」は、ユーザスペースにする。
(2008/6/23)Linux 2.6.24からは、既定のgovernorとして「ondemand」と「conservative」が使用できるようになった。
クロック周波数の決定
http://www.gentoo.org/doc/ja/power-management-guide.xml#doc_chap3にあるように、
- クロックや電圧を調節する際の動作モード「governor」の種類
- クロック周波数の変動可能範囲(最大値: /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq 最小値: /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq)
の両方によって、クロック周波数が変化する(最終的な)ポリシーが決められる。後述のcpufreqdでは、この2つの組み合わせ*5を「プロファイル」として扱う。
(2009/8/2)範囲に関する記述を微調整
種類 | 動作 |
---|---|
ondemand | 負荷がかかるとクロックを上げ、負荷が下がるとクロックも下げる(値は急に大きく変動する) |
conservative | 負荷がかかるとクロックを上げ、負荷が下がるとクロックも下げる(値はゆっくり段階的に変動する) |
powersave | 負荷に関わらず、変動可能範囲内の最低のクロックで動作 |
performance | 負荷に関わらず、変動可能範囲内の最高のクロックで動作 |
(2009/8/2)powersaveとperformanceの記述を微調整
governorの手動変更
cpufrequtilsパッケージのcpufreq-setコマンドで変更できる。$ sudo cpufreq-set -g ondemand
cpufreqに関する現在の各種状態の取得
cpufrequtilsパッケージのcpufreqd-infoでコマンドで表示できる。$ cpufreq-info cpufrequtils 002: cpufreq-info (C) Dominik Brodowski 2004-2006 Report errors and bugs to linux@brodo.de, please. analyzing CPU 0: driver: powernow-k8 CPUs which need to switch frequency at the same time: 0 hardware limits: 1000 MHz - 2.20 GHz available frequency steps: 2.20 GHz, 2.00 GHz, 1.80 GHz, 1000 MHz available cpufreq governors: ondemand, powersave, userspace, performance current policy: frequency should be within 1000 MHz and 1.80 GHz. The governor "ondemand" may decide which speed to use within this range. current CPU frequency is 1000 MHz.
この場合、
- CPUが1GHzから2.2GHzまでをサポートしている
- クロックの値は2.2GHz,2GHz,1.8GHz,1GHzの4段階で変更される
- ondemand governorで動作している
- 最大値と最小値のポリシー設定により、1GHzから1.8GHzの間で変動させている
ということが分かる。
(2008/8/18)「available cpufreq governors」では、利用可能なgovernorの一覧が表示される。手元の環境ではカーネルビルド設定でconservativeを外しているためにこれが表示されていないが、有効にしていれば表示される。
ondemand governorでの動作時において、CPUクロックを上げるCPU使用率のしきい値
/sys/devices/system/cpu/cpu0/cpufreq/ondemand/up_thresholdの値まで負荷がかかると、更にクロック周波数を上げようとする。この値は、低すぎると省電力効果が薄れ(すぐクロックが上がるため)、高すぎると処理の体感速度が悪くなる(負荷が高いのにクロックが上がりにくいと処理が遅くなるため)ので、難しい。現在は65にしている。この値を上書きすれば手動で変更もできるが、後述のcpufreqdでも設定できる。
cpufreqdで実用的な動的クロック変更を行う
cpufreqdデーモンは、複数の「プロファイル」と「ルール」を定義することで、CPUの負荷だけでなく、動作しているプログラムや、その他様々な情報*6により、高度な条件の作成ができ、システムの状態に適したクロック制御で、優れた省電力効果が得られる。*7設定
手元の設定では、- 基本はondemand
- クロックを上げるしきい値は65%
- 最低クロックで快適に動作するが、CPU使用率が常に100%になるようなソフトウェア(一部のゲームなど)に対して、これが動作するとクロックを最低に下げるようにする*8
- ルールからは使用しないが、手動で変更したいときのために、プロファイルは余計に作ってある
という程度のことしかしていない上、CPUクロックの値も、環境に合わせて調整する必要があるため、無駄にCPUを100%使用するアプリの対策以外は、あまり参考にならないかもしれない。あくまでも自分用の覚え書きということで貼っておく。
ファイル名: /etc/cpufreqd.conf
[General] pidfile=/var/run/cpufreqd.pid poll_interval=4 enable_remote=1 remote_group=wheel verbosity=0 [/General] [Profile] name=ondemand low minfreq=1000000 maxfreq=1800000 up_threshold=70 policy=ondemand [/Profile] [Profile] name=ondemand mid minfreq=1000000 maxfreq=2000000 up_threshold=70 policy=ondemand [/Profile] [Profile] name=ondemand high minfreq=1000000 maxfreq=2200000 up_threshold=70 policy=ondemand [/Profile] [Profile] name=powersave low minfreq=1000000 maxfreq=1000000 policy=powersave [/Profile] [Profile] name=powersave mid minfreq=1800000 maxfreq=1800000 policy=powersave [/Profile] [Profile] name=performance minfreq=2200000 maxfreq=2200000 policy=performance [/Profile] # 最低クロックで快適に動作するがCPU使用率100%のものに対してクロック下げ [Rule] name=throttle low cpu_interval=0-100 programs=program1,program2,program3 profile=powersave low [/Rule] # 最低クロックよりは高いクロックが必要だが常に100%というわけではないもの [Rule] name=throttle mid-ondemand cpu_interval=0-100 programs=program4 profile=ondemand low [/Rule] # 最低クロックよりは高いクロックが必要なもの(100%使用)に対してクロック下げ [Rule] name=throttle mid-fixed cpu_interval=0-100 programs=program5 profile=powersave mid [/Rule] # デフォルトは最低クロックから最大クロックまで使用 [Rule] name=default cpu_interval=0-100 profile=ondemand high [/Rule]
(2008/8/4)内容に関して、以下の修正を行った。
- 「enable_plugins」の行は不要な上、書かないほうがよくなっているらしいため、外している
- コメントの記号は正しくは「#」なので修正
- 最低ではないクロックでの動作で、低負荷時にクロックを下げるもの(throttle mid-ondemand)と下げないもの(throttle mid-fixed)とを分けた
なお、これは設定例(参考)ということで、これをコピペしてそのまま使うことはできない。環境や運用ポリシーによって、値は変更する。
以下は設定上の覚え書き。
- poll_intervalは、何秒ごとに状態を見て、ルールの変更を検討するかの間隔。3〜4秒が適当?
enable_pluginsで、情報を取得するプラグインをコンマ区切りで記述- enable_remoteを1にすると、remote_groupで指定したグループのメンバーがcpufreqd-setコマンドで、プロファイルを手動で変更できるようになる
- minfreqとmaxfreqは「80%」のような、最大(定格)のクロック周波数に対するパーセンテージでも記述できる
- up_thresholdは、前述の、クロックを上げるために必要なCPU使用率。プロファイルごとに決められる*9
- cpu_interval指定では、ルール適用の条件となるCPU使用率の幅を書くのだが、上の例では特にクロック変更の動作には関係ない。「default」のルールがデフォルトで動作するようにするために書いてある
- programs指定では、(動作していると)ルール適用の条件となるプログラムの実行ファイル名(例: blobwars)をコンマ区切りで書く
- (2008/8/4)ルールを記述する順番には意味があり、優先される順番が変わるようだ。テスト中、意図した通りにルールが適用されない場合、ルール記述の順番を変えて試すと、うまく動くことがあるかもしれない
詳細は「man cpufreqd.conf」を参照。
設定のテスト
ルールが思った通りに適用されて、プロファイルが切り替えられているかなど、詳細なメッセージを表示しながら実行する形のテストを$ sudo /usr/sbin/cpufreqd -D -V 7
のようにして行い、Ctrl+Cで止める。問題がなければ
$ sudo /etc/init.d/cpufreqd start
で開始。
(2008/8/4)-Vオプションの後ろの値はメッセージの詳細度で、必要に応じて6や5などの値で多少大まかなメッセージを見るようにすることもできる。
(2010/2/5)「cpufreqdの手動プロファイル/モード変更ツールを更新(Vala言語への移植,デーモン制御機能とテストツールの追加)」で作成したバージョン2(1.9)系のcpufreqd-iconではこのテストをGUI上で簡単に行えるようにした。
プロファイルの手動変更
プロファイルは、ルールに基づいて、ルールの記述内に指定されたプロファイルが自動的に選択されて切り替わるのだが、手動でこれを変更するには、上記enable_remoteとremote_groupの設定をした上で、$ cpufreqd-set manual
でマニュアルモードに切り替え、更に、プロファイルの番号を指定する。番号はcpufreqd-getコマンドで
$ cpufreqd-get socket I'll try to connect: /tmp/cpufreqd-xxxxxx/cpufreqd Name (#1): ondemand-low Governor: ondemand Min freq: 1000000 Max freq: 1800000 Name (#2): ondemand-mid Governor: ondemand Min freq: 1000000 Max freq: 2000000 Name (#3): ondemand-high * Governor: ondemand Min freq: 1000000 Max freq: 2200000 Name (#4): powersave-low Governor: powersave Min freq: 1000000 Max freq: 1000000 Name (#5): powersave-mid Governor: powersave Min freq: 1800000 Max freq: 1800000 Name (#6): performance Governor: performance Min freq: 2200000 Max freq: 2200000
のように一覧を表示し、「#」の後ろの番号を見て指定する。現在選択されているプロファイル(上の例では#3)には、後ろに「*」が付いている。例として、ondemandの1GHz-1.8GHz動作にする「#1」を選択する場合は
$ cpufreqd-set 1
を実行する。手動プロファイル変更(マニュアルモード)から自動プロファイル変更(ダイナミックモード)に戻すには
$ cpufreqd-set dynamic
を実行。
(2008/8/4)cpufreqdのバージョン2.2系では、選択されているプロファイルの表示は
Name (#1): ondemand low Governor: ondemand Min freq: 1000000 Max freq: 1800000 Name (#2): ondemand mid Governor: ondemand Min freq: 1000000 Max freq: 2000000 Name (#3): ondemand high Active on CPU#: 0 Governor: ondemand Min freq: 1000000 Max freq: 2200000 (以下略)
のように、名前の下にCPU番号で表示されるようになっている。
使用したバージョン:
- cpufreqd-2.1.1, 2.2.1
*1:2.6系から利用可能
*2:以前使用していたPentium4では、BIOS設定でクロック変更機能に関する項目がなかったが、p4-clockmodドライバでcpufreqは使えていた
*3:モジュールの場合、modprobeで読み込み、組み込みの場合は何もしない
*4:Athlon世代はpowernow-k7、K6世代はpowernow-k6
*5:実際にはそれ以外の要素も追加できるが、必須なのはこの2つと識別名だけで、governorは「policy」、範囲は「minfreq」と「maxfreq」
*6:センサ経由で取得する温度や、バッテリー動作などによる条件も作れるが、ここでは取り上げない
*7:センサ温度やバッテリーなどを設定に組み込むと、更に大きな効果が得られる
*8:これをしないと、無駄にクロックが最大になって、電力の大幅な損失(無駄)になる