CORY's twilight zone > 98備忘録 (tips)[an error occurred while processing this directive] > FreeBSDでCPUの発熱や消費電力を抑える
今年も暑さに悩まされる時季が近づいてきました。年々暑くなり異常気象が毎年のように起きている昨今、さらに集積化・性能向上により機器自体の発熱量や熱耐性などの状況変化もあってか、パソコンやサーバを扱っていると、近年、夏を乗り切れずに壊れてしまう機器が毎年のようにあり、以前より格段に気遣いが求められている感があります。
一方、昨今の機器は省エネや発熱量抑制に対応すべく、様々な仕組みが採り入れられています。そうした仕組みはファームウェア等で制御されるものと、OSやドライバソフトウェアで制御するものがありますが、ここでは OS 側で CPU の電源管理を設定することで、どれくらい違うかを見てみることにします。
なお、ここでは FreeBSD 8.3-RELEASE での例を挙げていますが、以下で利用する powerd は6系列より導入されているので、他のバージョンでも試すことができると思われます。
◆ CPUの省電力技術 ◆ Intel SpeedStep / AMD PowerNow! 対応状況を確認する ◆ CPUの動作クロックと状態遷移について ■ (おまけ)ハードディスクドライブ(HDD)の状態を見る
パソコンの高性能化(動作クロックの上昇や高集積化)により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 SpeedStep、AMD PowerNow! / Cool'n'Quiet が投入され、改良されるとともに、今では大半のCPUで採用されています。
…と前説明が長くなりましたが、この Intel SpeedStep や AMD PowerNow! のような、CPU の周波数・電圧を動的に変化させることで、アイドル時間のパソコンやサーバの発熱量・消費電力を引き下げる効果を期待できます。 これらの技術では、OS側の負荷に応じてCPUに動作を切り替える指示を出す必要があります。FreeBSD 6系列以降では、CPU の周波数制御を担当する cpufreq カーネルモジュールと、負荷に応じてCPUの設定を変える powerd デーモンが実装されており、これを起動しておけば上記の機能を使うことができます。
※Crusoe プロセッサ向け LongRun サポートは cpufreq ライブラリで未対応のため、powerd からは制御できません。
CPU が動作クロック・電圧の動的変更に対応していないと、この手法は使えません。まずはお使いの機器が対応しているかどうか、確認しておきます。
# 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)
# 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)
上記の要領で確認できれば、動作するのではと期待されます。 ただし、対応が不十分なアーキテクチャでは正常動作せず、システムが落ちる場合もあるようなので、以下の要領で予め動作確認しておく方がよさそうです。
% 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(最小) となります。
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
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 では、周辺機器への電源制御や、システム自体のサスペンドなどを管理できるようになっています。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
電子部品は全般に熱に弱いものの、特に気になるのはハードディスク。最近の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月26日 (5392)
CORY's twilight zone > 98備忘録 (tips)[an error occurred while processing this directive] > FreeBSDでCPUの発熱や消費電力を抑える