コンパイル(make)の高速化

BMW M3


最近、yum(rpm)やaptなどといったパッケージ管理の仕組みが秀逸で使いやすくなってきていますが、最新バージョンのプロダクトの検証がしたいときなど、ソースからビルドしてぶち込む事も個人的に多々あったりもします。


そんなビルド野郎な方に朗報です。


いやね、ちょっとしたものなら全然いいんですよ。
最近はマシンスペックもすっかり良くなっちゃって、時間もそれほどかからなくなってきているから。

でも、MySQLとかPHPとか、ちょっと大きいものを色々オプションつけてコンパイルしたりすると、時間がかかりはじめて、ちょっと馬鹿にならなくなってきます。


で、今日、makeのマニュアルを読んでたら、こんなオプション見つけました。

-j jobs
     同時に実行できるジョブ(コマンド)の数を指定する。 -j オプション が
     複 数 個指定された場合は、最後の指定が有効になる。引き数無しで -j
     オプションが与えられた場合、 make は同時に実行できるジョブの数 を
     制限しない。

うほっ。
つまり、複数のコマンドが並列で走るので、マルチプロセッサな環境だと、効果がありそうだ、と。
ということで、さっそくデュアルコアなマシンで試してみました。

前提

  • CPU
    • Xeon D5110 (1.60GHz, Dual Core) x 1
  • コンパイル対象
    • Subversion-1.4.5
    • Subversion-deps-1.4.5

-j オプション無し

とりあえず、オプションは何もつけずmakeした場合。

$ time make

real    3m34.201s
user    2m45.370s
sys     0m43.655s

-j オプション有り

  • j オプション付けて、ジョブ数を何パターンか指定してみるとこんな感じ。

あからさまに早くなっている。効果有り。


ジョブ数は、当たり前だけど、大きくすればいいってものではないようだ。
でも、コア数の2倍くらいまでは大きくした方が効果が高そう。


つか、劇的な改善です。オプション無しと比べても、かかる時間は半分以下です。

$ time make -j2

real    2m6.172s
user    2m47.322s
sys     0m41.725s
$ time make -j4

real    1m47.745s
user    2m47.670s
sys     0m41.633s
$ time make -j8

real    1m38.865s
user    2m37.026s
sys     0m30.688s
$ time make -j16

real    1m41.880s
user    2m37.345s
sys     0m33.006s


ジョブ数の指定無し(制限なし)だと↓こんな感じ。
制限無しは、やりすぎ感を伴う(ロードアベレージが上がりまくって、システムに影響を与える可能性がある)ので、-jオプションの後に、引数でコア数 x 1〜2あたりの数字を渡すようにしませう。

$ time make -j

real    1m40.562s
user    2m36.806s
sys     0m33.053s

結論

CPUリソースをフルに使ってもいい状況なら、makeは迷わず-jオプションを付けて実行しましょう!

$ make -j ${コア数 x 2くらい}

もうオプション無しには戻れません。

おまけ

  • l オプションでロードアベレージを見ながらジョブ数を制限しながら実行する事も出来るみたい。
-l load
     他のジョブが動作しており、ロードアベレージが少なくとも load (浮動
     小数)ならば、新しいジョブ(コマンド)を実行しないことを指定する。引
     き数無しの場合には、以前に指定した負荷の制限が取り除かれる。