目次: ベンチマーク
FizzBuzzの実装は簡単ですが、可能な限り高速に出力しようとするとなかなか面白い遊びになります。今回はあるCPUでうまくいっても、他のCPUでは効果がないケースをご紹介します。
実験用に4つのコードを用意しました。出力がボトルネックになって測定結果が不必要に遅く見えないよう、vmspliceとバッファリングは最初から実装します。
30個まとめて処理する最適化で速くなるのはほぼ確実でしょう。3つ目は、前回(2023年9月23日の日記参照)紹介したオフセット0xf6アルゴリズムです。これも速くなるのはほぼ確実でしょう。
4つ目は、前々回(2023年9月21日の日記参照)紹介した9桁と10桁を狙い撃ちで最適化する方法です。自前のitoa()には効果抜群でしたので、オフセット0xf6アルゴリズムとの相乗効果にも期待したいところです。
まずは省電力PC(CPU: Pentium J4205)で測定します。
# 20231001_fizzbuzz_base.c 33.3GiB 0:01:06 [ 512MiB/s] [ <=> ] real 1m6.621s user 1m4.461s sys 0m5.356s # 20231001_fizzbuzz_30.c 33.3GiB 0:00:38 [ 877MiB/s] [ <=> ] real 0m38.860s user 0m37.459s sys 0m4.377s # 20231001_fizzbuzz_offset.c 33.3GiB 0:00:09 [3.45GiB/s] [ <=> ] real 0m9.671s user 0m8.047s sys 0m3.726s # 20231001_fizzbuzz_fixed.c 33.3GiB 0:00:08 [3.74GiB/s] [ <=> ] real 0m8.906s user 0m6.955s sys 0m4.216s
いずれの最適化も効いていて、4つ目が最速です。良いですね。
次はデスクトップPC(CPU: Ryzen 7 5700X)で測定します。
# 20231001_fizzbuzz_base.c 33.3GiB 0:00:15 [2.11GiB/s] [ <=> ] real 0m15.759s user 0m15.425s sys 0m1.345s # 20231001_fizzbuzz_30.c 33.3GiB 0:00:09 [3.64GiB/s] [ <=> ] real 0m9.152s user 0m8.886s sys 0m1.176s # 20231001_fizzbuzz_offset.c 33.3GiB 0:00:02 [16.2GiB/s] [ <=> ] real 0m2.063s user 0m1.762s sys 0m1.070s # 20231001_fizzbuzz_fixed.c 33.3GiB 0:00:02 [15.8GiB/s] [ <=> ] real 0m2.112s user 0m1.802s sys 0m1.080s
なんと9桁と10桁狙い撃ちで最適化すると逆に遅くなりました。時間と高速化の度合いをまとめると、
FizzBuzzの種類 | Pentium J4205の実行時間 | 倍率 | Ryzen 7の実行時間 | 倍率 |
---|---|---|---|---|
自前itoa | 1m6.621s | - | 15.759s | - |
30個まとめる | 38.860s | x1.7 | 9.152s | x1.7 |
オフセット0xf6 | 9.671s | x6.8 | 2.063s | x7.6 |
9桁10桁狙い撃ち | 8.906s | x7.4 | 2.112s | x7.4 |
Ryzen 7 5700Xでなぜ遅くなるのか?は内部構造を知らないので何とも言えませんが、あるCPUに効く最適化が他のCPUだと効果がなかったり逆効果になったりすることは良くあります。
ソースコードはこちらからどうぞ。
< | 2023 | > | ||||
<< | < | 09 | > | >> | ||
日 | 月 | 火 | 水 | 木 | 金 | 土 |
- | - | - | - | - | 1 | 2 |
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
合計:
本日: