DNA Cafe | Download | FreeSoftware | Java | Links
distcc は分散コンパイラであり C, C++, Objective C や Objective C++ のコードをネットワーク上のマシンを通じて構築できる。 distcc はローカルマシン上でコンパイルするのと同等な結果を得ることができ、 導入したり使ったりするのが簡単で、 しばしばローカルマシン上で同じことをするよりもずっと速い。
distcc はそれぞれ前処理したソースコードと引数をネットワークを通じて送る。 そのため、ファイルシステムやヘッダーファイル、 あるいはライブラリを共有する必要はなく、 同じプラットフォームである必要もない。 ただしコンパイラの名前は合わせる必要がある。
環境変数にサーバの名前を設定する。
$ DISTCC_HOSTS="host_to_use_for_compilation ..."
$ export DISTCC_HOSTS
名前は速い順に並べる。これは distcc が先に来たものを先に使うため。 サーバ名に localhost を指定すると distcc は直接コンパイラを使うので、 ネットワーク経由にしたい場合は 127.0.0.1 を指定する。
次に目的のコードを構築する。
$ make -j8 CC=distcc
make に指定する同時ジョブの数(-j の引数)は、 同時実行しても遅くならない数値、だいたい全 CPU 数の二倍以下、を指定する。 大きくし過ぎると、スピードは改善しないが、待ちプロセスが増えてサーバ側のリソースを消費する。
例えば、クライアントが一台、サーバが三台あり、それぞれに CPU が一個ついている場合には、 -j8 か、それ以下を指定するとよい。
distcc 3.0 から pump モードが追加された。 pump モードを使うにはサーバ名を DISTCC_POTENTIAL_HOSTS で指定し、 構築時に pump コマンドを使う。
$ DISTCC_POTENTIAL_HOSTS="host_to_use_for_compilation ..."
$ export DISTCC_POTENTIAL_HOSTS
$ eval `pump --startup`
$ make -j8 CC=distcc
$ pump --shutdown
pump の起動と終了はもっと簡単にできる。以下のコマンドは上と同等である。
$ DISTCC_POTENTIAL_HOSTS="host_to_use_for_compilation ..."
$ export DISTCC_POTENTIAL_HOSTS
$ pump make -j8 CC=distcc
distcc を ccache と組み合わせることで効率を上げることができる。 ただし ccache と pump モードを同時に使ってはいけない。 使い方については ccache のメモ (ccache_ja.html) を参照すること。
pump モードではプリプロセッサの処理をサーバ側で行なう。
この内容はコマンド ccache で行なわれる処理と重複する部分が多く、二つを併用した場合、 pump モードでの処理が無駄になる。
では pump モードと ccache のどちらを使うべきだろうか?
distcc だけで使う場合、 distcc pump モードおよび distcc と ccache を組み合わせた場合とを比較すると以下の表になる。
組み合わせ | プリプロセス | コンパイル | リンク | 利点 |
---|---|---|---|---|
distcc | ローカル上 | サーバ上 | ローカル上 | |
distcc pump | サーバ上 | サーバ上 | ローカル上 | プリプロセスも分散処理できる |
distcc + ccache | ローカル上 | サーバ上またはキャッシュ | ローカル上 | ローカル上でキャッシュを共有できる |
比較のため単純なモデルを考える。 プリプロセスにかかるを時間 tcpp, コンパイルにかかるを時間 tcc1, リンクにかかる時間を tld, キャッシュのヒット率を h (0 ≤ h ≤ 1), 並行コンパイル数を n (n ≥ 1) とすれば、かかる時間を以下のように表せる。
tdistcc ∼ tcpp + tcc1/n + tld
tpump ∼ (tcpp + tcc1)/n + tld
tccache ∼ tcpp + (1-h) tcc1/n + tld
ccache と distcc pump mode のパフォーマンス.
ccache の場合、コンパイルにかかる時間は tccache(h=0;n) と tccache(h=1;n)
の間であるのに対して、
pump モードの場合はコンパイルにかかる時間が並列コンパイル数に反比例し、
ある時点で ccache でキャッシュが全部ヒットする場合の時間と逆転する。
条件によるが、サーバ数が多い場合には pump モードが、
サーバが 1-3 台の場合は ccache の方が有利と考えられる。
サーバ側では distccd を使う。 ここでは inetd 経由または独立したサーバとして設定する方法をしめす。 他にもいくつか方法があるので詳しいことは一次配布先を参照すること。
distccd は独立したサーバとして設定することをお進めする。 サーバ側ではクライアント側から送られるファイルをコンパイルするが、 inetd 経由だと起動するのに余分なコストがかかるからである。
distcc を走らせる推奨方法である。 distcc を独立したサービスとして走らせるには、以下のコマンドを使用する。 ユーザは root もしくは普通のユーザで良い。
$ distccd --daemon
伝統的な Unix の inetd では、サーバ側でポートの接続要求を受けた時に distcc コマンドを走らせる設定が必要となる。
以下のそれぞれファイルに行を追加する(既にないか調べること)。
distcc 3632/tcp #distributed C/C++ compiler server
distcc stream tcp nowait root /usr/bin/distccd distccd --verbose --inetd --user nobody --nice 20
distcc: LOCAL
RedHat などで xinetd を使っている場合は inetd.conf の代わりに、 以下のファイルを作成する。
それから設定ファイルを読み込ませるため inetd へ SIGHUP シグナルを送る。