玩式草子─ソフトウェアとたわむれる日々

第25回 猛暑とCPUの発熱対策[その2]

この記事を読むのに必要な時間:およそ 4.5 分

前回紹介したように,手元のCore i7 CPUを使った開発機ではカーネルやGCCといった大規模なソフトウェアをmakeの-jオプションを使って並列度を上げてビルドしようとするとCPUの温度が危険なほど上昇してしまいます。この問題が起きるのは「大規模なソフトウェアを並列度を上げてビルドする」というかなり限定された場合のみなので,並列度を下げることで問題を回避することは可能ですが,そうするとビルドにかかる時間がずいぶん長くなってしまって不便です。

何かいい方法はないかなぁ……,と考えているうちにCpufreqと呼ばれる動作周波数数管理機能のことを思い出しました。

Linuxの動作周波数管理機能

去年買ったCore i7の動作周波数は2.93GHzだったように,最近のCPUの動作周波数は2GHzを大きく超えています。CPUの動作周波数は高ければ高いほど,1秒あたりの処理回数が増えて性能は向上しますが,その分,発熱も大きくなると共に消費電力も大きくなり,ノートPCのような環境では使いづらくなってしまいます。

そのような問題に対処するために,最近のCPUでは,従来は固定だった動作周波数を可変にして,必要に応じて動作中でも動作周波数を変更できるようになっています。この機能を使えば,CPUの処理がそれほど必要ない文字入力等の対話的な作業の際には周波数を下げて消費電力や発熱を抑制し,コンパイルや動画再生といったCPUパワーが必要な作業の際には周波数を上げて処理能力を高め,ユーザにストレスを感じさせずに電力消費や発熱を抑制することが可能です。

ただし,CPUの側からすると,ユーザの入力を待っている間でもプログラム中のウエイトループを全速力で回っているだけなので,作業負荷の高低を監視するにはOS側の協力が必要となります。Linuxで動作周波数を管理しているのはカーネル内部のcpufreqgovernorと呼ばれるドライバで,ユーザ領域で動作するcpufreqdがそれらを制御しています。

動作周波数設定用ドライバcpufreq

CPUの動作周波数を変更するにはカーネルレベルの権限が必要となるので,そのための機能はカーネル内部のcpufreqというドライバが担っています。また,動作周波数の変更方法はメーカやCPUによって異なるため,cpufreqドライバはいくつかの種類が用意されています。

現在,手もとで使っているlinux-2.6.38.4カーネルでは以下のようなcpufreqドライバが用意されていました。

acpi-cpufreq.koCore i7を含む,新しい世代のIntel製CPU用のドライバ。
p4-clockmod.koPentium 4世代のIntel製CPU用ドライバ。あまり細かい制御はできない。
speedstep-centrino.koPentium-M世代のIntel製CPU用ドライバ。機能はacpi-cpufreq.koにマージされたので現在はdeprecated(使用すべきでない)とされている
powernow-k8.koAMD製CPU用のドライバ。

これら以外にもx86互換CPUで主に組み込み向けに使われているAMD ElanやVIA Cyrix,あるいはx86系以外でもARMやSuperH,BlackfinといったさまざまなCPU用にcpufreqドライバは開発されているようです。

動作周波数制御用ドライバgovernor

cpufreqドライバがそれぞれのCPUに応じた方法で動作周波数を指定された値に設定する機能を担当しているのに対し,状況に応じて動作周波数をどのような値にするかを管理しているのがgovernorと呼ばれるドライバです。

状況に応じて動作周波数をどう選択するかにはさまざまな方針が考えられるため,governorドライバも複数の種類が用意されており,linux-2.6.38.4ではperformancepowersaveondemandconservativeuserspaceという5種類のgovernorが用意されています。それぞれのgovernorの動作周波数設定方針は以下の通りです。

performanceCPUの状況にかかわらず,指定された範囲で最大の動作周波数を選ぶ
powersaveperformanceの反対で,指定された範囲で最小の動作周波数を選ぶ
ondemandCPUの負荷状況を見ながら,指定された範囲内で動作周波数を上下させる
conservativeondemandと同じだが,周波数の変動をゆっくりめに行う
userspaceCPUの周波数の設定は常にユーザ領域のソフトウェアから行う

userspace以外のgovernorでは動作周波数を0から100%の間の一定の範囲で指定し,performance governorはそのうちの最大値を,powersave governorはそのうちの最小値を,それぞれ選ぶようになっています。

一方,ondemand governorは,ごく短い間隔(デフォルトでは10ms)ごとにCPUの使用率を調べ,その期間中のCPU使用率があらかじめ設定されている閾値(デフォルトでは95%)を超えていれば,指定された範囲内で動作周波数を上昇させ,閾値以下ならば動作周波数を下降させるように働きます。

conservative governorは,周波数を上下させる考え方はondemand governorと同じですが,ondemand governorが条件を満せば即座に周波数を変更するのに対し,周波数の変化が多少ゆっくりめになるように設定されています。

周波数の変動はそのまま消費電力の変動につながりますが,消費電力の変動は,急峻よりもなだらかな方がバッテリーに優しいので,ノートPCのような環境ではconservative governorが適しているそうです。

userspace governorは他のgovernorとは異なり,自分で周波数を設定することはせず,ユーザ領域のソフトウェアや手動設定で指定された周波数をcpufreqドライバに反映させる役割を持ちます。

これらのgovernorは必要に応じて切り替えることが可能で,普段はpowersave governorで動作周波数を最低限に抑えてバッテリーの消費を抑えつつ,動画再生用のソフトウェアを動かす時にはondemand governorに切り替えて必要なレベルまで動作周波数を高める,といった使い方が可能です。システムの動作状況を監視して,このような切り替え処理をするのがcpufreqdの役割です。

動作周波数管理デーモンcpufreqd

cpufreqやgovernorがカーネルレベルで動作するのに対し,cpufreqdはユーザ領域で動作して,あらかじめ指定された条件に応じてgovernorを切り替え,それを通じてcpufreqでCPUの動作周波数を調整します。

cpufreqdの設定ファイルは/etc/cpufreqd.confです。このファイルには,システムがどのような状況になればどのgovernorを適用するのかというルールを複数記述でき,cpufreqdはシステムの動作状況を監視しながら,それらのルールの中からもっとも状況に適合するものを選んで,そのルールに従ってgovernorを切り替えます。

もともとcpufreqdは,AC電源使用時とバッテリー使用時でCPUの動作速度を自動的に切り替えて,バッテリー使用時の動作時間を少しでも延ばそう,というニーズから生まれてきたソフトウェアなので,電源回りの状況(電源はACかバッテリーか,バッテリーの残量はどれくらいか,等)をACPIやAPMを使って監視する機能を豊富にもっています。

加えて最近では,CPUの負荷状態や特定のソフトウェアの動作の有無,lm-sensorsを経由した温度情報なども監視することができるようになっており,一定の温度を上まわれば動作周波数を落して発熱を抑える,といった設定も可能です。そこで今回は,cpufreqdにCPUの温度を監視させ,高温時には動作周波数を抑えることにしました。

著者プロフィール

こじまみつひろ

Plamo Linuxとりまとめ役。もともとは人類学的にハッカー文化を研究しようとしていたものの,いつの間にかミイラ取りがミイラになってOSSの世界にどっぷりと漬かってしまいました。最近は田舎に隠棲して半農半自営な生活をしながらソフトウェアと戯れています。

URLhttp://www.linet.gr.jp/~kojima/Plamo/index.html

コメント

コメントの記入