何故 clang++ 編?

前記事で、clang でも結果変わらないって書いてあったじゃん?
→ 再度追試を行ったら違う結果が出てきました。ごめんなさい。
(恐らくコンパイルした後にリンクのコマンドを打つのを忘れていたものと思われる……。辛い)

また、こちらの記事の方が正確に検証しています。

先に本記事の結論を書いておきます。

本記事の結論

    • clang++ は -O3 でリンクアンローリングを行う(前記事からの修正 / 具体的には自分でコンパイルして調べて頂ければ)

 

    下記ベンチマーク環境においては、clang++ での出力結果は Rust の出力と比較して、統計的に有意(p < 0.01)に速い

ベンチマーク環境

コンパイラ on 環境その2

    • clang

8.0.0

Rustc

1.39.0-nightly

環境その2でコンパイルしたものを環境その1で流用しています。

環境その1

    • OS

Fedora 30

CPU

AMD A6-1450

Memory

DDR3-1333 4GB x 1 (4GB)

環境その2

    • OS

Fedora 30

CPU

Intel i7 4771

Memory

DDR3-1600 8GB x 2 (16GB)

測定条件

コンパイルコマンド

# libSolveRust.so は前回のものを流用するものとして、省略
# clang++ でのコンパイル
clang++ main.cpp -I/usr/include/c++/9/x86_64-redhat-linux/ -O3 -c -o main.o
# リンク
g++ main.o -L. -lSolveRust

このコンパイルオプションにてmain.cppのみ編集し、 Rust → C++ → C++ → Rustの順番で実行するバイナリ及び、 C++ → Rust → Rust → C++の順番で実行するバイナリの計2つを用意した。

実行回数

    • 環境その1ではRust → C++ → C++ → Rustのバイナリを20回実行した。(Rust, C++の各々で40サンプルずつ)

 

    環境その2では2つのバイナリを各々100回実行するのを2回行った。(Rust, C++の各々で800サンプルずつ)

計測結果

以下で貼られるグラフは、横軸が実行回数、縦軸がSolveの実行時間(ms)です。

環境その1

生アウトプットGenerating Problem…
SequentialNative, PreProcess, 46.536, Solve, 7435.52, PostProcess, 6.584
Rust, PreProcess, 43.817, Solve, 7459.02, PostProcess, 6.512
Rust, PreProcess, 43.7, Solve, 7469.44, PostProcess, 6.947
SequentialNative, PreProcess, 49.377, Solve, 7603.81, PostProcess, 5.76
Generating Problem…
SequentialNative, PreProcess, 43.793, Solve, 7432.91, PostProcess, 6.422
Rust, PreProcess, 42.819, Solve, 7471.99, PostProcess, 5.735
Rust, PreProcess, 43.535, Solve, 7475.79, PostProcess, 5.66
SequentialNative, PreProcess, 43.664, Solve, 7433.53, PostProcess, 5.713
Generating Problem…
SequentialNative, PreProcess, 41.582, Solve, 7430.47, PostProcess, 6.403
Rust, PreProcess, 43.698, Solve, 7471.96, PostProcess, 5.635
Rust, PreProcess, 43.163, Solve, 7462.47, PostProcess, 5.72
SequentialNative, PreProcess, 42.248, Solve, 7419.78, PostProcess, 5.25
Generating Problem…
SequentialNative, PreProcess, 43.649, Solve, 7421.57, PostProcess, 5.47
Rust, PreProcess, 41.425, Solve, 7475.46, PostProcess, 5.697
Rust, PreProcess, 41.874, Solve, 7469.53, PostProcess, 5.636
SequentialNative, PreProcess, 43.456, Solve, 7432.9, PostProcess, 5.651
Generating Problem…
SequentialNative, PreProcess, 44.004, Solve, 7443.77, PostProcess, 5.707
Rust, PreProcess, 42.41, Solve, 7467.45, PostProcess, 5.665
Rust, PreProcess, 43.423, Solve, 7471.64, PostProcess, 5.658
SequentialNative, PreProcess, 42.495, Solve, 7417.09, PostProcess, 5.378
Generating Problem…
SequentialNative, PreProcess, 43.938, Solve, 7415.61, PostProcess, 5.558
Rust, PreProcess, 42.728, Solve, 7459.35, PostProcess, 5.663
Rust, PreProcess, 41.35, Solve, 7465.66, PostProcess, 5.687
SequentialNative, PreProcess, 43.277, Solve, 7421, PostProcess, 5.445
Generating Problem…
SequentialNative, PreProcess, 41.57, Solve, 7407.09, PostProcess, 5.531
Rust, PreProcess, 42.595, Solve, 7451.06, PostProcess, 5.621
Rust, PreProcess, 43.365, Solve, 7458.52, PostProcess, 5.556
SequentialNative, PreProcess, 41.133, Solve, 7424.89, PostProcess, 5.367
Generating Problem…
SequentialNative, PreProcess, 43.564, Solve, 7441.41, PostProcess, 5.779
Rust, PreProcess, 41.476, Solve, 7471.34, PostProcess, 5.633
Rust, PreProcess, 41.266, Solve, 7462.76, PostProcess, 5.714
SequentialNative, PreProcess, 43.277, Solve, 7456.74, PostProcess, 5.464
Generating Problem…
SequentialNative, PreProcess, 43.55, Solve, 7419.47, PostProcess, 5.526
Rust, PreProcess, 41.23, Solve, 7489.61, PostProcess, 5.523
Rust, PreProcess, 42.019, Solve, 7467.35, PostProcess, 5.541
SequentialNative, PreProcess, 41.42, Solve, 7422.92, PostProcess, 5.624
Generating Problem…
SequentialNative, PreProcess, 41.751, Solve, 7440.62, PostProcess, 5.373
Rust, PreProcess, 42.39, Solve, 7474.82, PostProcess, 5.516
Rust, PreProcess, 41.008, Solve, 7465.9, PostProcess, 5.436
SequentialNative, PreProcess, 41.701, Solve, 7429.15, PostProcess, 5.501
Generating Problem…
SequentialNative, PreProcess, 44.135, Solve, 7416, PostProcess, 5.71
Rust, PreProcess, 43.874, Solve, 7477.67, PostProcess, 5.568
Rust, PreProcess, 42.902, Solve, 7476.97, PostProcess, 5.579
SequentialNative, PreProcess, 43.827, Solve, 7444.09, PostProcess, 5.682
Generating Problem…
SequentialNative, PreProcess, 41.671, Solve, 7450.28, PostProcess, 5.814
Rust, PreProcess, 41.627, Solve, 7472.48, PostProcess, 5.467
Rust, PreProcess, 43.53, Solve, 7467.89, PostProcess, 5.763
SequentialNative, PreProcess, 41.289, Solve, 7431.97, PostProcess, 5.555
Generating Problem…
SequentialNative, PreProcess, 41.948, Solve, 7422.41, PostProcess, 5.309
Rust, PreProcess, 43.945, Solve, 7472.94, PostProcess, 5.808
Rust, PreProcess, 43.039, Solve, 7464.25, PostProcess, 5.4
SequentialNative, PreProcess, 42.787, Solve, 7427.44, PostProcess, 5.594
Generating Problem…
SequentialNative, PreProcess, 43.292, Solve, 7428.2, PostProcess, 5.551
Rust, PreProcess, 41.181, Solve, 7465.17, PostProcess, 5.479
Rust, PreProcess, 41.408, Solve, 7464.66, PostProcess, 5.809
SequentialNative, PreProcess, 42.568, Solve, 7429.14, PostProcess, 5.548
Generating Problem…
SequentialNative, PreProcess, 43.786, Solve, 7427.12, PostProcess, 5.46
Rust, PreProcess, 43.255, Solve, 7462.49, PostProcess, 5.565
Rust, PreProcess, 46.043, Solve, 7472.55, PostProcess, 5.524
SequentialNative, PreProcess, 42.449, Solve, 7441.32, PostProcess, 5.633
Generating Problem…
SequentialNative, PreProcess, 43.566, Solve, 7418.71, PostProcess, 5.55
Rust, PreProcess, 42.665, Solve, 7456.97, PostProcess, 5.627
Rust, PreProcess, 42.722, Solve, 7465.98, PostProcess, 5.671
SequentialNative, PreProcess, 43.447, Solve, 7423.07, PostProcess, 5.568
Generating Problem…
SequentialNative, PreProcess, 42.095, Solve, 7423.1, PostProcess, 5.58
Rust, PreProcess, 41.659, Solve, 7466.42, PostProcess, 5.654
Rust, PreProcess, 41.801, Solve, 7455.87, PostProcess, 5.612
SequentialNative, PreProcess, 43.358, Solve, 7410.63, PostProcess, 5.559
Generating Problem…
SequentialNative, PreProcess, 42.212, Solve, 7428.34, PostProcess, 5.506
Rust, PreProcess, 42.701, Solve, 7478.29, PostProcess, 5.496
Rust, PreProcess, 43.163, Solve, 7483.22, PostProcess, 5.577
SequentialNative, PreProcess, 42.366, Solve, 7445.22, PostProcess, 5.581
Generating Problem…
SequentialNative, PreProcess, 43.629, Solve, 7451.63, PostProcess, 5.63
Rust, PreProcess, 42.068, Solve, 7480.78, PostProcess, 5.635
Rust, PreProcess, 42.279, Solve, 7492.77, PostProcess, 5.615
SequentialNative, PreProcess, 41.138, Solve, 7432.22, PostProcess, 5.757
Generating Problem…
SequentialNative, PreProcess, 43.525, Solve, 7427.78, PostProcess, 5.664
Rust, PreProcess, 42.975, Solve, 7462.58, PostProcess, 5.613
Rust, PreProcess, 42.951, Solve, 7467.68, PostProcess, 5.495
SequentialNative, PreProcess, 44.966, Solve, 7422.13, PostProcess, 5.551

img1.png

t-検定

    Welch Two Sample t-test

data:  cpp and rust
t = -7.2259, df = 45.615, p-value = 4.377e-09
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -45.3178 -25.5672
sample estimates:
mean of x mean of y 
 7433.776  7469.219 

環境その2

(生アウトプットはでかすぎるので省略)

img2.png
    • 200回ごとに切れ切れに計測しているので、その間にCPU温度が下がり周期的に時間が短くなっている場所がある。

これは弊環境の空冷が貧弱なためである

400回目までが、Rust → C++ → C++ → Rust の順番での計測、それ以降が C++ → Rust → Rust → C++ である。

t-検定

    Welch Two Sample t-test

data:  cpp and rust
t = -3.2078, df = 1596.6, p-value = 0.001364
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -63.32819 -15.26924
sample estimates:
mean of x mean of y 
 2491.068  2530.366 

結論

Rust より C++ の方が速い ?

感想

言語間の速度の比較は話題になるものの、実装者の腕やらコンパイラの最適化の差やらで厳密に定義することは本当に難しいなぁと思いました。
また、実行するCPUによってもレジスタリネーミングの強さやら、分岐予測の強さやら、命令のレイテンシー・スループットの違いなどなど、パラメーターが多すぎるのでこの結果が他のCPUでも同じとは到底言えません。
本結果は、あくまでも私の使える環境について結果を述べた似すぎず、かつコンパイラも上記バージョンのみしか使って居ないことはご了承ください。
とは言え、LLVM を使うような言語では、誤差は数%の差に過ぎないので、殆どのケースでは気にしなくてよいのではと思います。

image.png
广告
将在 10 秒后关闭
bannerAds