cpupower と cpufreq-utils で Linux の CPU 周波数スケーリングを制御する:パフォーマンス向上と省電力化

Linux tutorial - IT technology blog
Linux tutorial - IT technology blog

多くの人が見落としている問題

Linux サーバーのバッチジョブが遅い。軽い作業中でもノートPC のファンが回り続ける。アプリケーションのチューニング、メモリの確認、ディスク I/O の監査まで行ったのに、まだ遅い。実は CPU ガバナーがずっと powersave に設定されたまま、カーネルが正当化できる最小クロック速度に静かに制限をかけていたのだ。

これは CPU 周波数スケーリングが設計通りに動作している状態だ。ただし、あなたの意図通りではない。カーネルはガバナーと呼ばれるポリシーを使って、負荷に応じて CPU クロック速度を動的に調整する。多くのディストリビューションのデフォルト設定はパフォーマンスより省電力を優先する。アイドル状態のマシンならそれでいいが、安定したスループットが必要なときには最悪だ。

ここでは、cpupowercpufreq-utils を使って CPU 周波数ガバナーを確認・変更・永続化する方法を解説する。どちらも現代的な Linux システムでこの作業に使う主要なツールセットだ。

クイックスタート — 5 分で動かす

ツールのインストール

Ubuntu/Debian の場合:

sudo apt update
sudo apt install linux-tools-common linux-tools-$(uname -r) cpufrequtils

Fedora/RHEL/AlmaLinux の場合:

sudo dnf install kernel-tools

Arch Linux の場合:

sudo pacman -S cpupower

現在のガバナーを確認する

cpupower frequency-info

次のような出力が表示される:

analyzing CPU 0:
  driver: intel_pstate
  CPUs which run at the same hardware frequency: 0
  available cpufreq governors: performance powersave
  current policy: frequency should be within 400 MHz and 3.60 GHz
  current CPU frequency: 800 MHz (asserted by call to hardware)
  boost state support: supported - enabled

current CPU frequency: 800 MHz という表示が見えるだろうか?CPU が最低周波数で動作している。CPU 集約的な処理を行っている場合、これがボトルネックだ。

パフォーマンスモードに切り替える

sudo cpupower frequency-set -g performance

設定が反映されたことを確認する:

cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor

performance と表示されるはずだ。

詳細解説 — CPU 周波数スケーリングの仕組み

ガバナーの種類

Linux にはいくつかのガバナーが含まれている。使用可能なものは CPU ドライバー(intel_pstateamd-pstate、または汎用の acpi-cpufreq)によって異なる:

  • performance — CPU を最大周波数で動作させる。継続的な負荷がかかるサーバーに最適。
  • powersave — 最小周波数で動作させる。アイドル状態のマシンやバッテリーが重要な状況に最適。
  • ondemand — 負荷時に素早くスケールアップし、アイドル時に下げる。デスクトップの定番デフォルト。
  • conservative — ondemand に似ているが、より緩やかに上昇する。消費電力への影響が穏やか。
  • schedutil — CPU スケジューラーに直接フックする。一般的に現代のカーネル(5.x+)で最もバランスが良い。
  • userspace — 周波数を手動で設定できる。テストや固定周波数の用途に便利。

CPU で使用可能なガバナーを確認する

cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors

intel_pstate を使用している Intel システムでは performancepowersave しか表示されないことが多い。これはドライバーの制限ではなく、Intel の実装が独自の内部周波数ステッピングを処理しているためだ。新しい CPU では AMD の amd-pstate も同様に動作する。

cpufreq-utils と cpupower の違い

2 つのツール、同じ目的、異なる歴史:

  • cpufreq-utilscpufreq-infocpufreq-set を提供する — 古いが広く利用可能
  • cpupowerlinux-tools に含まれる)はより広い機能サポートを持つ現代的な後継ツール

どちらも問題なく動作する。使用可能な場合は cpupower を使い、使えない場合は cpufreq-set にフォールバックする。

応用的な使い方

全 CPU に一度にガバナーを設定する

デフォルトでは、cpupower frequency-set は CPU 0 にのみ影響する。全コアに適用するには:

sudo cpupower -c all frequency-set -g performance

cpufreq-set を使う場合:

for i in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do
  echo performance | sudo tee $i
done

周波数の上限・下限を手動で設定する

どのガバナーが有効かに関わらず、最小または最大周波数を固定することができる:

# 最小周波数を 2.0 GHz に設定
sudo cpupower frequency-set -d 2GHz

# 最大周波数の上限を 3.0 GHz に設定
sudo cpupower frequency-set -u 3GHz

ノートPC の発熱を抑えたり、共有サーバーで他のテナントのためにヘッドルームを確保したりするのに便利だ。ガバナーはその範囲内で動作し続ける — 単に動作範囲を狭めるだけだ。

コアごとのリアルタイム周波数を監視する

watch -n 1 "cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq"

または、よりきれいな表示で:

cpupower monitor -m Mperf

再起動後もガバナーを永続化する

cpupower によるガバナー変更は再起動後に残らない。解決策は 2 つある:

Ubuntu/Debian(cpufrequtils を使用):

sudo nano /etc/default/cpufrequtils
GOVERNOR="performance"
sudo systemctl enable cpufrequtils
sudo systemctl restart cpufrequtils

systemd を使用(ディストリビューション非依存):

起動時に実行するワンショットサービスを作成する:

sudo nano /etc/systemd/system/cpugovernor.service
[Unit]
Description=CPU ガバナーをパフォーマンスに設定
After=multi-user.target

[Service]
Type=oneshot
ExecStart=/usr/bin/cpupower -c all frequency-set -g performance
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now cpugovernor.service

スクリプト:電源状態に応じてガバナーを自動切換え(ノートPC)

AC 電源接続時は performance、バッテリー駆動時は powersave にしたい場合は、これを /usr/local/bin/cpu-governor-switch.sh に保存する:

#!/bin/bash
# /usr/local/bin/cpu-governor-switch.sh

POWER_STATUS=$(cat /sys/class/power_supply/AC/online 2>/dev/null || echo 1)

if [ "$POWER_STATUS" -eq 1 ]; then
    cpupower -c all frequency-set -g performance
    echo "AC 電源接続中 — ガバナーをパフォーマンスに設定"
else
    cpupower -c all frequency-set -g powersave
    echo "バッテリー駆動中 — ガバナーを省電力に設定"
fi
chmod +x /usr/local/bin/cpu-governor-switch.sh

udev の電源イベントにフックするか、数分ごとに cron ジョブから実行する。

実際の運用から学ぶ実践的なヒント

サーバー:プロビジョニング後は必ずガバナーを確認する

本番の Ubuntu 22.04 サーバー(Intel Core i5-8400、6 コア、4GB RAM)で powersave から performance に切り替えたところ、AI コンテンツ生成時間が 45 秒から約 28 秒に短縮された — コード変更なしで 38% の改善だ。CPU がずっと人為的に抑制されていたのだ。上記の systemd サービスにより、再起動やカーネルアップデートを経ても設定が維持された。

新しいクラウド VM やベアメタルサーバーは、ほぼ例外なく powersave または ondemand の状態で提供される。プロビジョニング直後に確認しよう。30 秒でできる作業だが、見落としやすい。

ターボブーストを確認する

performance ガバナーが有効でも、ターボブーストが独立して無効化されている場合がある。確認しておく価値がある:

# Intel の場合
cat /sys/devices/system/cpu/intel_pstate/no_turbo
# 0 = ターボ有効、1 = ターボ無効

# ターボブーストを有効化
echo 0 | sudo tee /sys/devices/system/cpu/intel_pstate/no_turbo

サーマルスロットリングとガバナースロットリングは別物

performance ガバナーを設定しても CPU が周波数を下げ続ける?それはサーマルスロットリングだ — ガバナーの問題ではない。監視ツールでは両者が同じように見えるが、原因はまったく異なる。確認するには:

dmesg | grep -i "cpu.*throttl"
cat /sys/class/thermal/thermal_zone*/temp

冷却の問題はガバナーのチューニングでは解決できない。まずヒートシンクを清掃しよう。

デスクトップ・ノートPC では schedutil を試す価値がある

ドライバーとして acpi-cpufreq を使用している場合(cpupower frequency-info で確認)、schedutil はたいていもっともバランスの良いガバナーだ。ondemand より速く負荷に反応し、performance より消費電力が少ない:

sudo cpupower -c all frequency-set -g schedutil

クイックヘルスチェックスクリプト

#!/bin/bash
echo "=== CPU 周波数ステータス ==="
echo "ドライバー: $(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_driver)"
echo "ガバナー: $(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor)"
echo "最小周波数: $(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq) kHz"
echo "最大周波数: $(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq) kHz"
echo "現在の周波数:"
for cpu in /sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq; do
  echo "  $(basename $(dirname $(dirname $cpu))): $(cat $cpu) kHz"
done

ガバナーを変更した後に実行して、全コアに設定が適用されたことを確認する。/usr/local/bin/cpu-status に保存して実行可能にしておく — 実行は 2 秒、一目でわかる情報が揃っている。

ガバナーのチューニングは地味な作業だ。しかし、CPU バウンドなワークロードでは差は明確かつ即効性があり、しかも 5 分しかかからない。問題でもないアプリケーションコードのプロファイリングに何時間も費やす前に、まずガバナーを確認しよう。

Share: