CPU 周波数スケーリング
CPU パフォーマンススケーリングにより、オペレーティングシステムは消費電力の削減やパフォーマンスの向上のために CPU の周波数を上げ下げすることができるようになります。スケーリングは、システムの負荷に応じて自動的に行ったり、ACPI イベントに応じて調整したり、ユーザスペースのプログラムで手動で変更したりできます。
Linux カーネルは CPUFreq サブシステムを通して CPU パフォーマンススケーリングを提供します。このサブシステムには2つの抽象化レイヤが定義されています:
- スケーリングガバナーは、望ましい CPU 周波数を計算するアルゴリズムを実装します。システムのニーズに基づいている可能性があります。
- スケーリングドライバは、直接 CPU と対話し、現在のガバナーの要求する望ましい周波数に変更します。
デフォルトのスケーリングドライバとスケーリングガバナーは自動的に選択されますが、cpupower や acpid、Laptop Mode Tools、デスクトップ環境によって提供されている GUI ツールなどのユーザスペースのツールでも高度な設定をすることができます。
目次
ユーザースペースツール
thermald
thermald はプラットフォームのオーバーヒートをふせぐのに使われる Linux デーモンです。このデーモンは P-state、T-state、および Intel power clamp ドライバを使用してサーマルパラメータを積極的に制御します。最新のドライバが利用できない場合、デーモンはシステムの冷却を制御するために x86 モデル特有のレジスタと Linux "cpufreq subsystem "に戻り、システムの冷却を制御します。
Tiger Lake ラップトップ (例: Dell Latitude 3420) では、このデーモンは、他の方法で利用できるものよりも多くのパフォーマンスを解放すると報告されています。
関連する systemd ユニットは thermald.service
で、起動して有効化されていなくてはなりません。
i7z
i7z は Linux 向けの i7 (と i3, i5) CPU レポートツールです。i7z
コマンドでターミナルから実行することができ、GUI は i7z-gui
で起動できます。
turbostat
turbostat は最近の Intel と AMD の CPU の周波数、消費電力、アイドル状態、その他の統計情報を表示することができます。
cpupower
cpupower は CPU 周波数スケーリングを手伝うように作られたユーザースペースのユーティリティの集まりです。このパッケージがなくてもスケーリングを使うことはできますが、便利なコマンドラインユーティリティや起動時に governor を変えるための systemd のサービスが入っているためインストールすることが推奨されています。
cpupower の設定ファイルは /etc/default/cpupower
です。この設定ファイルは /usr/lib/systemd/scripts/cpupower
の bash スクリプトによって読み込まれます。bash スクリプトは cpupower.service
と systemd によって有効にされます。ブート時に起動するには cpupower.service
を有効化してください。
cpupower-gui
cpupower-guiAUR は CPU 周波数のスケーリングを支援するために設計されたグラフィカルなユーティリティです。GUI は GTK をベースにしており、cpupower と同じオプションを提供することを意図しています。 cpupower-gui は各コアの最大/最小の CPU 周波数とガバナーを変更することができます。このアプリケーションは polkit を通して特権付与を行い、wheel
にログインしているユーザであれば誰でも利用することができます。ユーザーとグループ は、周波数とガバナーを変更することができます。
power-profiles-daemon
power-profiles-daemon の powerprofilesctl コマンドラインツールは power-profiles-daemon
サービスを通して電源プロファイル (バランス、パワーセーバー、パフォーマンスなど) を扱います。GNOME と KDE もプロファイル切り替えのための グラフィカルインターフェイス を提供しています。
使い方や使用例、類似プロジェクトとの比較などについては、プロジェクトの README を参照してください。
power-profiles-daemon
サービスを 起動/有効化 します。 powerprofilesctl が起動されると、サービスも起動しようとすることに注意してください(dbus.service
の ユニットを使う を見てください)
スケーリングドライバ
cpupower はネイティブ CPU の制限を知るためにモジュールを必要とします:
モジュール | 説明 |
---|---|
intel_pstate | このドライバーは Intel Core (SandyBridge 以降) プロセッサの内部 governor でスケーリングドライバーを実装しています。 |
acpi-cpufreq | ACPI Processor Performance States を利用する CPUFreq ドライバー。このドライバーは Intel Enhanced SpeedStep もサポートしています (以前は speedstep-centrino モジュールによってサポートされていました)。 |
speedstep-lib | Intel SpeedStep が有効になっているプロセッサ (ほとんどの Atom と古い Pentium (< 3)) の CPUFreq ドライバー。 |
powernow-k8 | K8/K10 Athlon64/Opteron/Phenom プロセッサの CPUFreq ドライバー。Linux 3.7 からこのファミリーの新しい CPU では 'acpi-cpufreq' が自動的に使われます。 |
pcc-cpufreq | このドライバーは ProLiant サーバーで使われている Hewlett-Packard と Microsoft Corporation による Processor Clocking Control インターフェイスをサポートしています。 |
p4-clockmod | Intel Pentium 4 / Xeon / Celeron プロセッサの CPUFreq ドライバー。有効にするとクロックをスキップして CPU の温度を下げます。 基本的には SpeedStep ドライバーを使って下さい。 |
利用可能なモジュールの完全なリストを表示するには、次を実行してください:
$ ls /lib/modules/$(uname -r)/kernel/drivers/cpufreq/
適切なモジュールをロードしてください (詳しくはカーネルモジュールを見て下さい)。cpufreq ドライバーが正しくロードされていれば、次のコマンドで CPU の詳細が表示されます:
$ cpupower frequency-info
最大・最小周波数を設定する
ごく稀に、手動で最大・最小周波数を設定しなくてはならないことがあります。
最大クロック周波数を設定するには (clock_freq には単位を付けて下さい: GHz, MHz):
# cpupower frequency-set -u clock_freq
最小クロック周波数を設定するには:
# cpupower frequency-set -d clock_freq
CPU を特定の周波数で動作するように設定するには:
# cpupower frequency-set -f clock_freq
Turbo Boost の無効化
intel_pstate
# echo 1 > /sys/devices/system/cpu/intel_pstate/no_turbo
acpi-cpufreq
# echo 0 > /sys/devices/system/cpu/cpufreq/boost
x86_energy_perf_policy
x86_energy_perf_policy を使用します。
# x86_energy_perf_policy --turbo-enable 0
この変更は一時的なものです。
スケーリング governor
Governor (下の表を参照) は cpu の電源設定です。一度に有効にできるのはどれか一つだけになります。詳しくは、カーネルソースに含まれているカーネルドキュメントを見て下さい。
Governor | 説明 |
---|---|
performance | 最大周波数で CPU を動作させます。 |
powersave | 最小周波数で CPU を動作させます。 |
userspace | ユーザーが指定した周波数で CPU を動作させます。 |
ondemand | 負担にあわせて周波数を動的に切り替えます。負担が高まると周波数が高くなり、アイドル時間が増えると元の周波数に戻ります。 |
conservative | 負担にあわせて周波数を動的に切り替えます。ondemand と違って段階的に周波数を切り替えます。 |
schedutil | スケジューラによって CPU の周波数が選択されます [3], [4]。 |
スケーリングドライバーによって、以上の governor のどれかがデフォルトでロードされます:
- AMD と古い Intel の CPU では
ondemand
。 intel_pstate
ドライバーを使用する Sandybridge 以降の Intel CPU ではpowersave
。
特定の governor を有効にするには、以下のコマンドを実行してください:
# cpupower frequency-set -g governor
もしくは、CPU ごとに governor を手動で有効にすることもできます:
# echo governor > /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
ondemand governor を調整する
詳細は カーネルドキュメント を見て下さい。
閾値を切り替える
周波数を上げるときの閾値を設定するには:
# echo -n percent > /sys/devices/system/cpu/cpufreq/<governor>/up_threshold
周波数を下げるときの閾値を設定するには:
# echo -n percent > /sys/devices/system/cpu/cpufreq/<governor>/down_threshold
サンプリングレート
サンプリングレートは CPU の周波数を変化させるのに governor が確認する頻度を決めます。1 より大きく sampling_down_factor
を設定すると負担評価のオーバーヘッドが減って、負担が高い時に CPU がずっと最高周波数で動作しパフォーマンスが向上します。sampling_down_factor
に設定できる値は 1 から 100000 です。CPU 周波数や負担が低いときの挙動には影響がありません。
値を読み取るには (デフォルト = 1)、次を実行:
$ cat /sys/devices/system/cpu/cpufreq/ondemand/sampling_down_factor
値を設定するには、次を実行:
# echo -n value > /sys/devices/system/cpu/cpufreq/ondemand/sampling_down_factor
変更を永続化させる
カーネルモジュール#/etc/modprobe.d/ 内のファイルを使うあるいは systemd で永続的に設定する方法がありますが、場合によっては競合状態になることがあります。systemd#一時ファイルを参照してください。udev のほうが上手く処理します。
例えば、スケーリングガバナーが acpi_cpufreq
の場合で CPU コア 0
のスケーリングガバナーを performance に設定するには、以下の udev ルールを作成してください:
/etc/udev/rules.d/50-scaling-governor.rules
SUBSYSTEM=="module", ACTION=="add", KERNEL=="acpi_cpufreq", RUN+=" /bin/sh -c ' echo performance > /sys/devices/system/cpu/cpufreq/policy0/scaling_governor ' "
起動後に変更を永続化させるには、initramfs を使用している場合、udev#デバッグ出力の例に従ってください。
Intel CPU のエネルギーパフォーマンスポリシーの制御
インストール x86_energy_perf_policy:
ハードウェア P-States を有効にする。
# x86_energy_perf_policy -H 1 # x86_energy_perf_policy -U 1
デフォルト ポリシーを設定します。
# x86_energy_perf_policy default
パフォーマンス ポリシーを設定します。
# x86_energy_perf_policy performance
バランス・パフォーマンス ポリシーを設定します。
# x86_energy_perf_policy balance-performance
バランス・パワー ポリシーを設定します。
# x86_energy_perf_policy
パワー ポリシーを設定します。
# x86_energy_perf_policy power
この変更は一時的なものです。詳しくは x86_energy_perf_policy(8) を参照してください。
CPU idle ドライバ
intel_idle
を使用します。 CPU idle ドライバは、最近の Intel CPU では acpi_idle
ドライバの代わりに自動的に使用されます。このドライバは現在 Sandy Bridge およびそれ以降の CPU で自動的に使用されます。intel_idle
は BIOS の C-State 設定を無視する場合があります。このドライバを使用中に問題が発生した場合、カーネルラインに intel_idle.max_cstate=0
を追加してください。
ACPI イベントによる動作
AC アダプタを接続したときやノートパソコンのフタを閉じたときなど様々な ACPI イベントによって governor を自動的に切り替えるように設定することができます。簡単なサンプルは下にありますが、acpid の記事は全部読む価値があります。
イベントは /etc/acpi/handler.sh
で定義します。acpid パッケージがインストールされていれば、ファイルは既に存在し実行可能になっているはずです。例えば、AC アダプタが切断されたときにスケーリング governor を performance
から conservative
に変更して、またアダプタが接続されたときは戻したい場合:
/etc/acpi/handler.sh
[...] ac_adapter) case "$2" in AC*) case "$4" in 00000000) echo "conservative" >/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor echo -n $minspeed >$setspeed #/etc/laptop-mode/laptop-mode start ;; 00000001) echo "performance" >/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor echo -n $maxspeed >$setspeed #/etc/laptop-mode/laptop-mode stop ;; esac ;; *) logger "ACPI action undefined: $2" ;; esac ;; [...]
トラブルシューティング
- ntop などのアプリケーションは自動的な周波数スケーリングに上手く応じられません。ntop の場合、現在のプロセッサ速度では対処できないような大量のパケットが突然ネットワークインターフェイスに押し寄せてきたときに
on-demand
governor が周波数を素早く変更できずにセグメンテーションフォルトが発生したり情報が失われることがあります。
- CPU によっては
on-demand
governor のデフォルトの設定でパフォーマンスが出ないことがあります (例: flash 動画がスムーズに再生されなかったりウィンドウアニメーションがガタガタになる)。周波数スケーリングを完全に無効化することで問題を解決する代わりに、それぞれの CPU の up_threshold sysctl 変数を低くすることで周波数スケーリングを積極的にすることができます。on-demand governor の閾値を変更する方法を見て下さい。
- ときどき on-demand governor は最大周波数までスロットルを上げないで、その一段階下で抑えることがあります。max_freq の値を本当の最大値よりも少しだけ多目に設定することでこれを解決できます。例えば、CPU の周波数のレンジが 2.00 GHz から 3.00 GHz ならば、max_freq を 3.01 GHz に設定すると良いかもしれません。
- ALSA ドライバーとサウンドチップの組み合わせによっては周波数が変化する governor で音飛びが発生することがあります。周波数が変化しない governor に切り替えることで音飛びをなくすことができます。
BIOS 周波数の制限
CPU/BIOS 設定によっては最大周波数までスケールすることができなかったり周波数を上げることが全くできなかったりすることがあります。これは大抵 BIOS イベントが OS に周波数を制限するよう通知しているのが原因であり、結果的に /sys/devices/system/cpu/cpu0/cpufreq/bios_limit
が低い値に設定されます。
BIOS のセットアップユーティリティで設定 (Frequency, Thermal Management など) をしたのに変更できない場合、BIOS にバグが存在したり、BIOS 自体のバージョンが古いのかもしれません。または BIOS に何か理由があって CPU の周波数を制限しているということもあります。
そのような理由として、バッテリーが取り除かれた (またはほとんど死んでいる) ことで AC 電源しか使えないようになっているのが原因だということがあります (使用しているマシンがノートパソコンの場合)。この場合、電力が弱い AC 電源だけではピーク性能を発揮するのに十分な電力が供給されておらず、バッテリーの補助がないとデータを喪失したり、破損したり、または最悪の場合ハードウェアに深刻なダメージを与える可能性があります。
全ての BIOS が CPU 周波数を制限するわけではありませんが、例えば IBM/Lenovo のほとんどの Thinkpad は制限を加えます。詳しくは thinkwiki のトピック を参照して下さい。
変な BIOS の設定がないことを確認して、何をするのかちゃんと理解できているのなら、BIOS の制限を無視するようにカーネルを設定することができます。
特殊なパラメータをプロセッサのモジュールに渡す必要があります。
一時的に変更してみたいときは /sys/module/processor/parameters/ignore_ppc
の値を 0
から 1
に変更してください。
設定を永続的にするにはカーネルモジュールを参照するか processor.ignore_ppc=1
をカーネルブート行に追加する、または以下のファイルを作成してください。
/etc/modprobe.d/ignore_ppc.conf
# If the frequency of your machine gets wrongly limited by BIOS, this should help options processor ignore_ppc=1