CPU 周波数スケーリング

提供: ArchWiki
2023年7月16日 (日) 14:29時点におけるAshMyzk (トーク | 投稿記録)による版 ("Collaborative processor performance control" を追加)
ナビゲーションに移動 検索に移動

関連記事

CPU パフォーマンススケーリングにより、オペレーティングシステムは消費電力の削減やパフォーマンスの向上のために CPU の周波数を上げ下げすることができるようになります。スケーリングは、システムの負荷に応じて自動的に行ったり、ACPI イベントに応じて調整したり、ユーザスペースのプログラムで手動で変更したりできます。

Linux カーネルは CPUFreq サブシステムを通して CPU パフォーマンススケーリングを提供します。このサブシステムには2つの抽象化レイヤが定義されています:

  • スケーリングガバナーは、望ましい CPU 周波数を計算するアルゴリズムを実装します。システムのニーズに基づいている可能性があります。
  • スケーリングドライバは、直接 CPU と対話し、現在のガバナーの要求する望ましい周波数に変更します。

デフォルトのスケーリングドライバとスケーリングガバナーは自動的に選択されますが、cpupoweracpidLaptop Mode Tools、デスクトップ環境によって提供されている GUI ツールなどのユーザスペースのツールでも高度な設定をすることができます。

ユーザースペースツール

thermald

thermald は、Intel CPU のオーバーヒートを防止するために使用される Linux デーモンです。このデーモンは P-state、T-state、および Intel power clamp ドライバを使用してサーマルパラメータを積極的に制御します。最新のドライバが利用できない場合、デーモンはシステムの冷却を制御するために x86 モデル固有のレジスタと Linux の "cpufreq サブシステム" に戻り、システムの冷却を制御します。

デフォルトでは、このデーモンは利用可能な CPU デジタル温度センサーを使って CPU 温度を監視し、ハードウェアが積極的な補正動作を行う前に CPU 温度を制御下に維持します。thermal sysfs に皮膚温度センサーがある場合、皮膚温度を 45C 以下に保とうと試みます (訳注: ここでの皮膚温度 (skin temperature) とは、ユーザがデバイスを持ったときに感じる温度のことです)。

Tiger Lake ラップトップ (例: Dell Latitude 3420) では、このデーモンは、他の方法で利用できるものよりも多くのパフォーマンスを解放すると報告されています。

関連する systemd ユニットは thermald.service です。このサービスは起動され、かつ有効化されている必要があります。

i7z

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

turbostat

turbostat は最近の Intel と AMD の CPU の周波数、消費電力、アイドル状態、その他の統計情報を表示することができます。

cpupower

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

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

cpupower-gui

cpupower-guiAUR は CPU 周波数のスケーリングを支援するために設計されたグラフィカルなユーティリティです。GUI は GTK をベースにしており、cpupower と同じオプションを提供することを意図しています。 cpupower-gui は各コアの最大/最小の CPU 周波数とガバナーを変更することができます。このアプリケーションは polkit を通して特権付与を行い、wheel ユーザグループのログイン済みユーザであれば誰でも周波数とガバナーを変更することができます。

gnome-shell-extension-cpupower

gnome-shell-extension-cpupower-gitAUR は、CPU 周波数の最大値と最小値を変更し、周波数ブーストを有効化/無効化することのできる GNOME シェル拡張です。

auto-cpufreq

auto-cpufreqAUR は、Linux 用の CPU 速度と電源の自動オプティマイザです。ノート PC のバッテリー状態、CPU 使用率、CPU 温度、そしてシステムの負荷をアクティブに監視します。

power-profiles-daemon

power-profiles-daemonpowerprofilesctl コマンドラインツールは power-profiles-daemon サービスを通して電源プロファイル (バランス、パワーセーバー、パフォーマンスなど) を扱います。GNOME と KDE もプロファイル切り替えのための グラフィカルインターフェイス を提供しています。以下を参照してください:

使い方や使用例、類似プロジェクトとの比較などについては、プロジェクトの README を参照してください。

power-profiles-daemon サービスを起動/有効化してください。powerprofilesctl が起動されると、サービスも起動しようとすることに注意してください (dbus.serviceユニットステータスを見てください)。

ノート: power-profiles-daemon は、TLPtunedAURsystem76-powerAUR といった他の電源管理サービスと衝突します。(潜在的に依存関係にあるため) power-profiles-daemonアンインストールせずに前述のサービスのどれかを代わりに使用するには、power-profiles-daemon サービスをマスクして無効化してください ([1][2] も参照)。

スケーリングドライバ

ノート:
  • カーネル 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 で設定できます。

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 (下の表を参照) は 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
ノート: 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 > /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
ヒント: 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#デバッグ出力の例に従ってください。

ヒント: もしくは、cpupower ユーティリティを設定して systemd サービスを有効にしてください。

自律的な周波数スケーリング

Intel と AMD は両方とも、(1) システムのパフォーマンスの範囲と、(2) プリファレンスを指定するパフォーマンス/電力のヒントに基づいて CPU に自身の速度を決定させる方法を定義しています。以下の場合に完全自律モードがアクティブ化されます:

  • amd-pstate が "active" に設定された場合。手動による設定と、CPU と BIOS の両方に CPPC サポートが必要です。
  • intel-pstate が "active" に設定され、かつ、ハードウェア P-state (HWP) が利用可能である (つまり、Sandy Bridge 以降) 場合。設定無しで動作します。

能動的な governing の最も重要な特徴は、2つのガバナー (powersaveperformance) のみが利用可能であるように見えることです。これらは通常のガバナーのようには動作しません。これらのレベルは、CPU の内部ガバナーの Energy Performance Preference ヒントに変換されます。結果として、これらは両方、動的スケーリングを提供します。schedutilondemand に似ていますが、主にレイテンシが異なります。performance アルゴリズムは、Intel HWP に古い ondemand ガバナーよりも優れた省電力機能を提供するはずです

Intel active、非 HWP

紛らわしいことに、intel-pstate ドライバには、CPU の能動的な決定を必要としない "active" モードがあります。カーネルコマンドラインによって "active" モードが強制されたが、HWP が利用できないか無効化されている場合に、このモードはオンになります。powersaveperformance しか提供しませんが、ドライバ自体は schedutilperformance に似た方法で governing を行います (つまり、最大の P-state のままになります)。能動的な intel-pstate に比べて、このモードに実際の利点はありません。

EPP を設定する

sysfs インターフェイスが利用可能である場合、中間的なヒントを選択することができます。インターフェイスは AMD と Intel で同じです。/sys/devices/system/cpu/cpu*/power/energy_performance_preference ファイルは現在のプリファレンスを記述し、/sys/devices/system/cpu/cpu*/power/energy_performance_available_preferences は利用可能なプリファレンスのリストを提供します。また、0 (パフォーマンス優先) から 255 (省電力優先) までの間の数値を渡すことができます。EPP がない Intel CPU にはフォールバック実装が提供されています。文字列 を EPB レベル (次のセクションで説明) に変換しますが、数値では失敗します。

x86_energy_perf_policy は、Intel CPU に対してのみ--hwp-epp スイッチによる EPP ヒントの設定をサポートしています。これは、Intel と AMD で異なるマシン固有のレジスタ (MSR) への直接アクセスにより機能します。このプログラムは、周波数乗数の範囲を使って HWP 周波数の範囲を制限することもできます。

Collaborative processor performance control

最近の CPU の電力消費量は、もはや単純に周波数や電圧設定に依存していません。必要に応じて切り替え可能なモジュールが存在しているからです。Collaborative Processor Performance Control (CPPC) は、ACPI 5.0 で提供されている P-state の置き換えです。静的な周波数レベルのテーブルを定義する代わりに、プロセッサは多くの抽象的なパフォーマンスレベルを提供し、オペレーティングシステムはこれらのレベルの中から選択します。これには2つの長所があります:

  • 16個の P-state エントリという制限がない。典型的な CPU では数百ものレベルの中から選ぶことができます。
  • CPU は、特定の部品 (例えば、ベクトル FPU) が使用されていない時に、より高い周波数を提供できます。

一方、柔軟な周波数は、schedutil による高速な周波数変更において重要な周波数不変の使用率追跡を破壊します。CPPC において周波数を静的にするために多くのベンダ固有の方法が取られてきましたが、ほとんどの成功例は arm64 におけるものです。

cppc_cpufreq は汎用の CPPC スケーリングドライバです。amd_pstate も、Zen 3 MSR が利用できない場合に、ACPI CPPC を使用して CPU の周波数を管理します。この方法 ("共有メモリ" とも呼ばれる) は、MSR よりも高レイテンシです。

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

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

参照