cpufreqの設定について

最近のIntel製のCPUには、
EISTという動作周波数を動的に変化させる技術が搭載されています。
Linuxカーネルはこの機能を利用可能であり、消費電力を抑えることが出来ます。
その機能を、実際に周波数や負荷を変化させて、消費電力にどれほどの差異が現れるのかを
実験して確認してみました。


環境
    CPU: Intel Xeon 3060 2.4GHz
    M/B: PDSMi+

    driver: acpi-cpufreq
    governor: ondemand

今回使用した実験機の場合、acpi-cpufreqというドライバをロードすれば周波数の制御が可能になります。
governorというのは周波数の調整のポリシーで、主に
    performance    ...    パフォーマンス重視で、負荷に関係なく常に最高速度を保つ
    ondemand    ...    負荷の低い時は周波数を下げ、高負荷の時は周波数を上げる
    powersave    ...    消費電力を最低限に抑えるため、常に最低のクロックで動作する
この様なものがあります。今回の実験ではondemandを使用しました。以下ではそれを前提にレポートします。

modprobe acpi-cpufreq
とmodprobeコマンドを実行してacpi-cpufreqをロードすると、/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequenciesに設定可能な周波数のリストが出現します。
あるいはcpufreq-infoコマンドを使用してもそのリストは見ることが出来ます。

指定可能な周波数は4段階あり、例えば手元のノートPCでは

cpufrequtils 002: cpufreq-info (C) Dominik Brodowski 2004-2006
Report errors and bugs to このメールアドレスはスパムボットから保護されています。閲覧するにはJavaScriptを有効にする必要があります。, please.
analyzing CPU 0:
  driver: acpi-cpufreq
  CPUs which need to switch frequency at the same time: 0
  hardware limits: 600 MHz - 1.20 GHz
  available frequency steps: 1.20 GHz, 1000 MHz, 800 MHz, 600 MHz
  available cpufreq governors: performance, ondemand, userspace
  current policy: frequency should be within 1.20 GHz and 1.20 GHz.
                  The governor "ondemand" may decide which speed to use
                  within this range.
  current CPU frequency is 1.20 GHz.

この様な表示が得られます。
ちなみにこのマシンの/proc/cpuinfoは

processor    : 0
vendor_id    : GenuineIntel
cpu family    : 6
model        : 13
model name    : Intel(R) Pentium(R) M processor 1.20GHz
stepping    : 8
cpu MHz        : 1200.000
cache size    : 2048 KB
fdiv_bug    : no
hlt_bug        : no
f00f_bug    : no
coma_bug    : no
fpu        : yes
fpu_exception    : yes
cpuid level    : 2
wp        : yes
flags        : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat clflush dts acpi mmx fxsr sse sse2 ss tm pbe nx bts est tm2
bogomips    : 2395.74
clflush size    : 64

この様になっています。
ちなみにEISTに対応していることを調べるにはflagsにestという値が出現しているかいないかで判断することが出来ます。

以下は実験用サーバ機の/proc/cpuinfoです。デュアルコアなのでOSからはCPUが2つあるように認識されています。

processor    : 0
vendor_id    : GenuineIntel
cpu family    : 6
model        : 15
model name    : Intel(R) Xeon(R) CPU            3060  @ 2.40GHz
stepping    : 6
cpu MHz        : 2394.181
cache size    : 4096 KB
physical id    : 0
siblings    : 2
core id        : 0
cpu cores    : 2
fdiv_bug    : no
hlt_bug        : no
f00f_bug    : no
coma_bug    : no
fpu        : yes
fpu_exception    : yes
cpuid level    : 10
wp        : yes
flags        : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe nx lm constant_tsc pni monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr lahf_lm
bogomips    : 4791.65
clflush size    : 64

processor    : 1
vendor_id    : GenuineIntel
cpu family    : 6
model        : 15
model name    : Intel(R) Xeon(R) CPU            3060  @ 2.40GHz
stepping    : 6
cpu MHz        : 2394.181
cache size    : 4096 KB
physical id    : 0
siblings    : 2
core id        : 1
cpu cores    : 2
fdiv_bug    : no
hlt_bug        : no
f00f_bug    : no
coma_bug    : no
fpu        : yes
fpu_exception    : yes
cpuid level    : 10
wp        : yes
flags        : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe nx lm constant_tsc pni monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr lahf_lm
bogomips    : 4788.39
clflush size    : 64

このサーバでacpi-cpufreqをロードしてみると、以下のような結果になりました。

processor    : 0
vendor_id    : GenuineIntel
cpu family    : 6
model        : 15
model name    : Intel(R) Xeon(R) CPU            3060  @ 2.40GHz
stepping    : 6
cpu MHz        : 900.000
cache size    : 4096 KB
physical id    : 0
siblings    : 2
core id        : 0
cpu cores    : 2
fdiv_bug    : no
hlt_bug        : no
f00f_bug    : no
coma_bug    : no
fpu        : yes
fpu_exception    : yes
cpuid level    : 10
wp        : yes
flags        : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe nx lm constant_tsc pni monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr lahf_lm
bogomips    : 4791.65
clflush size    : 64

processor    : 1
vendor_id    : GenuineIntel
cpu family    : 6
model        : 15
model name    : Intel(R) Xeon(R) CPU            3060  @ 2.40GHz
stepping    : 6
cpu MHz        : 900.000
cache size    : 4096 KB
physical id    : 0
siblings    : 2
core id        : 1
cpu cores    : 2
fdiv_bug    : no
hlt_bug        : no
f00f_bug    : no
coma_bug    : no
fpu        : yes
fpu_exception    : yes
cpuid level    : 10
wp        : yes
flags        : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe nx lm constant_tsc pni monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr lahf_lm
bogomips    : 4788.39
clflush size    : 64

何故かクロックが900MHzと表示されます。
cpufreq-infoを実行してみても、

cpufrequtils 002: cpufreq-info (C) Dominik Brodowski 2004-2006
Report errors and bugs to このメールアドレスはスパムボットから保護されています。閲覧するにはJavaScriptを有効にする必要があります。, please.
analyzing CPU 0:
  driver: acpi-cpufreq
  CPUs which need to switch frequency at the same time: 0
  hardware limits: 600 MHz - 900 MHz
  available frequency steps: 900 MHz, 600 MHz
  available cpufreq governors: userspace, performance
  current policy: frequency should be within 600 MHz and 900 MHz.
                  The governor "userspace" may decide which speed to use
                  within this range.
  current CPU frequency is 900 MHz (asserted by call to hardware).
analyzing CPU 1:
  driver: acpi-cpufreq
  CPUs which need to switch frequency at the same time: 1
  hardware limits: 600 MHz - 900 MHz
  available frequency steps: 900 MHz, 600 MHz
  available cpufreq governors: userspace, performance
  current policy: frequency should be within 600 MHz and 900 MHz.
                  The governor "userspace" may decide which speed to use
                  within this range.
  current CPU frequency is 900 MHz (asserted by call to hardware).

と表示されます。設定可能な周波数が2段階しかないようです。
2段階という点は置いておいても、設定可能な周波数が最大でも900MHzというのは
ドライバをインストールしていない状態の2.4GHzと比較してみてもおかしいことは明らかです。

しかし、カーネルコンパイルでベンチマークを行ってみたところ、900MHzとacpi-cpufreqをロードしていない素の状態(2.4GHz)ではスコアにほとんど差が出ませんでした。
以下の図1がベンチマークをとってみたグラフです。それぞれの条件で5回データをとりました。
X軸は単なるベンチマークの順番、Y軸がtimeコマンドの出力のuser項目を抜き出したものです。
また、カーネルソースツリーをディスク上に置いた場合とメモリ上に置いた場合の2通りのデータをとっています。

図1:カーネルコンパイルの所要時間
Image

つまり、900MHzと表示されている状態は実際は2.4GHzで動作していると考えられます。この様な、実際のクロックとは関連性のない奇妙な値が表持されている状態の原因は不明です。

また、900MHzと表示されている状態が2.4GHzだとしたら、表示上はその2/3倍である600MHzと表示されている状態は1.6GHzであると推測されます。
図2は、900MHzと600MHzの両方でカーネルコンパイルに掛かった時間を計測し、グラフまとめたものです。
ベンチマークの結果、900MHzではおおよそ400秒かかるのにたいし、600MHzではおおよそ600秒かかっています。つまり、同じ量の計算を行うのに3/2倍の時間が必要となっており、この600MHzと表示されている状態のクロックは実質1.6GHzだと考えられます。

図2:動作周波数毎のカーネルコンパイルの所要時間
Image

なぜ表示されるクロックが900MHz、600MHzという奇妙な値なのか、ということに関して、Intel社に在籍しているacpi-cpufreqの開発者の方にメールで質問を送ってみたところ、BIOSがエクスポートしている値がおかしいのではないか、との回答を得ました。
このマザーボードで使用しているBIOSではEISTで指定可能な周波数の値を設定することは出来ないことと、周波数とベンチマークの比率に整合性がとれているということを考えると、BIOSに問題があると推測されます。現時点ではそれ以上のことは分かっていません。

表示される値のおかしさは置いておいて、cpufreqの設定でgovehrnorをondemandにして、消費電流を測定してみました。
    600MHz(1.6GHz)でアイドル    ...    ほとんど負荷がかかっていない状態。
                        消費電流は約0.9A。
    900MHz(2.4GHz)でアイドル    ...    CPUの周波数が切り替わるほどには負荷がかかっているが、
                        切り替わった状態に対しては大した負荷ではないという状態。
                        また、acpi-cpufreqをロードしていない状態のアイドル時もこれです。
                        消費電力は約1.0A。j
    900MHz(2.4GHz)でビジー        ...    限界まで負荷がかかっている状態。
                        acpi-cpufreqがロードされていなくてもロードされていてもこれは変わらない。
                        消費電力は約1.2A。
以下の図3がそれらの状態をグラフにしたものです。

図3:cpufreqを用いた場合のXeon 3060サーバの主な消費電力の状態遷移
Image

acpi-cpufreqを用いると、アイドル時は0.1A分の消費電力を低く抑えることが可能になります。
今回の実験環境では0.1Aの低下でしたが、EISTという技術を積極的に利用すれば、他のCPUやマザーボードではより消費電力を抑えられる場合があると期待されます。