組み込みProgrammerのチラシの裏

Make vs Ninja

| Comments

cmakeの出力でmakeとninjaのビルド速度をベンチマーク。 測定対象は、cmakeのmasterを使った。

概要

以下の4種類についてcmakeから生成、ビルド実行についての実行速度を/usr/bin/timeを使って計測した。

  • make(-j1)
  • make(-j4)
  • make(-j8)
  • ninja

make(-j1)は一回の試行時間が長いため3回のみ計測したが、それ以外については10回づつ計測している。

測定環境

項目 内容
PC Mac book air
core 4

ベンチマーク結果

ビルド時間の単位は秒。

summary

real時間を比較すると、make(-jなし)が圧倒的に遅いことが分かる。 ninjaは並列ビルドを行なっており、make(-jなし)は逐次ビルドしている。 そのため、ninjaとmake(-jなし)と比較すると圧倒的な差が出ることは自明である。 ここからは当然遅いmake(-jなし)を除き、make(-j4), make(-j8), ninjaで比較していく。

まずは、cmakeでmake生成時・およびninja生成時の比較から始める。

summary

cmakeでmakeを生成した時よりも、cmakeでninjaを生成した方が10%程度ビルド速度が速いことが分かる。 ビルド前から差が出ていることは意外だった。

次に、make(-j4), make(-j8), ninja実行時間を比較していく。

summary

  • coreが4なので、make(-j4)だと少しバラつきが出ている
  • user時間の中央値は大差ないが、real時間の中央値は差が出ている

さらにreal時間のみに絞って比較する

summary

  • make(-j8)とninjaを比較すると、ninjaの方が10%弱速い

導出過程

箱ヒゲ図用のデータを収集するために、result.csvに追記するスクリプト。 append_csv.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/bin/bash -x

function logTime() {
    local cmd="${1}"
    local title="${2}"
    local tmpFile=`mktemp`
    local resultFile=../result.csv
    ( /usr/bin/time ${cmd} ) 2>&1 | tee ${tmpFile}
    if [ ${PIPESTATUS[0]} != 0 ]; then
        rm ${tmpFile}
        return 1
    fi
    echo -n "${title}" >> ${resultFile}
    cat ${tmpFile} | tail -1 >> ${resultFile}
    rm ${tmpFile}
    return 0
}

mkdir build
cd build
logTime "cmake .. -GNinja" "cmake(ninja)" || exit 1
logTime "ninja"            "ninja"        || exit 1
cd ..
rm -rf build

これをループするためにzshから以下を実行した。

1
repeat 10 { ./append_csv.sh }

実行結果のresult.csvの一部は以下のような形式となる。

1
2
3
4
cmake(ninja)       67.41 real        31.48 user        26.36 sys
ninja      407.00 real      1333.92 user       105.21 sys
cmake(ninja)       71.14 real        34.97 user        27.37 sys
ninja      372.25 real      1264.98 user        98.53 sys

あとはresult.csvから箱ヒゲ図を生成するgnuplotスクリプトを作っていく。

summary

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#!/usr/bin/env gnuplot

set terminal png
set output "out.png"

set yrange [0:1800]

$D1 << EOD
make(-j1)       1653.39 real        0 user        0 sys
make(-j1)       1533.39 real        0 user        0 sys
make(-j1)       1713.39 real        0 user        0 sys
cmake(-j4)       82.62 real        40.09 user        32.77 sys
make(-j4)      471.78 real      1359.54 user       125.65 sys
cmake(-j4)       79.74 real        39.37 user        31.63 sys
make(-j4)      445.16 real      1379.10 user       122.69 sys
cmake(-j4)       84.49 real        42.28 user        33.08 sys
make(-j4)      463.21 real      1326.14 user       121.92 sys
cmake(-j4)       86.74 real        43.49 user        33.68 sys
make(-j4)      411.99 real      1302.73 user       114.85 sys
cmake(-j4)       80.82 real        40.95 user        31.65 sys
cmake(-j4)       82.77 real        41.43 user        32.84 sys
make(-j4)      456.09 real      1410.56 user       126.05 sys
cmake(-j4)       95.46 real        45.73 user        35.60 sys
make(-j4)      417.48 real      1315.46 user       117.54 sys
cmake(-j4)       80.22 real        40.55 user        30.92 sys
make(-j4)      378.31 real      1259.26 user       109.45 sys
cmake(-j4)       79.51 real        40.14 user        30.77 sys
make(-j4)      377.63 real      1259.19 user       109.61 sys
cmake(-j4)       79.60 real        40.50 user        30.85 sys
make(-j4)      374.87 real      1250.27 user       108.38 sys
cmake(-j4)       78.79 real        39.88 user        30.50 sys
make(-j4)      370.85 real      1243.24 user       107.75 sys
cmake(-j8)       79.24 real        38.92 user        31.49 sys
make(-j8)      448.00 real      1377.00 user       122.53 sys
cmake(-j8)       82.95 real        41.77 user        32.68 sys
make(-j8)      387.72 real      1266.12 user       112.39 sys
cmake(-j8)       78.88 real        40.18 user        30.42 sys
make(-j8)      382.24 real      1247.82 user       109.16 sys
cmake(-j8)       78.51 real        40.16 user        30.06 sys
make(-j8)      376.21 real      1245.88 user       108.02 sys
cmake(-j8)       77.25 real        39.34 user        29.81 sys
make(-j8)      378.14 real      1248.86 user       109.25 sys
cmake(-j8)       77.51 real        39.53 user        29.86 sys
make(-j8)      399.68 real      1270.69 user       111.52 sys
cmake(-j8)       79.35 real        40.56 user        30.69 sys
make(-j8)      401.73 real      1280.87 user       112.17 sys
cmake(-j8)       78.44 real        39.88 user        30.23 sys
make(-j8)      377.49 real      1249.86 user       109.39 sys
cmake(-j8)       78.10 real        39.77 user        30.34 sys
make(-j8)      376.54 real      1248.50 user       108.94 sys
cmake(-j8)       77.88 real        39.60 user        30.11 sys
make(-j8)      374.71 real      1246.47 user       108.77 sys
cmake(ninja)       67.41 real        31.48 user        26.36 sys
ninja      407.00 real      1333.92 user       105.21 sys
cmake(ninja)       71.14 real        34.97 user        27.37 sys
ninja      372.25 real      1264.98 user        98.53 sys
cmake(ninja)       65.13 real        32.14 user        24.52 sys
ninja      355.09 real      1238.72 user        94.72 sys
cmake(ninja)       66.40 real        32.85 user        24.93 sys
ninja      353.47 real      1241.70 user        94.16 sys
cmake(ninja)       64.26 real        31.95 user        24.08 sys
ninja      354.85 real      1240.93 user        93.86 sys
cmake(ninja)       64.79 real        31.57 user        24.74 sys
ninja      378.97 real      1267.42 user        95.66 sys
cmake(ninja)       68.54 real        33.86 user        25.95 sys
ninja      367.68 real      1251.11 user        97.50 sys
cmake(ninja)       65.66 real        32.35 user        24.69 sys
ninja      349.18 real      1226.34 user        93.21 sys
cmake(ninja)       64.49 real        31.93 user        24.30 sys
ninja      349.54 real      1228.71 user        93.52 sys
cmake(ninja)       63.70 real        31.82 user        24.07 sys
ninja      350.60 real      1233.30 user        93.76 sys
EOD

plot \
  $D1 using (1.0):2:(0):1 with boxplot title "real", \
  $D1 using (1.0):4:(0):1 with boxplot title "user", \
  $D1 using (1.0):6:(0):1 with boxplot title "sys"

cmake make vs cmake ninja

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
31
32
33
34
#!/usr/bin/env gnuplot

set terminal png
set output "out.png"

set yrange [0:100]

$D1 << EOD
cmake(-j8)       79.24 real        38.92 user        31.49 sys
cmake(-j8)       82.95 real        41.77 user        32.68 sys
cmake(-j8)       78.88 real        40.18 user        30.42 sys
cmake(-j8)       78.51 real        40.16 user        30.06 sys
cmake(-j8)       77.25 real        39.34 user        29.81 sys
cmake(-j8)       77.51 real        39.53 user        29.86 sys
cmake(-j8)       79.35 real        40.56 user        30.69 sys
cmake(-j8)       78.44 real        39.88 user        30.23 sys
cmake(-j8)       78.10 real        39.77 user        30.34 sys
cmake(-j8)       77.88 real        39.60 user        30.11 sys
cmake(ninja)       67.41 real        31.48 user        26.36 sys
cmake(ninja)       71.14 real        34.97 user        27.37 sys
cmake(ninja)       65.13 real        32.14 user        24.52 sys
cmake(ninja)       66.40 real        32.85 user        24.93 sys
cmake(ninja)       64.26 real        31.95 user        24.08 sys
cmake(ninja)       64.79 real        31.57 user        24.74 sys
cmake(ninja)       68.54 real        33.86 user        25.95 sys
cmake(ninja)       65.66 real        32.35 user        24.69 sys
cmake(ninja)       64.49 real        31.93 user        24.30 sys
cmake(ninja)       63.70 real        31.82 user        24.07 sys
EOD

plot \
  $D1 using (1.0):2:(0):1 with boxplot title "real", \
  $D1 using (1.0):4:(0):1 with boxplot title "user", \
  $D1 using (1.0):6:(0):1 with boxplot title "sys"

cmake make vs cmake ninja

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#!/usr/bin/env gnuplot

set terminal png
set output "out.png"

set yrange [0:500]

$D1 << EOD
make(-j4)      471.78 real      1359.54 user       125.65 sys
make(-j4)      445.16 real      1379.10 user       122.69 sys
make(-j4)      463.21 real      1326.14 user       121.92 sys
make(-j4)      411.99 real      1302.73 user       114.85 sys
make(-j4)      456.09 real      1410.56 user       126.05 sys
make(-j4)      417.48 real      1315.46 user       117.54 sys
make(-j4)      378.31 real      1259.26 user       109.45 sys
make(-j4)      377.63 real      1259.19 user       109.61 sys
make(-j4)      374.87 real      1250.27 user       108.38 sys
make(-j4)      370.85 real      1243.24 user       107.75 sys
make(-j8)      448.00 real      1377.00 user       122.53 sys
make(-j8)      387.72 real      1266.12 user       112.39 sys
make(-j8)      382.24 real      1247.82 user       109.16 sys
make(-j8)      376.21 real      1245.88 user       108.02 sys
make(-j8)      378.14 real      1248.86 user       109.25 sys
make(-j8)      399.68 real      1270.69 user       111.52 sys
make(-j8)      401.73 real      1280.87 user       112.17 sys
make(-j8)      377.49 real      1249.86 user       109.39 sys
make(-j8)      376.54 real      1248.50 user       108.94 sys
make(-j8)      374.71 real      1246.47 user       108.77 sys
ninja      407.00 real      1333.92 user       105.21 sys
ninja      372.25 real      1264.98 user        98.53 sys
ninja      355.09 real      1238.72 user        94.72 sys
ninja      353.47 real      1241.70 user        94.16 sys
ninja      354.85 real      1240.93 user        93.86 sys
ninja      378.97 real      1267.42 user        95.66 sys
ninja      367.68 real      1251.11 user        97.50 sys
ninja      349.18 real      1226.34 user        93.21 sys
ninja      349.54 real      1228.71 user        93.52 sys
ninja      350.60 real      1233.30 user        93.76 sys
EOD

plot \
  $D1 using (1.0):2:(0):1 with boxplot title "real", \
  $D1 using (1.0):4:(0):1 with boxplot title "user", \
  $D1 using (1.0):6:(0):1 with boxplot title "sys"

Comments