CORY's twilight zone > 98備忘録 (tips)[an error occurred while processing this directive] > FreeBSDでCPUの発熱や消費電力を抑える

FreeBSDでCPUの発熱や消費電力を抑える

since 2012.06.16 / CORY

今年も暑さに悩まされる時季が近づいてきました。年々暑くなり異常気象が毎年のように起きている昨今、さらに集積化・性能向上により機器自体の発熱量や熱耐性などの状況変化もあってか、パソコンやサーバを扱っていると、近年、夏を乗り切れずに壊れてしまう機器が毎年のようにあり、以前より格段に気遣いが求められている感があります。

一方、昨今の機器は省エネや発熱量抑制に対応すべく、様々な仕組みが採り入れられています。そうした仕組みはファームウェア等で制御されるものと、OSやドライバソフトウェアで制御するものがありますが、ここでは OS 側で CPU の電源管理を設定することで、どれくらい違うかを見てみることにします。

なお、ここでは FreeBSD 8.3-RELEASE での例を挙げていますが、以下で利用する powerd は6系列より導入されているので、他のバージョンでも試すことができると思われます。

目次

CPUの省電力技術 Intel SpeedStep / AMD PowerNow! 対応状況を確認する CPUの動作クロックと状態遷移について (おまけ)ハードディスクドライブ(HDD)の状態を見る

CPUの省電力技術

パソコンの高性能化(動作クロックの上昇や高集積化)によりCPUの消費電力も拡大し、大昔のパソコンにはCPUにヒートシンクすら乗っていなかったものが、80386の頃にはヒートシンクが載るようになり、Pentium時代に入るとCPUにはファン登載が主流になり(もちろん最近でも意図的にクロックを抑えるなどしてファンレス動作に対応する物がありますが)、最近では巨大なヒートシンクや冷却システムを備えるものも見かけます。

発熱量は動作クロックに比例し、また動作電圧の2乗に比例するそうです。Intel 486の頃は100MHz以下、今は数GHzですから、それだけ発熱量も増えて当然なのでしょう。

1994年発売の NEC PC-9801NS/A に搭載されたCPU i486SX (5V 33MHz) の消費電力は約1〜2W、システム全体の消費電力は12Wでした。

2005年発売の PC-VY12F/CH-W に搭載されているCPU Pentium M 超低電圧版 753 (約1V 1.2GHz) の消費電力は約6〜12Wで、システム全体の消費電力は10〜40W。さらに空冷ファンも電気を使います。 ノートパソコンではバッテリの制約があり全体の消費電力はあまり増やせませんが、その中で CPU が占める割合が大きくなっています。

デスクトップパソコンやサーバで使われるCPUの消費電力は100W超の製品もありますが、電源制約が厳しいノートパソコンや、近年はサーバでも省エネ要求に応えるため、仕事量に応じて動作クロックや電圧を可変とする技術が投入されるようになりました。

その先駆けは米トランスメタ社の LongRun 技術。パソコンや組込機器ではCPU能力が常に100%利用されているわけではありませんが、負荷の低い時には動作クロックを下げるなど、CPUの動作クロックを動的に変化させる技術を採り入れることで、使用感をあまり損なわずに消費電力・発熱量の削減を狙ったもの。2000年に同社より発売されたCPU Crusoe TM5600 (600MHz) に採用され、2001年発売の NEC PC-LX60T/7B1EC など国内メーカーのパソコンに搭載されました。この PC-LX60T/7B1EC ではバックライトをOFFにできる半透過型液晶を併用するなどの工夫もあり、仕様上のバッテリ駆動時間8〜11時間、標準消費電力 6W を実現したのは当時画期的でした。

LongRun技術・Crusoe はこれまでクロック競争をしていた他社(Intel と AMD)のロードマップにも影響を与え、高クロック競争をしていた Intel が速やかに対抗して低電圧版 Pentium M を発売、さらに類似技術である Intel SpeedStepAMD PowerNow! / Cool'n'Quiet が投入され、改良されるとともに、今では大半のCPUで採用されています。

…と前説明が長くなりましたが、この Intel SpeedStep や AMD PowerNow! のような、CPU の周波数・電圧を動的に変化させることで、アイドル時間のパソコンやサーバの発熱量・消費電力を引き下げる効果を期待できます。 これらの技術では、OS側の負荷に応じてCPUに動作を切り替える指示を出す必要があります。FreeBSD 6系列以降では、CPU の周波数制御を担当する cpufreq カーネルモジュールと、負荷に応じてCPUの設定を変える powerd デーモンが実装されており、これを起動しておけば上記の機能を使うことができます。

※Crusoe プロセッサ向け LongRun サポートcpufreq ライブラリで未対応のため、powerd からは制御できません。

Intel SpeedStep / AMD PowerNow! 対応状況を確認する

CPU が動作クロック・電圧の動的変更に対応していないと、この手法は使えません。まずはお使いの機器が対応しているかどうか、確認しておきます。

Intel CPU の場合NEC PC-VY12F/CH-X の例)

# kldload cpufreq
kldload: can't load cpufreq: File exists	←すでに組み込まれている場合はエラーになるが問題なし
% dmesg | grep -E "^(est|powernow)"
est0: <Enhanced SpeedStep Frequency Control> on cpu0
% sysctl -a dev.cpu.0.freq
dev.cpu.0.freq: 1200	←現在の動作クロック(MHz)

AMD CPU の場合hp Compaq t5720 の例)

# kldload cpufreq
kldload: can't load cpufreq: File exists	←すでに組み込まれている場合はエラーになるが問題なし
% dmesg | grep -E "^(est|powernow)"
powernow0: <PowerNow! K7> on cpu0
% sysctl -a dev.cpu.0.freq
dev.cpu.0.freq: 997	←現在の動作クロック(MHz)

powerd を動かしてみて、動作クロックの変化を見る

上記の要領で確認できれば、動作するのではと期待されます。 ただし、対応が不十分なアーキテクチャでは正常動作せず、システムが落ちる場合もあるようなので、以下の要領で予め動作確認しておく方がよさそうです。

% sysctl -a dev.cpu.0.freq
dev.cpu.0.freq: 1200	←powerdを起動する前の動作クロック
# kldload cpufreq
kldload: can't load cpufreq: File exists	←すでに組み込まれていれば問題なし
# ps ax | grep powerd	←powerdが起動しているか確認
	←何も返ってこなければ起動していない
# /usr/sbin/powerd	←powerdを起動(パラメータは必要に応じ指定)
# sysctl -a dev.cpu.0.freq
dev.cpu.0.freq: 700	←powerd起動前より周波数が落ちている

この状態でしばらく動作させてみて、不具合が起きなければ、次回起動時より自動的に立ち上がるようにしておきます。

# cat >> /boot/loader.conf
cpufreq_load="YES"	←すでに組み込まれている場合は不要
^D
# cat >> /etc/rc.conf
powerd_enable="YES"
powerd_flags="-i 85"	←任意、パラメータを指定
^D

上記各ファイルに設定しておけば、次回再起動時には powerd が有効になっているはずです。

なお、powerd は特にパラメータを指定しなければ、バッテリ動作中は adaptive(適応)、AC電源接続中は hiadaptive モードで動作します。 処理性能(と消費電力)の高い順に、 maximum(最大) > hiadaptive > adaptive(適応) > minimum(最小) となります。

CPUの動作クロックと状態遷移について

AMD Geode NX の例

hp Compaq t5720 Thin Client ではACPIを無効にしていますが、前述の動作クロックの切り替えはACPIやAPMに依存せず、cpufreq / powerd が動いていれば使うことができます。 また、この Geode NX は、PowerNow! が使えない環境(非対応マザーボードなど)でも動作クロック倍率を動的に切り替えられるようです(未確認)

※余談ながら、t5720 ではマザーボードに温度計が搭載されていないのか、thermal zone (acpi_tz0) が認識されながらエラーを吐くので、ACPI を切って動かしています。

% sysctl -a dev.cpu
dev.cpu.0.%driver: cpu
dev.cpu.0.%parent: legacy0
dev.cpu.0.freq: 665
dev.cpu.0.freq_levels: 997/-1 798/-1 665/-1

上記で dev.cpu.0.freq_levels の値が示しているように、このCPUでは 997MHz, 798MHz, 665MHz、つまり 7.5倍、6倍、5倍の3段階で切り替えられるようです。

ちなみにこの機械に搭載のCPU AMD Geode NX 1500 は、大きなヒートシンクこそ載っていますが、ファン無しで動作します。V_CORE(動作電圧)1V、TDP 9W、FSB 266MHz。2003年頃に発売された モバイル Athlon XP-M を組込向けに低電圧動作させているもののよう。 (参考:【特集】Geode NX 1500を試す - 低消費電力プラットフォーム徹底比較 要は一昔前のパソコンを使っている感覚なので、標準搭載の Windows Embedded はもちろん、FreeBSD/i386 や NetBSD/i386 がそのまま動きますし、100BASE-TX LAN、USB 2.0、シリアルポートなどを搭載しており、ちょっとした事なら充分こなせてしまいます。

さて、以下のように負荷をかけてみると、CPUクロックが上がり、powerd が動作している様子が分かります。

% sysctl -a dev.cpu
dev.cpu.0.%driver: cpu
dev.cpu.0.%parent: legacy0
dev.cpu.0.freq: 665	←動作クロックが下がっている状態で
dev.cpu.0.freq_levels: 997/-1 798/-1 665/-1

% tar czf - / > /dev/null &	←CPU負荷をかけると

% top -nz	↓CPUが高負荷に
last pid:  1395;  load averages:  0.34,  0.10,  0.03    up 0+03:16:06  17:48:05
21 processes:  2 running, 19 sleeping
CPU: 81.6% user,  0.0% nice,  4.5% system,  0.8% interrupt, 13.2% idle
Mem: 10M Active, 52M Inact, 54M Wired, 20K Cache, 58M Buf, 354M Free
Swap:

  PID USERNAME  THR PRI NICE   SIZE    RES STATE    TIME   WCPU COMMAND
 1393 cory        1 113    0  5348K  2828K RUN      0:19 77.59% bsdtar
 1038 root        1  44    0  3360K  1120K select   3:39  0.00% powerd
...

% sysctl -a dev.cpu
dev.cpu.0.%driver: cpu
dev.cpu.0.%parent: legacy0
dev.cpu.0.freq: 997	←動作クロックが上がっている
dev.cpu.0.freq_levels: 997/-1 798/-1 665/-1

Intel Pentium M 超低電圧版 の例

NEC PC-VY12F/CH-X で動かしている FreeBSD にて。ACPI で動作しており、14段階の切り替えに対応しているようです。 E-mailをはじめ様々な処理をこなしているインターネットサーバ機ですが、休日など暇になる時は 75MHz 動作まで落ちているようです。powerd を動かさないと筐体が熱を持ちますが、powerd を使うことで発熱が(おそらく消費電力も)大幅に抑えられています。

% sysctl -a dev.cpu
dev.cpu.0.%desc: ACPI CPU
dev.cpu.0.%driver: cpu
dev.cpu.0.%location: handle=\_PR_.CPU0
dev.cpu.0.%pnpinfo: _HID=none _UID=0
dev.cpu.0.%parent: acpi0
dev.cpu.0.freq: 75
dev.cpu.0.freq_levels: 1200/-1 1100/-1 1000/-1 900/-1 800/-1 700/-1 600/-1 525/-1 450/-1 375/-1 300/-1 225/-1 150/-1 75/-1
dev.cpu.0.cx_supported: C1/1 C2/1 C3/85
dev.cpu.0.cx_lowest: C1
dev.cpu.0.cx_usage: 100.00% 0.00% 0.00% last 424us

ACPI による CPU 状態遷移の範囲を指定する

ACPI では、周辺機器への電源制御や、システム自体のサスペンドなどを管理できるようになっています。FreeBSD では 6系列以降なら対応していますが、昔のシステムで不具合が出ることがままあり、ACPIを無効にして運用しているシステムもあるかもしれませんが、有効にしている場合は、下記の設定も検討してみると良いでしょう。

ACPI を使うと、負荷が低い時に CPU をスリープ状態へ切り替えることができます。この例では C1〜C3 の3つがあり、各々程度の異なる省電力状態を意味します。C1〜C3 は CPU の眠りの深さとでも評しましょうか、CPUが眠り(スリープ)から覚める(通常動作のC0状態に戻る)までの時間が異なります。CPUの種類や運用状況等によっても違うでしょうから、運用に差し支えのない設定にしましょう。

上記 PC-VY12F/CH-X の例では、初期値では C1 までしか認められていませんが、下記のように dev.cpu.0.cx_lowest の値を変更して C2/3 への遷移を許可します。

# sysctl dev.cpu.0.cx_lowest="C3"
dev.cpu.0.cx_lowest: C1 -> C3
(しばらく待つ)
% sysctl -a dev.cpu
dev.cpu.0.%desc: ACPI CPU
dev.cpu.0.%driver: cpu
dev.cpu.0.%location: handle=\_PR_.CPU0
dev.cpu.0.%pnpinfo: _HID=none _UID=0
dev.cpu.0.%parent: acpi0
dev.cpu.0.freq: 75
dev.cpu.0.freq_levels: 1200/-1 1100/-1 1000/-1 900/-1 800/-1 700/-1 600/-1 525/-1 450/-1 375/-1 300/-1 225/-1 150/-1 75/-1
dev.cpu.0.cx_supported: C1/1 C2/1 C3/85
dev.cpu.0.cx_lowest: C3
dev.cpu.0.cx_usage: 0.00% 0.63% 99.36% last 769us

なお、CPU の種類によっては、一旦 C3 に遷移すると、戻る際に時間がかかり、場合によってはシステムが停止したような状態になってしまう場合があるようです。特にマルチプロセッサ・マルチコアのシステムでは、全てのCPUを止めないよう注意します。 最悪止まっても大事にならない状態(シングルユーザモードや、デーモンを落とした状態にするなど)で設定値を調整し、差し支えがあるようなら C2 までの遷移を認める設定に変えるなど調整すると良いでしょう。

C-state は、簡単にまとめると次の通り(構成により変わると思うので参考までに)。一般に下へ行くほど省エネ効果が大きいとともに、C0 へ戻る際に時間がかかるようになります。

詳しくは…

この状態でしばらく運用してみて、問題が無いようであれば、/boot/loader.conf にこの設定を書いておけば、再起動後にも有効になります。

# cat >> /boot/loader.conf
dev.cpu.0.cx_lowest="C3"
^D
[an error occurred while processing this directive]

(おまけ)ハードディスクドライブ(HDD)の状態を見る

電子部品は全般に熱に弱いものの、特に気になるのはハードディスク。最近のHDDは一般にS.M.A.R.T.に対応していますが、対応ドライブでは smartmontools を使って状態を見ることができます。

FreeBSD ディストリビューションには含まれていないので、追加します。source から入れても、ports や packages を入れても構いません。FreeBSD 8.3-RELEASE の packages を入れる場合は下記の要領で。

# pkg_add ftp://ftp.jp.freebsd.org/pub/FreeBSD/releases/pc98/8.3-RELEASE/packages/sysutils/smartmontools-5.42_3.tbz
Fetching ftp://ftp.jp.freebsd.org/pub/FreeBSD/releases/pc98/8.3-RELEASE/packages/sysutils/smartmontools-5.42_3.tbz... Done.

smartmontools has been installed

To check the status of drives, use the following:

        /usr/local/sbin/smartctl -a /dev/ad0    for first ATA/SATA drive
        /usr/local/sbin/smartctl -a /dev/da0    for first SCSI drive
        /usr/local/sbin/smartctl -a /dev/ada0   for first SATA drive

To include drive health information in your daily status reports,
add a line like the following to /etc/periodic.conf:
        daily_status_smart_devices="/dev/ad0 /dev/da0"
substituting the appropriate device names for your SMART-capable disks.

To enable drive monitoring, you can use /usr/local/sbin/smartd.
A sample configuration file has been installed as
/usr/local/etc/smartd.conf.sample
Copy this file to /usr/local/etc/smartd.conf and edit appropriately

To have smartd start at boot
        echo 'smartd_enable="YES"' >> /etc/rc.conf

# rehash
# smartctl -a /dev/ad0
smartctl 5.42 2011-10-20 r3458 [FreeBSD 8.3-RELEASE i386] (local build)
Copyright (C) 2002-11 by Bruce Allen, http://smartmontools.sourceforge.net

=== START OF INFORMATION SECTION ===
Model Family:     Fujitsu MHV
Device Model:     FUJITSU MHV2080AT PL
Serial Number:    NS**********
Firmware Version: 000000A0
User Capacity:    80,026,361,856 bytes [80.0 GB]
Sector Size:      512 bytes logical/physical
Device is:        In smartctl database [for details use: -P show]
ATA Version is:   7
ATA Standard is:  ATA/ATAPI-7 T13 1532D revision 4a
Local Time is:    Sat Jun 16 20:28:55 2012 JST
SMART support is: Available - device has SMART capability.
SMART support is: Enabled

=== START OF READ SMART DATA SECTION ===
SMART overall-health self-assessment test result: PASSED

General SMART Values:
Offline data collection status:  (0x00) Offline data collection activity
                                        was never started.
                                        Auto Offline Data Collection: Disabled.
Self-test execution status:      (   0) The previous self-test routine completed
                                        without error or no self-test has ever
                                        been run.
Total time to complete Offline
data collection:                (  552) seconds.
Offline data collection
capabilities:                    (0x7b) SMART execute Offline immediate.
                                        Auto Offline data collection on/off support.
                                        Suspend Offline collection upon new
                                        command.
                                        Offline surface scan supported.
                                        Self-test supported.
                                        Conveyance Self-test supported.
                                        Selective Self-test supported.
SMART capabilities:            (0x0003) Saves SMART data before entering
                                        power-saving mode.
                                        Supports SMART auto save timer.
Error logging capability:        (0x01) Error logging supported.
                                        No General Purpose Logging support.
Short self-test routine
recommended polling time:        (   2) minutes.
Extended self-test routine
recommended polling time:        (  70) minutes.
Conveyance self-test routine
recommended polling time:        (   2) minutes.
SCT capabilities:              (0x003d) SCT Status supported.
                                        SCT Error Recovery Control supported.
                                        SCT Feature Control supported.
                                        SCT Data Table supported.

SMART Attributes Data Structure revision number: 16
Vendor Specific SMART Attributes with Thresholds:
ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
  1 Raw_Read_Error_Rate     0x000f   100   100   046    Pre-fail  Always       -       133749
  2 Throughput_Performance  0x0005   100   100   030    Pre-fail  Offline      -       28049408
  3 Spin_Up_Time            0x0003   100   100   025    Pre-fail  Always       -       1
  4 Start_Stop_Count        0x0032   099   099   000    Old_age   Always       -       1042
  5 Reallocated_Sector_Ct   0x0033   100   100   024    Pre-fail  Always       -       0 (2000, 0)
  7 Seek_Error_Rate         0x000f   100   100   047    Pre-fail  Always       -       3260
  8 Seek_Time_Performance   0x0005   100   100   019    Pre-fail  Offline      -       0
  9 Power_On_Seconds        0x0032   071   071   000    Old_age   Always       -       14963h+24m+55s
 10 Spin_Retry_Count        0x0013   100   100   020    Pre-fail  Always       -       0
 12 Power_Cycle_Count       0x0032   100   100   000    Old_age   Always       -       1009
192 Power-Off_Retract_Count 0x0032   100   100   000    Old_age   Always       -       20
193 Load_Cycle_Count        0x0032   090   090   000    Old_age   Always       -       215983
194 Temperature_Celsius     0x0022   100   100   000    Old_age   Always       -       37 (Min/Max 14/45)
195 Hardware_ECC_Recovered  0x001a   100   100   000    Old_age   Always       -       1070
196 Reallocated_Event_Count 0x0032   100   100   000    Old_age   Always       -       0 (0, 6972)
197 Current_Pending_Sector  0x0012   100   100   000    Old_age   Always       -       0
198 Offline_Uncorrectable   0x0010   100   100   000    Old_age   Offline      -       0
199 UDMA_CRC_Error_Count    0x003e   200   200   000    Old_age   Always       -       0
200 Multi_Zone_Error_Rate   0x000f   100   100   060    Pre-fail  Always       -       10170
203 Run_Out_Cancel          0x0002   100   100   000    Old_age   Always       -       2628540696075

SMART Error Log Version: 1
No Errors Logged

SMART Self-test log structure revision number 1
No self-tests have been logged.  [To run self-tests, use: smartctl -t]


SMART Selective self-test log data structure revision number 1
 SPAN  MIN_LBA  MAX_LBA  CURRENT_TEST_STATUS
    1        0        0  Not_testing
    2        0        0  Not_testing
    3        0        0  Not_testing
    4        0        0  Not_testing
    5        0        0  Not_testing
Selective self-test flags (0x0):
  After scanning selected spans, do NOT read-scan remainder of disk.
If Selective self-test is pending on power-up, resume after 0 minute delay.

上記のように、HDDの状態が一覧できます。 例えば温度を見たい場合、上記の例では194番に記録されているので、194番の値を参照すれば温度(このドライブでは℃で返る)が分かります。

# smartctl -a /dev/ad0 | grep -E ^194
194 Temperature_Celsius     0x0022   100   100   000    Old_age   Always       -       37 (Min/Max 14/45)

詳細パラメータはHDDのメーカーによって異なる場合があるので注意しましょう。 また、そもそも S.M.A.R.T. に対応していなかったり(以下は Apacer ATA Flash Disk の例)、対応していても Flash SSD などでは温度計の値を返さないドライブもあるようです。

# smartctl -a /dev/ad0
smartctl 5.42 2011-10-20 r3458 [FreeBSD 8.3-RELEASE i386] (local build)
Copyright (C) 2002-11 by Bruce Allen, http://smartmontools.sourceforge.net

=== START OF INFORMATION SECTION ===
Device Model:     512MB  ATA Flash Disk
Serial Number:    B13*****************
Firmware Version: ADAA408J
User Capacity:    512,483,328 bytes [512 MB]
Sector Size:      512 bytes logical/physical
Device is:        Not in smartctl database [for details use: -P showall]
ATA Version is:   6
ATA Standard is:  ATA/ATAPI-6 T13 1410D revision 3a
Local Time is:    Sat Jun 16 08:09:50 2012 JST
SMART support is: Unavailable - device lacks SMART capability.

A mandatory SMART command failed: exiting. To continue, add one or more '-T permissive' options.

改版履歴

2012.06.17
分かりにくい記述を補訂
2012.06.16
初版掲載

更新日 : 2012年06月26日 (329)

CORY's twilight zone > 98備忘録 (tips)[an error occurred while processing this directive] > FreeBSDでCPUの発熱や消費電力を抑える


« 短絡線 »
[ CORY's twilight zone | PC-98, FreeBSD(98), Mac OS X, Android | 鉄道・街 | 自然 | flickr | twitter (log) | YouTube | Contact ]

Copyright © 1996-2019 CORY / ISAKA Yoji. Some rights reserved:
Creative Commons Attribution-Share alike 2.1 Japan.