Raspberry PiをオーバークロックしてUnix Benchmark取ってみた。
パフォーマンスはチューニングしたわけではなく、普段起動してあるサービスは起動したままターミナルを2つだけ開いてベンチマークを実行。 もう一つのターミナルではクロック速度と温度を監視するスクリプトを実行しておいた。
- ベンチマーク環境
- オーバークロックの方法
- デフォルト
- オーバークロック 1750 MHz
- オーバークロック 2000 MHz
- オーバークロック 2000MHz (force turbo)
- オーバークロック 2000MHz (force turbo + 温度計測なし)
- ベンチマーク結果比較
- 考察
ベンチマーク環境
- Model: Raspberry Pi 4 Model B Rev 1.4
- OS: Ubuntu 20.04.3 LTS (Focal Fossa) bullseye/sid
BYTE UNIX Benchmarks (Version 5.1.3) System: raspi: GNU/Linux OS: GNU/Linux -- 5.4.0-1047-raspi -- #52-Ubuntu SMP PREEMPT Wed Nov 24 08:16:38 UTC 2021 Machine: aarch64 (aarch64) Room Temperature: around 10 ℃
オーバークロックの方法
下準備
ハードウェア状態を監視するためのツールをインストール
sudo apt install -y libraspberrypi-bin
CPUクロックの定格をチェック
クロックを監視
watch -n 1 sudo vcgencmd measure_clock arm
温度を監視
watch -n 1 sudo vcgencmd measure_temp
電圧を取得
sudo vcgencmd measure_volts
オーバークロック
電圧とクロックを上げる。 /bootをいじるので慎重に。
ブートの設定は/boot/firmwareにある。 READMEを読んだら作業に入る。
sudo nano /boot/firmware/usercfg.txt
以下を追加
over_voltage=2 arm_freq=1750
保存してリブートするとオーバークロックが実現する。
import pandas as pd import matplotlib.pyplot as plt from datetime import datetime pd.options.display.float_format = "{:.4g}".format plt.rcParams["figure.figsize"] = (9, 6) plt.style.use("seaborn-bright") results = []
def load_data(filename) -> pd.DataFrame: df = pd.read_csv(filename) df["clock [MHz]"] = df["clock [Hz]"] / 1e6 del df["clock [Hz]"] df["time"] = df["time"].apply(lambda x: datetime.fromisoformat(x)) df["throttled"] = df["throttled"].apply(lambda x: x.strip()).apply(lambda x: int(x, base=16)) df = df[["time", "temp [℃]", "clock [MHz]", "voltage [V]", "throttled"]] df.set_index("time", inplace=True) return df def parse_benchmark_result(filename) -> pd.DataFrame: with open(filename) as f: lines = f.readlines() names = [] scores = [] for line in lines: if line.startswith(" "): continue split = line.split() if len(split) < 3: continue try: score = float(split[-1]) except ValueError: continue names.append(" ".join(split[:-3])) scores.append(score) n = len(names) // 2 names = names[:n] names[-1] = "System Benchmarks Index Score" return pd.DataFrame({"name": names, "1 core": scores[:n], "4 core": scores[n:]})
デフォルト
コンフィグ
arm_freq=1500
ベンチマーク結果
results.append(parse_benchmark_result("0/results/raspi-2021-12-31-01")) results[0]
name | 1 core | 4 core | |
---|---|---|---|
0 | Dhrystone 2 using register variables | 1293 | 5018 |
1 | Double-Precision Whetstone | 487.4 | 1902 |
2 | Execl Throughput | 96.9 | 329.2 |
3 | File Copy 1024 bufsize 2000 maxblocks | 231.6 | 445.8 |
4 | File Copy 256 bufsize 500 maxblocks | 154 | 289.2 |
5 | File Copy 4096 bufsize 8000 maxblocks | 447.4 | 738.1 |
6 | Pipe Throughput | 112.6 | 436 |
7 | Pipe-based Context Switching | 70.2 | 288.8 |
8 | Process Creation | 204.1 | 473.6 |
9 | Shell Scripts (1 concurrent) | 387.4 | 1019 |
10 | Shell Scripts (8 concurrent) | 873.8 | 972.4 |
11 | System Call Overhead | 113.4 | 430.1 |
12 | System Benchmarks Index Score | 250.2 | 665.9 |
CPUの状態
df = load_data("0/data.csv")
df.describe()
temp [℃] | clock [MHz] | voltage [V] | throttled | |
---|---|---|---|---|
count | 2879 | 2879 | 2879 | 2879 |
mean | 40.39 | 1467 | 0.85 | 0 |
std | 4.668 | 58.85 | 1.11e-16 | 0 |
min | 32.1 | 1200 | 0.85 | 0 |
25% | 36 | 1400 | 0.85 | 0 |
50% | 40.4 | 1500 | 0.85 | 0 |
75% | 44.8 | 1500 | 0.85 | 0 |
max | 50.1 | 1500 | 0.85 | 0 |
df.plot(subplots=True, );
オーバークロック 1750 MHz
コンフィグ
arm_freq=1750 over_voltage=2
ベンチマーク結果
results.append(parse_benchmark_result("1/results/raspi-2021-12-31-01")) results[1]
name | 1 core | 4 core | |
---|---|---|---|
0 | Dhrystone 2 using register variables | 1508 | 5878 |
1 | Double-Precision Whetstone | 569.3 | 2220 |
2 | Execl Throughput | 112.8 | 374.4 |
3 | File Copy 1024 bufsize 2000 maxblocks | 270.6 | 521.6 |
4 | File Copy 256 bufsize 500 maxblocks | 176.9 | 341.3 |
5 | File Copy 4096 bufsize 8000 maxblocks | 512.3 | 837 |
6 | Pipe Throughput | 132.2 | 509.8 |
7 | Pipe-based Context Switching | 82.2 | 340.5 |
8 | Process Creation | 222.6 | 506.4 |
9 | Shell Scripts (1 concurrent) | 439.1 | 1133 |
10 | Shell Scripts (8 concurrent) | 975.9 | 1082 |
11 | System Call Overhead | 132.1 | 503.3 |
12 | System Benchmarks Index Score | 288 | 763.9 |
CPUの状態
df = load_data("1/data.csv")
df.describe()
temp [℃] | clock [MHz] | voltage [V] | throttled | |
---|---|---|---|---|
count | 2879 | 2879 | 2879 | 2879 |
mean | 45.32 | 1717 | 0.9 | 0 |
std | 6.688 | 63.8 | 1.11e-16 | 0 |
min | 35.5 | 1200 | 0.9 | 0 |
25% | 38.9 | 1700 | 0.9 | 0 |
50% | 46.2 | 1750 | 0.9 | 0 |
75% | 52.1 | 1750 | 0.9 | 0 |
max | 58.4 | 1750 | 0.9 | 0 |
df.plot(subplots=True);
オーバークロック 2000 MHz
コンフィグ
arm_freq=2000 over_voltage=4
ベンチマーク結果
results.append(parse_benchmark_result("2/results/raspi-2021-12-31-01")) results[2]
name | 1 core | 4 core | |
---|---|---|---|
0 | Dhrystone 2 using register variables | 1725 | 6722 |
1 | Double-Precision Whetstone | 650.8 | 2545 |
2 | Execl Throughput | 128.1 | 414.2 |
3 | File Copy 1024 bufsize 2000 maxblocks | 303.1 | 586.8 |
4 | File Copy 256 bufsize 500 maxblocks | 205.2 | 388.4 |
5 | File Copy 4096 bufsize 8000 maxblocks | 563 | 907 |
6 | Pipe Throughput | 150.5 | 582.5 |
7 | Pipe-based Context Switching | 93.4 | 391.2 |
8 | Process Creation | 236.6 | 527.5 |
9 | Shell Scripts (1 concurrent) | 464 | 1227 |
10 | Shell Scripts (8 concurrent) | 1056 | 1170 |
11 | System Call Overhead | 150.7 | 576.8 |
12 | System Benchmarks Index Score | 321.8 | 851.8 |
CPUの状態
df = load_data("2/data.csv")
df.describe()
temp [℃] | clock [MHz] | voltage [V] | throttled | |
---|---|---|---|---|
count | 2898 | 2898 | 2898 | 2898 |
mean | 48.67 | 1953 | 0.95 | 0 |
std | 7.673 | 88.98 | 0 | 0 |
min | 34 | 1400 | 0.95 | 0 |
25% | 41.3 | 1900 | 0.95 | 0 |
50% | 49.1 | 2000 | 0.95 | 0 |
75% | 56.4 | 2000 | 0.95 | 0 |
max | 65.2 | 2001 | 0.95 | 0 |
df.plot(subplots=True);
オーバークロック 2000MHz (force turbo)
コンフィグ
over_voltage=4 arm_freq=2000 force_turbo=1
ベンチマーク結果
results.append(parse_benchmark_result("3/results/raspi-2022-01-02-01")) results[3]
name | 1 core | 4 core | |
---|---|---|---|
0 | Dhrystone 2 using register variables | 1725 | 6745 |
1 | Double-Precision Whetstone | 651 | 2550 |
2 | Execl Throughput | 159.8 | 493.6 |
3 | File Copy 1024 bufsize 2000 maxblocks | 304.8 | 582.3 |
4 | File Copy 256 bufsize 500 maxblocks | 204.2 | 387.6 |
5 | File Copy 4096 bufsize 8000 maxblocks | 568.7 | 907.2 |
6 | Pipe Throughput | 149.4 | 580.9 |
7 | Pipe-based Context Switching | 120.9 | 413.4 |
8 | Process Creation | 326.7 | 549.2 |
9 | Shell Scripts (1 concurrent) | 625 | 1321 |
10 | Shell Scripts (8 concurrent) | 1169 | 1262 |
11 | System Call Overhead | 150.4 | 575.9 |
12 | System Benchmarks Index Score | 355.8 | 881.5 |
CPUの状態
df = load_data("3/data.csv")
df.describe()
temp [℃] | clock [MHz] | voltage [V] | throttled | |
---|---|---|---|---|
count | 2945 | 2945 | 2945 | 2945 |
mean | 55.63 | 2000 | 0.95 | 0 |
std | 7.799 | 0.02204 | 0 | 0 |
min | 40.4 | 2000 | 0.95 | 0 |
25% | 48.2 | 2000 | 0.95 | 0 |
50% | 56.4 | 2000 | 0.95 | 0 |
75% | 63.3 | 2000 | 0.95 | 0 |
max | 72 | 2001 | 0.95 | 0 |
df.plot(subplots=True);
オーバークロック 2000MHz (force turbo + 温度計測なし)
コンフィグ
over_voltage=4 arm_freq=2000 force_turbo=1
ベンチマーク結果
results.append(parse_benchmark_result("4/results/raspi-2022-01-02-01")) results[4]
name | 1 core | 4 core | |
---|---|---|---|
0 | Dhrystone 2 using register variables | 1726 | 6898 |
1 | Double-Precision Whetstone | 651.2 | 2606 |
2 | Execl Throughput | 169.2 | 536.8 |
3 | File Copy 1024 bufsize 2000 maxblocks | 306.7 | 603.1 |
4 | File Copy 256 bufsize 500 maxblocks | 204.5 | 397.1 |
5 | File Copy 4096 bufsize 8000 maxblocks | 587.3 | 964.1 |
6 | Pipe Throughput | 150.9 | 606.5 |
7 | Pipe-based Context Switching | 123.5 | 429 |
8 | Process Creation | 354.5 | 598.5 |
9 | Shell Scripts (1 concurrent) | 653.5 | 1422 |
10 | Shell Scripts (8 concurrent) | 1252 | 1356 |
11 | System Call Overhead | 146.5 | 574.3 |
12 | System Benchmarks Index Score | 364.8 | 923.4 |
ベンチマーク結果比較
df = pd.DataFrame( [list(result["4 core"]) for result in results], columns=results[0]["name"], index=["1500MHz", "1750MHz", "2000MHz", "2000MHz(force turbo)", "2000MHz (performance)"] )
fig, axes = plt.subplots(len(df.columns), figsize=(9, 18)) fig.tight_layout(h_pad=2) df.iloc[::-1, :].plot.barh(ax=axes, subplots=True, legend=False, sharex=False);
考察
2000MHz, +0.1000Vでスコア850程度。
オーバークロック前と比べておよそ1.28倍の性能アップである。
throttledは発生していないので電圧はover_voltage=4
で十分だと思われる。
2.0GHzまで問題なくオーバークロックできることがわかったが、負荷がかかると最大温度65℃まで上昇している。
冬場でこれだと夏場は70℃を超えることが予想されるため、冷却機能を強化するかクロックを落とす必要があると考えられる。
force turboして温度計測をやめたところスコアは920まで伸びた。