CPU 周波数スケーリング

提供: ArchWiki
2018年2月6日 (火) 23:44時点におけるKusakata.bot (トーク | 投稿記録)による版 (文字列「http://www.freedesktop.org/」を「https://www.freedesktop.org/」に置換)
ナビゲーションに移動 検索に移動

関連記事

CPU 周波数スケーリングを使うことで電力を節約するためにオペレーティングシステムが CPU の周波数を調整することが出来るようになります。CPU の周波数はユーザースペースのプログラムを使って手動で変更したり、システムの負担や、ACPI イベントにあわせて自動的に調整することが可能です。

CPU 周波数スケーリングは Linux カーネル内に実装されており、そのインフラストラクチャは cpufreq と呼ばれています。カーネル 3.4 から必要なモジュールが自動でロードされるようになり推奨の ondemand governor がデフォルトで有効になっています。しかしながら、cpupower, acpid, Laptop Mode Tools などのユーザースペースツールや、デスクトップ環境から提供されている GUI ツールを使って高度な設定をすることも可能です。

ユーザースペースツール

thermald

thermald はプラットフォームのオーバーヒートをふせぐのに使われる Linux デーモンです。このデーモンは温度をモニターして利用できる冷却方法を使って温度を適正に保ちます。

デフォルトでは、CPU のデジタル温度センサーを使って CPU の温度を監視して、ハードウェアが強引な是正措置を実行する前に CPU の温度をコントロールします。thermal sysfs に表面温度センサーがある場合は、表面温度を 45°C 以下に維持します。

i7z

i7z は Linux 向けの i7 (と i3, i5) CPU レポートツールです。i7z コマンドでターミナルから実行することができ、GUI は i7z-gui で起動できます。

cpupower

cpupower は CPU 周波数スケーリングを手伝うように作られたユーザースペースのユーティリティの集まりです。このパッケージがなくてもスケーリングを使うことはできますが、便利なコマンドラインユーティリティや起動時に governor を変えるための systemd のサービスが入っているためインストールすることが推奨されています。

cpupower の設定ファイルは /etc/default/cpupower です。この設定ファイルは /usr/lib/systemd/scripts/cpupower の bash スクリプトによって読み込まれます。bash スクリプトは cpupower.servicesystemd によって有効にされます。ブート時に起動するには cpupower.service を有効にしてください。

CPU 周波数ドライバー

ノート:
  • カーネル 3.4 から、ネイティブ CPU モジュールは自動的にロードされます。
  • カーネル 3.9 から、新しい Intel の CPU には下に書かれているドライバーの代わりに新しい pstate パワースケーリングドライバーが自動的に使われます。このドライバーは他のドライバーよりも優先され、モジュールではなく初めから備えられています。現在 Sandy Bridge や Ivy Bridge 以降の新しい CPU でこのドライバーが自動的に使用されます。このドライバーを使っていて問題が生じた際は、kernel 行に intel_pstate=disable を追加してください。同じユーザースペースユーティリティを使うこともできますがコントロールはできません。
  • 上記の P State の挙動は /sys/devices/system/cpu/intel_pstate で変えることができます。例えば、CPU の温度を低く保つために # echo 1 > /sys/devices/system/cpu/intel_pstate/no_turbo で Intel Turbo Boost を無効にすることが可能です。
  • 新しい Intel の CPU は Linux Thermal Daemon (thermald から使えます) でコントロールでき P-states, T-states, Intel power clamp ドライバーを使って熱を積極的にコントロールします。thermald は古い Intel CPU でも使うことができます。最新のドライバーが存在しない場合、デーモンは x86 モデルのレジスタにリバートして Linux の ‘cpufreq サブシステム’ で冷却システムを制御します。

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
ノート:
  • 単一の CPU コアだけを調整するには、-c core_number を加えて下さい。
  • governor, 最大・最小周波数は /etc/default/cpupower で設定できます。

スケーリング governor

Governor (下の表を参照) は cpu の電源設定です。一度に有効にできるのはどれか一つだけになります。詳しくは、カーネルソースに含まれているカーネルドキュメントを見て下さい。

Governor 説明
performance 最大周波数で CPU を動作させます。
powersave 最小周波数で CPU を動作させます。
userspace ユーザーが指定した周波数で CPU を動作させます。
ondemand 負担にあわせて周波数を動的に切り替えます。負担が高まると周波数が高くなり、アイドル時間が増えると元の周波数に戻ります。
conservative 負担にあわせて周波数を動的に切り替えます。ondemand と違って段階的に周波数を切り替えます。
schedutil スケジューラによって CPU の周波数が選択されます [1], [2]

スケーリングドライバーによって、以上の governor のどれかがデフォルトでロードされます:

  • AMD と古い Intel の CPU では ondemand
  • intel_pstate ドライバーを使用する Sandybridge 以降の Intel CPU では powersave
ノート: intel_pstate ドライバーでは performance と powersave ガバナーしかサポートされていません。どちらも動的に周波数を切り替えます。performance ガバナーを利用することで旧 ondemand ガバナーよりも高度な省電力機能を使うことができます

特定の governor を有効にするには、以下のコマンドを実行してください:

# cpupower frequency-set -g governor
ノート:
  • 単一の CPU コアだけを調整するには、上のコマンドに -c core_number を加えて下さい。
  • governor を有効にするには特定のカーネルモジュール (cpufreq_governor) がロードされることを必要とします。カーネル 3.4 から、これらのモジュールは自動的にロードされます。

もしくは、CPU ごとに governor を手動で有効にすることもできます:

# echo governor | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor >/dev/null
ヒント: cpu の速度をリアルタイムで表示するには、次を実行してください:
$ watch grep \"cpu MHz\" /proc/cpuinfo

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#デバッグ出力の例に従ってください。

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
;;

[...]

GNOME での特権取得

ノート: systemd は consolekit と policykit のアクションを管理する logind を導入しています。以下のコードは動作しません。logind では /usr/share/polkit-1/actions/org.gnome.cpufreqselector.policy ファイルの <defaults> エレメントを必要に応じて polkit のマニュアル [3] を見て設定してください。

GNOME にはオンザフライで governor を切り替える素晴らしいアプレットがあります。root パスワードを入力しないで使用するには、以下のファイルを作成してください:

/var/lib/polkit-1/localauthority/50-local.d/org.gnome.cpufreqselector.pkla
[org.gnome.cpufreqselector]
Identity=unix-user:user
Action=org.gnome.cpufreqselector
ResultAny=no
ResultInactive=no
ResultActive=yes

user は使用するユーザー名に置き換えて下さい。

AURdesktop-privilegesAUR パッケージには power グループに入っているユーザーなら誰でも governor を変更できるようにする同じような .pkla ファイルが含まれています。

トラブルシューティング

  • 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 の制限を無視するようにカーネルを設定することができます。

警告: このセクションをよく読んで理解してください。CPU 周波数の制限は 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

参照