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

第24回猛暑とCPUの発熱対策その1]

例年よりもずいぶん早めに梅雨が明け、いよいよ夏本番の時期となりました。原発事故による電力不足とあいまって、今年の夏は例年よりも厳しい暑さになりそうです。

最近の猛暑は人間にとってもこたえますが、十分な空調設備の無い環境で酷使されるPCにとっても厳しい季節の到来です。特に昨秋導入したCore i7機にとっては初の本格的な暑さで、果してどうなることかと思っていたら、さっそく発熱による問題に直面することになりました。

謎の警告音

授業や地区の営農組合やらであわただしかった時期がすぎ、やっとまとまった時間が取れるようになったので、そろそろPlamo Linuxの開発に復帰しようと、久しぶりにGCCのサイトを眺めてみると、GCC-4.6.1と共にGCC-4.5.3がリリースされていることに気づきました。

新しいGCC-4.6.1も面白そうですが、現在、Plamo-5.0用にはGCC-4.5.2を収めているので、パッケージ作りのリハビリを兼ねてGCC-4.5.3をパッケージ化することにしました。

最近のGCCは数値演算用にGMP(Gnu Multiple Precision arithmetric library)MPFR(Multiple-Precision Floating-point computations with correct Rounding)といったライブラリ類を必要とします。ざっと調べてみるとそれらのライブラリも少しずつバージョンアップしていたので、まずそれらのライブラリをパッケージ化し、手元の環境をアップデートした上でGCCのビルドに取りかかりました。

GCC-4.5.3のビルドを始めてしばらくすると、散発的にビープ音が鳴り始めました。始めのうちは短かい「ピッ」⁠ピッ」という音で、何かコンパイルエラーでも起きたのかな、と思って画面を確認したものの、コンパイル作業は特に問題なく続いています。

「あれれ、どうしたのだろう?」と思っているうちに、ビープ音の鳴る間隔がしだいに短くなり、ついには「ビー」という音が鳴りっぱなしになってしまいました。さすがにこれはマズい、と思ってCtrl-Cを連打しビルド作業を止めるとビープ音もすぐ収まりました。

何が起きたのだろう?と恐る恐るいくつかコマンドを打ちこんでみても、特に動作に支障はありません。dmesgでカーネルのログを見たり/var/log/以下に保存されている各種ログファイルを調べても、特にエラーメッセージ等は記録されていません。念のためリブートもしてみましたが、何の問題も無かったように立ちあがります。

さて、あのビープ音は何だったんだろう……、としばらく考えていたところ、BIOSの設定でCPUの温度を監視していたことを思い出しました。

今使っているGIGABYTEのマザーボードには"PC-Health"という機能があり、CPUの温度を監視して、あらかじめ設定しておいた温度に達すると警告音を鳴らしてくれます。BIOS画面で改めて確認すると80℃で警告音を鳴らすような設定になっていました。

図1 BIOSのPC-Healthの設定画面
図1 BIOSのPC-Healthの設定画面

どうやらあのビープ音はCPUの温度が上がりすぎたことへの警告音だったようですが、はたしてどの程度CPUの温度が上がっていたのでしょう? また、それは一時的な問題だったのか、これからも継続する問題なのでしょうか? まずは状況を確認してみようと、高負荷時にCPUの温度がどれくらい上がるのかを調べてみることにしました。

最近のマザーボードやCPUには温度監視用のセンサが組み込まれており、Linuxではそれらを利用するためにlm-sensorsというソフトウェアが開発されています。まずはこのソフトウェアを使ってPC内部の温度を調べてみることにしました。

lm-sensorsのインストール

lm-sensors(Linux Monitoring sensors)はCPUやPCのマザーボードに設置された各種センサから、さまざまなデータを採取するためのソフトウェアです。

もっとも、CPUやマザーボード上のセンサにアクセスするにはカーネルレベルの権限が必要となるため、センサを実際に操作するドライバ類はカーネルのソースコードに組み込まれており、ユーザ領域で動作するlm-sensorsはそれらカーネルドライバとやりとりするためのユーザ領域用のソフトウェアになっています。

CPUやマザーボードに組み込まれているセンサには明確な規格が無いようで、さまざまなメーカがいろいろな特徴を持つセンサを開発しており、マザーボードメーカもそれらの中から都合のいいものを選んでいるようで、同じマザーボードメーカでも使っているセンサ用チップはマザーボードごとに異なっていたりします。そのような状況に対応するために、最近のカーネルには多数のセンサ用ドライバが用意されており、linux-2.6.38には80を越えるモジュールドライバが含まれていました。

% ls /lib/modules/2.6.38.4-plamo64/kernel/drivers/hwmon/
abituguru.ko   adm9240.ko       dme1737.ko   hwmon-vid.ko  lm75.ko  lm95241.ko  sis5595.ko     w83627ehf.ko
abituguru3.ko  ads7828.ko       ds1621.ko    hwmon.ko      lm77.ko  ltc4215.ko  smsc47b397.ko  w83627hf.ko
ad7414.ko      adt7462.ko       f71805f.ko   i5k_amb.ko    lm78.ko  ltc4245.ko  smsc47m1.ko    w83781d.ko
ad7418.ko      adt7470.ko       f71882fg.ko  ibmaem.ko     lm80.ko  max1111.ko  smsc47m192.ko  w83791d.ko
... 
adm1031.ko     coretemp.ko      hp_accel.ko  lm70.ko       lm93.ko  sht15.ko    vt8231.ko

最近のLinuxでは、PCIやUSBといった高機能なバスに接続されるハードウェアは、バス上に流れる識別情報をもとにudevsysfsを使って自動認識し、それらを操作するのに必要なドライバはたいてい自動的に組み込まれるようになっています。

一方、温度監視等のセンサ類はマザーボード上に直接組み込まれることもあって、ISAやI2Cといった自動識別機能を持たないシンプルなバスに接続されることが多く、どのようなチップが搭載されていて、どのドライバで操作可能かは実際に試してみないと分かりません。そのためのツールがlm-sensorsパッケージに含まれているsensors-detectです。

sensors-detectコマンドを実行すると、センサ用チップが接続されていそうな場所を順に探し、見つかったチップとそれに対応したドライバを報告してくれます。

# sensors-detect
# sensors-detect revision 5861 (2010-09-21 17:21:05 +0200)
# System: Gigabyte Technology Co., Ltd. P55-USB3

This program will help you determine which kernel modules you need
to load to use lm_sensors most effectively. It is generally safe
and recommended to accept the default answers to all questions,
unless you know what you're doing.

Some south bridges, CPUs or memory controllers contain embedded sensors.
Do you want to scan for them? This is totally safe. (YES/no): 
....
AMD Family 11h thermal sensors...                           No
Intel Core family thermal sensor...                         Success!
    (driver `coretemp')
Intel Atom thermal sensor...                                No
....
Some Super I/O chips contain embedded sensors. We have to write to
standard I/O ports to probe them. This is usually safe.
Do you want to scan for Super I/O sensors? (YES/no):
Probing for Super-I/O at 0x2e/0x2f
Trying family `National Semiconductor'...                   No
Trying family `SMSC'...                                     No
Trying family `VIA/Winbond/Nuvoton/Fintek'...               No
Trying family `ITE'...                                      Yes
Found `ITE IT8720F Super IO Sensors'                        Success!
    (address 0x290, driver `it87')
Probing for Super-I/O at 0x4e/0x4f
Trying family `National Semiconductor'...                   No
...
Now follows a summary of the probes I have just done.
Just press ENTER to continue: 

Driver `it87':
  * ISA bus, address 0x290
    Chip `ITE IT8720F Super IO Sensors' (confidence: 9)

Driver `coretemp':
  * Chip `Intel Core family thermal sensor' (confidence: 9)

Do you want to overwrite /etc/sysconfig/lm_sensors? (YES/no): no
To load everything that is needed, add this to one of the system
initialization scripts (e.g. /etc/rc.d/rc.local):

#----cut here----
# Chip drivers
modprobe coretemp
modprobe it87
/usr/bin/sensors -s
#----cut here----
...

Core i7機でsensors-detectを実行したところ、上記のように"Intel Core family thermal sensor"と呼ばれるCPU内蔵の温度センサと"ITE IT8720F Super IO Sensors"と呼ばれるマザーボード上のセンサが見つかり、それらを利用するためにcoretempit87というドライバが必要であることが報告されています。

メッセージの最後にあるように、Red Hat系のディストリビューションではシステム用の設定ファイルは/etc/sysconfig/以下に収めますが、Plamo Linuxでは/etc/sysconfig/は使っていないので、/etc/rc.d/rc.localに上記スクリプトを組み込んで、必要なドライバは起動時にロードするようにしました。

上記モジュールドライバを組み込むと、lm-sensorsパッケージに含まれているsensorsコマンドでデータを読み出すことができます。

% sensors
coretemp-isa-0000
Adapter: ISA adapter
Core 0:      +50.0°C  (high = +83.0°C, crit = +99.0°C)  

coretemp-isa-0001
Adapter: ISA adapter
Core 1:      +53.0°C  (high = +83.0°C, crit = +99.0°C)  

coretemp-isa-0002
Adapter: ISA adapter
Core 2:      +50.0°C  (high = +83.0°C, crit = +99.0°C)  

coretemp-isa-0003
Adapter: ISA adapter
Core 3:      +47.0°C  (high = +83.0°C, crit = +99.0°C)  

it8720-isa-0290
Adapter: ISA adapter
in0:         +0.85 V  (min =  +0.00 V, max =  +4.08 V)   
in1:         +1.58 V  (min =  +0.00 V, max =  +4.08 V)   
in2:         +3.39 V  (min =  +0.00 V, max =  +4.08 V)   
+5V:         +2.94 V  (min =  +0.00 V, max =  +4.08 V)   
in4:         +0.03 V  (min =  +0.00 V, max =  +4.08 V)   
in5:         +3.09 V  (min =  +0.00 V, max =  +4.08 V)   
in6:         +0.00 V  (min =  +0.00 V, max =  +4.08 V)   ALARM
5VSB:        +2.94 V  (min =  +0.00 V, max =  +4.08 V)   
Vbat:        +3.30 V
fan1:       2335 RPM  (min =   10 RPM)
fan2:          0 RPM  (min =    0 RPM)
fan3:          0 RPM  (min =    0 RPM)
fan4:          0 RPM  (min =    0 RPM)
temp1:       +48.0°C  (low  = +127.0°C, high = +127.0°C)  sensor = thermistor
temp2:       +25.0°C  (low  = +127.0°C, high = +127.0°C)  sensor = thermistor
temp3:       +39.0°C  (low  = +127.0°C, high = +70.0°C)  sensor = thermistor

sensorsコマンドを実行すると、coretemp-isa-0000から0003のデータとしてCPU内蔵の温度センサから得られた4つのCPUの温度、it8720-isa-0290からのデータとして電圧やファンの回転数、マザーボード上の温度についての情報が得られました。

sensorsコマンドを使えば動作中のCPU温度を知ることができますが、作業中にいちいちコマンドを叩かないと温度を調べられないのも面倒です。そう考える人も多いのか、これらの情報をリアルタイムで表示するためのソフトウェアもいろいろ開発されています。今、手元ではKDE環境を使っているので、今回はKDEに付属のシステムモニタウィジェットを試してみました。

KDEのシステムモニタウィジェットではlm-sensorsから得られる温度情報だけでなく、CPUの負荷やネットワークの利用状況、メモリやHDDの使用状況などをリアルタイムで表示してくれます。今回はCPUの負荷と温度との関係を調べるために、これら2つの情報を並べて表示してみました。なお、Core i7はクアッドCPUでハードウェア的なCPUは4つですが、ハイパースレッド機能のおかげでソフトウェア的には8つに見えるので、CPUは0から7までの8つを表示しています。

図2 KDEのシステムモニタの表示。安静時の状態
図2 KDEのシステムモニタの表示。安静時の状態

本原稿はKDE環境上でEmacsを使って書いていますが、その程度の利用状況ではほとんどのCPUがアイドル状態で、CPUの温度も50℃前後に収まっているようです。

カーネルコンパイルとCPU温度

さて、こうしてCPU温度を監視できるようにした上で、高負荷な作業時にCPUの温度がどれくらい上昇するかを調べてみました。高負荷な作業としてカーネルをmake -j4でビルドすることにしました。makeの-jオプションはコンパイル作業を並列化して複数同時実行する指示で、-j4ならば4つのコンパイル作業を同時に行うことになります。

make -j4でカーネルのビルドを始めると数分程度でCPUの温度が80℃に逹し、警告のビープ音がひっきりなしに鳴り出しました。

図3 KDEのシステムモニタの表示。高負荷時の状態
図3 KDEのシステムモニタの表示。高負荷時の状態

システムモニタのCPU負荷のグラフを見ると、8つのCPU全てにかなり高い負荷がかかりっぱなしになっていることがわかります。makeのオプションを変えて試してみたところ、-j2と並列度を半分にした場合、警告音の鳴る回数は多少減るものの、かなり長く鳴り続けることもあって耳障りです。一方、-jオプションを付けずに動かすとCPUの温度は70℃前後に留まり、警告音は鳴らないままカーネルビルドが完了しました。

図4 KDEのシステムモニタの表示。-jオプションなしのカーネルビルド
図4 KDEのシステムモニタの表示。-jオプションなしのカーネルビルド

カーネルのビルド以外の作業もあれこれ試してみたところ、Core i7は熱しやすく冷めやすいCPUで、高負荷時にはかなり温度が上がるものの、少し負荷が下がると温度も急速に下がり、CPU1つか2つで間に合う程度の作業ならばアイドル時間が十分あってそれほど高温状態が続かないようです。一方、make -j4のように並列度の高い作業を流すと、それぞれのCPUが休む間もなく動き、温度が下がる暇がなくなって、CPU温度が80℃を越えてしまうようでした。

このマシンはオーバークロックしているわけでもないし、最近のCPUは本当に危険な温度になった場合は自動的に周波数を下げたり、安全装置が働いて止まるようになっているはずなので、BIOSの警告音を止めてしまっても大丈夫だろうとは思いますが、温度情報を目に見えるようにしてしまった分、やはりCPUの高温状態は気になってしまいます(苦笑⁠⁠。

この問題が発生するのはカーネルとGCCのビルド時くらいなので、それらの作業の際にmakeの並列化を使わないことにすればとりあえず回避できそうですが、そうするとビルドにかかる時間がずいぶん長くなって不便です。これからしばらくは暑い時期が続くので、さてどうしたものか、と考えることになりました。

おすすめ記事

記事・ニュース一覧