cpupowerでCPU周波数を動的に変更する

## はじめに

　数年間使用したPCを新調し、Intel第4世代から第10世代に変わりました。コア数が倍増し、そろそろ排熱が空冷では追い付かなさそうな予感がしていましたが、案の定、CPUが100%で回らなくなってしまいました。

　今回は、CPU周波数をアンダークロックして、低負荷時には低消費電力で、高負荷時には高温にならないような運用ができるようにします。

（私個人の使用方法では、低負荷か高負荷が長時間続くことが多いので、PL2などの細かい電力制限には触れません。）

## 環境

CentOS 8
[Intel Core i7-10700](https://ark.intel.com/content/www/jp/ja/ark/products/199316/intel-core-i7-10700-processor-16m-cache-up-to-4-80-ghz.html)

## 現状の確認

低負荷状態
CPU周波数

```
$ grep "cpu MHz" /proc/cpuinfo
cpu MHz         : 4700.006
cpu MHz         : 4699.944
cpu MHz         : 4699.919
cpu MHz         : 4700.656
cpu MHz         : 4793.212
cpu MHz         : 4790.931
cpu MHz         : 4700.624
cpu MHz         : 4699.994
cpu MHz         : 4699.009
cpu MHz         : 4697.987
cpu MHz         : 4698.668
cpu MHz         : 4692.792
cpu MHz         : 4763.796
cpu MHz         : 4721.463
cpu MHz         : 4699.290
cpu MHz         : 4699.897
```

温度

```
$ sensors
Package id 0:  +48.0°C  (high = +80.0°C, crit = +100.0°C)
Core 0:        +48.0°C  (high = +80.0°C, crit = +100.0°C)
Core 1:        +46.0°C  (high = +80.0°C, crit = +100.0°C)
Core 2:        +45.0°C  (high = +80.0°C, crit = +100.0°C)
Core 3:        +47.0°C  (high = +80.0°C, crit = +100.0°C)
Core 4:        +46.0°C  (high = +80.0°C, crit = +100.0°C)
Core 5:        +45.0°C  (high = +80.0°C, crit = +100.0°C)
Core 6:        +46.0°C  (high = +80.0°C, crit = +100.0°C)
Core 7:        +48.0°C  (high = +80.0°C, crit = +100.0°C)
```

電力

```
$ sudo powertop
[Device stats]
System baseline power is estimated at 6.66 W
```

高負荷状態
CPU周波数

```
$ grep "cpu MHz" /proc/cpuinfo
cpu MHz         : 4328.071
cpu MHz         : 4346.428
cpu MHz         : 4342.870
cpu MHz         : 4336.785
cpu MHz         : 4339.932
cpu MHz         : 4330.750
cpu MHz         : 4339.736
cpu MHz         : 4335.298
cpu MHz         : 4290.729
cpu MHz         : 4332.395
cpu MHz         : 4352.393
cpu MHz         : 4345.483
cpu MHz         : 4338.481
cpu MHz         : 4329.166
cpu MHz         : 4339.690
cpu MHz         : 4330.716
```

温度

```
$ sensors
Package id 0: +100.0°C  (high = +80.0°C, crit = +100.0°C)
Core 0:        +98.0°C  (high = +80.0°C, crit = +100.0°C)
Core 1:       +100.0°C  (high = +80.0°C, crit = +100.0°C)
Core 2:        +97.0°C  (high = +80.0°C, crit = +100.0°C)
Core 3:        +93.0°C  (high = +80.0°C, crit = +100.0°C)
Core 4:        +99.0°C  (high = +80.0°C, crit = +100.0°C)
Core 5:       +100.0°C  (high = +80.0°C, crit = +100.0°C)
Core 6:        +90.0°C  (high = +80.0°C, crit = +100.0°C)
Core 7:        +89.0°C  (high = +80.0°C, crit = +100.0°C)
```

電力

```
$ sudo powertop
[Device stats]
System baseline power is estimated at 138 W
```

低負荷状態ではターボブーストが常に効いた周波数になっています。
高負荷状態では100℃に到達しており、CPUがクロックを下げていることが確認できます。Tjuncion=100℃なのでダイの損傷が気になります。

目標は、低負荷状態では最低周波数で動作し、高負荷状態では80℃を超えないようにします。

## tunedの停止

競合するtunedを停止します。

```
$ sudo systemctl stop tuned
$ sudo systemctl disable tuned
```

## cpupowerの設定

```
$ cpupower frequency-set -g powersave
```

設定可能なガバナーは以下で確認。

```
$ cpupower frequency-info -g
analyzing CPU0'
  available cpufreq governors: performance powersave
```

performanceまたはpowersaveが設定可能なようです。
意味はドキュメントを確認する。
https://www.kernel.org/doc/Documentation/cpu-freq/governors.txt

performance　最小～最大周波数の内、最大周波数で動作
powersave　最小～最大周波数の内、最小周波数で動作
（staticallyと書いてありますが、Turbo Boostが有効だと動的に変更してくれるようです。）

## 設定後の動作確認

/proc/cpuinfoを確認すると800MHzまで下がりました。

```
cpu MHz         : 800.019
cpu MHz         : 800.118
cpu MHz         : 800.019
cpu MHz         : 800.059
cpu MHz         : 800.007
cpu MHz         : 800.050
cpu MHz         : 800.070
cpu MHz         : 800.182
cpu MHz         : 800.067
cpu MHz         : 800.116
cpu MHz         : 800.206
cpu MHz         : 800.202
cpu MHz         : 800.064
cpu MHz         : 800.013
cpu MHz         : 800.014
cpu MHz         : 800.049
```       

## 周波数範囲の確認

```
$ cpupower frequency-info -p
analyzing CPU 0:
  current policy: frequency should be within 800 MHz and 4.80 GHz.
                  The governor "powersave" may decide which speed to use
                  within this range.
```

周波数範囲は、800MHz～4.8GHzのようです。

## 周波数範囲の設定

下限をベース動作周波数である2.9GHzに、上限を3.8GHzにしてみます。

```
$ cpupower frequency-set --min 2.9GHz --max 3.8GHz
```

低負荷状態
CPU周波数

```
cpu MHz         : 2902.360
cpu MHz         : 2901.175
cpu MHz         : 2900.632
cpu MHz         : 2902.443
cpu MHz         : 2900.469
cpu MHz         : 2899.796
cpu MHz         : 2900.445
cpu MHz         : 2901.305
cpu MHz         : 2901.635
cpu MHz         : 2901.020
cpu MHz         : 2901.466
cpu MHz         : 2900.628
cpu MHz         : 2900.409
cpu MHz         : 2901.041
cpu MHz         : 2900.094
cpu MHz         : 2901.011
```

高負荷状態
CPU周波数

```
cpu MHz         : 3800.000
cpu MHz         : 3799.999
cpu MHz         : 3800.000
cpu MHz         : 3800.000
cpu MHz         : 3800.000
cpu MHz         : 3800.000
cpu MHz         : 3800.002
cpu MHz         : 3800.001
cpu MHz         : 3800.001
cpu MHz         : 3800.000
cpu MHz         : 3800.000
cpu MHz         : 3800.000
cpu MHz         : 3800.000
cpu MHz         : 3800.000
cpu MHz         : 3800.001
cpu MHz         : 3800.001
```

温度
80℃前後で安定しています。

```
Package id 0:  +82.0°C  (high = +80.0°C, crit = +100.0°C)
Core 0:        +82.0°C  (high = +80.0°C, crit = +100.0°C)
Core 1:        +79.0°C  (high = +80.0°C, crit = +100.0°C)
Core 2:        +74.0°C  (high = +80.0°C, crit = +100.0°C)
Core 3:        +79.0°C  (high = +80.0°C, crit = +100.0°C)
Core 4:        +73.0°C  (high = +80.0°C, crit = +100.0°C)
Core 5:        +77.0°C  (high = +80.0°C, crit = +100.0°C)
Core 6:        +72.0°C  (high = +80.0°C, crit = +100.0°C)
Core 7:        +72.0°C  (high = +80.0°C, crit = +100.0°C)
```

電力

```
System baseline power is estimated at 87.9 W
```

## cpupowerサービスを永続化する

以下の内容で/etc/sysconfig/cpupowerを修正します。

```
$ cat /etc/sysconfig/cpupower
CPUPOWER_START_OPTS="frequency-set -g powersave --min 2.9GHz --max 3.8GHz"
CPUPOWER_STOP_OPTS="frequency-set -g powersave --min 2.9GHz --max 3.8GHz"
```

サービスを有効にする。

```
$ sudo systemctl enable cpupower
```

## まとめ

　CPU周波数を負荷に応じて動的に変更するようにしました。CPUが高負荷状態になると温度が100℃まで上昇し動作周波数が下がっているので、上限値を抑えることで高負荷状態でもCPU温度を80℃前後に抑えることができました。

　CPUのコア数が増えている現在ですが、最大性能で動作させ続けるには素人では難しい感じがしました。