RaspberryPiをオーバークロックしてベンチマーク

Raspberry PiオーバークロックしてUnix Benchmark取ってみた。

パフォーマンスはチューニングしたわけではなく、普段起動してあるサービスは起動したままターミナルを2つだけ開いてベンチマークを実行。 もう一つのターミナルではクロック速度と温度を監視するスクリプトを実行しておいた。

ベンチマーク環境

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, );

f:id:nnt339:20211231213355p:plain

オーバークロック 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);

f:id:nnt339:20211231213432p:plain

オーバークロック 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);

f:id:nnt339:20211231213506p:plain

オーバークロック 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);

f:id:nnt339:20220107142736p:plain

オーバークロック 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);

f:id:nnt339:20220107142658p:plain

考察

2000MHz, +0.1000Vでスコア850程度オーバークロック前と比べておよそ1.28倍の性能アップである。 throttledは発生していないので電圧はover_voltage=4で十分だと思われる。 2.0GHzまで問題なくオーバークロックできることがわかったが、負荷がかかると最大温度65℃まで上昇している。 冬場でこれだと夏場は70℃を超えることが予想されるため、冷却機能を強化するかクロックを落とす必要があると考えられる。

force turboして温度計測をやめたところスコアは920まで伸びた