Androidのdistccベースの分散コンパイルと負荷分散の実現

29017 ワード

distccの概要
distcc
distccは、有名なオープンソースプロジェクトsambaから始まり、プラットフォーム間で長い歴史を持つオープンソース分散コンパイルソリューションです.
ほとんどのc言語とその派生言語では、コンパイルプロセスは主に3つのステップに分けられます.
プリコンパイルコンパイルリンクdistccの役割は、第2ステップのコンパイル(3.0バージョン後にpumpで第1ステップの一部をサポート)プロセスをグリッド計算モードで採用し、コンパイルタスクを他のホストに割り当て、コンパイル終了後に第3ステップのリンクで使用するために返信することです.これにより、コンパイルを開始する機器の負荷が低減され、コンパイル効率が向上する.
distcc自体は実際にはコンパイルプロセスに関与せず,コンパイラ(gccなど)のフロントエンドにすぎない.コンパイラに分散プロパティを追加し、一部の管理と簡単な負荷分散機能に参加します.公式によると、その性能向上の限界閾値は3倍の速度であり、すなわちコンパイルプールの拡大によって、元のコンパイル速度の3分の1に無限に近いが達成できない.
これまでdistccはc言語とその派生c+,Objective-cなどのコンパイルのみをサポートしてきた.Javaの分散コンパイルをサポートできません.
pump
distccバージョン3.0からpythonベースの新しいツールpumpが追加されました.ヘッダファイルもソースコードとともにコンパイルサーバに送信する機能です.一部のプリコンパイル作業も分散処理を行う.これにより、コンパイル効率がさらに向上します.公式に与えられた数字は、ファイルの転送、コンパイルプロセスの10倍の効率を向上させることです.
しかし、pumpモードの限界は、コンパイル中にソースコード(特にヘッダファイル)を変更できないことです.そうしないと、誤ったコンパイル結果が発生します.
ccache
ccacheはsambaプロジェクトでも発生し、コンパイル中の中間ファイルを事前コンパイル結果に基づいてhashテーブルインデックスでキャッシュする役割を果たす.Ccacheには次の機能があります.
 
ヒット/欠落は静的自動キャッシュサイズ管理生成されたコンパイル警告をキャッシュできる.
容易取り付け非常に低いコストハードコネクタを使用して、distccとは異なるレプリケーションを回避できます.ccacheはandroid公式に直接サポートされているコンパイル加速スキームです.dmucs
dmucsはdistccサービスのための分散負荷等化ソリューションである.元のdistccは、サーバが指定した順序に基づいてのみコンパイルタスクを割り当て、コンパイルプール内のサーバの負荷状況に基づいて動的なコンパイルタスク割り当てを行うことはできません.dmucsは、コンパイルプール内のホストの負荷状況をdmucsサービスホストに通知します.負荷およびコンパイラの負担能力に基づいて、コンパイルタスクを動的に割り当てます.
 
基準試験結果及び分析
構築結果分析
図1は、異なるコンパイル条件下でのコンパイル時間を示す.このうち,単機のコンパイルパラメータには−j 8が用いられ,両機,三機のコンパイルパラメータはそれぞれ−j 12,−j 15である.
 
この図から、以下の結論を大まかにまとめることができる.
distccはandroidシステムのコンパイルに顕著な加速作用を果たし,コンパイル時間はコンパイルプールにおけるコンパイルマシン数の増加に伴ってほぼ線形に低下する傾向にある.しばらくはより多くのホストをテストできないためです.だから境界状況を知ることができません.分散コンパイルの効果はandroid 4.0のコンパイル中に2.3より顕著に現れた.pumpツールがコンパイル中に果たす速度向上の役割は明らかではありません.androidのプリコンパイルプロセスは大量のヘッダファイルと依存関係に関連しているため,分布式で得られた速度向上はファイル転送プロセスによって相殺されると推定される.ccacheの追加はコンパイル時間を大幅に改善した.ccacheの使用ヒット率は、2.3.7プラットフォームに対して、統計結果は以下の通りである:
cache hit 878
cache miss 11494
called for link 691
not a C/C++ file 307
unsupported compiler option 48
files in cache 22988
cache size 1.0 Gbytes
max cache size 20.0 Gbytes
ccache初回コンパイル2.3.7統計結果
cache hit 12127
cache miss 16
called for link 691
not a C/C++ file 307
unsupported compiler option 48
files in cache 23020
cache size 1.0 Gbytes
max cache size 20.0 Gbytes
ccache二次コンパイル2.3.7統計結果から、二次コンパイル時(コードは変更されていない)、cacheのヒット率は90%を超えた.これにより速度も大幅に向上し,初期速度の3倍にほぼ近づいた.Android 4.0バージョンの速度向上は特に顕著である.しかし、このデータは普段の開発過程でコードが変化した場合に参考になるだけです.テスト中、dmucsの追加は、単一コンパイル要求の時間を時間的に効率的に短縮しなかった.なぜならjava/cのハイブリッドコンパイルではdistccの推奨方法に従ってコンパイルjobの数を増やすことができず,分散コンパイルの均衡の優位性を十分に体現できないからである.しかし,コンパイル時の観察によれば,dmucsはコンパイルプールにおけるコンパイルマシンの負荷を効率的に制御し,コンパイル能力に基づいて平均的に割り当てることができる.また、グラフでは、コンパイルを開始したクライアントの平均負荷は、分散コンパイルを採用した後、cクラス言語のコンパイル段階で、いずれも大幅に低下したという結果が得られなかった. 
図2は、android 4.0コードを3機分布条件下でコンパイルし、job数とコンパイル時間との大まかな関係を示す.
このことから,job数を単純に増やすだけではより良いコンパイル時間を得ることはできないことが分かる.具体的な原因は下記の通りです.
存在する問題と後続の解決策の方向
Androidシステムのコンパイル中にjavaのコンパイルとcのコンパイルが同時に存在するため、distccはcクラス言語の分散コンパイルのみをサポートする.従ってandroidの分散コンパイルで得られた効果は,通常の純粋なcクラス言語プロジェクトほど顕著ではない.jobs数の増加に伴い,本機でのみ処理できるjavaコンパイルプロセスは,逆に機械ハードウェア機能の制限により全体のコンパイル速度を遅らせ,distcc分散コンパイルによって得られる利点を相殺した.
この問題を解決するために、以下のいくつかの面から着手し、さらなる改造を行うことができる.
cクラス言語を分割するコンパイルプロセス:全体androidコンパイルプロセスをc言語を主とjavaを主とする2つのプロセスに分け、その中でc言語のコンパイルプロセスはdistccコンパイルを採用し、java言語のコンパイルは元のコンパイル方式に従う.この方法はandroidコンパイルスクリプトの修正に関し,比較的簡単に実現できる.makeの実装を変更し、java/cコンパイラを呼び出すことによってジョブ数を動的に調整します.この変更は、コンパイルスクリプトの変更、makeソースコードの変更に関連する可能性があります.実装は少し複雑です.Javaコンパイルプロセスも同様に分散処理を行います.可能な方法は、異なるjavaプロジェクトを異なるホスト上でコンパイルすることです.ただし、物理的な共有ストレージとコンパイルスクリプトの変更が必要です.より複雑な実装.しかし、まだ実行可能な範囲内です.分散負荷等化コンパイル環境導入i
分散コンパイルをサポートするには、単一コンパイルホストで次の配置手順を実行する必要があります.
インストールサポートパッケージ:コンパイルホストはdistcc、distcc-pump、dmucsパッケージをインストールする必要があります
1
apt-get install distcc distcc-pump dumcs

クロスコンパイルツールチェーンの特定の場所への配備:androidソースコードに付属するprebuiltディレクトリを/opt/などの固定場所にコピーします.distccのプロファイルの変更:/etc/default/distccを変更し、STARTDISTCCをtrueに設定します.ALLOWEDNETSは接続するクライアント範囲であり、必要に応じて設定する.LISTENERはリスニングアドレスであり、自機ipアドレスに設定される.JOBは、同時に負担できるコンパイルジョブ数であり、CPU個数+2に設定されるのが一般的である.変更/etc/init.d/distccは、PATHパラメータをステップ2のクロスコンパイルツールチェーンコンパイラの位置に加えて、distccがコンパイルタスクを受け取ると、対応するコンパイラを見つけることができるようにする.distccサービスの開始:sudoサービスdistcc start  
コンパイル要求を発行するクライアントには、次の配置手順が必要です.
 
クロスコンパイルツールからdistccへのリンクの作成:クロスコンパイルツールをすべてdistccにリンクする:
cd /usr/lib/distcc
ln -s ../../bin/distcc arm-eabi-addr2line
ln -s ../../bin/distcc arm-eabi-ar
ln -s ../../bin/distcc arm-eabi-as
ln -s ../../bin/distcc arm-eabi-c++
ln -s ../../bin/distcc arm-eabi-c++filt
ln -s ../../bin/distcc arm-eabi-cpp
……
Androidコンパイルスクリプトを修正し、distccコンパイルをサポートします:build/core/combo/TARGET_linux-arm.mkの中のTARGET_TOOLS_PREFIX変数を/usr/lib/distcc/arm-eabi-build/core/definitionに変更します.mk、transform-d-to-pを変更するには:
define transform-d-to-p
$(hide) if [ -e $(@:%.o=%.d) ];then cp $(@:%.o=%.d) $(@:%.o=%.P); \
	sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
		-e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \
	rm -f $(@:%.o=%.d);else cp $(notdir $(@:%.o=%.d)) $(@:%.o=%.P); \
	sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
		-e '/^$$/ d' -e 's/$$/ :/' < $(notdir $(@:%.o=%.d)) >> $(@:%.o=%.P); \
	rm -f $(notdir $(@:%.o=%.d));fi
endef
環境変数の変更:PATHを変更し、distccコンパイラパスをPATHの最初のパスに追加し、クロスコンパイラパスを追加します:export PATH=/usr/lib/distcc:$PATHこのコマンドはprofileに書き込むことができます.DISTCC_の変更HOSTS、分散コンパイルをサポートするホストアドレスを示す:export DISTCC_HOSTS=’localhost … … ‘ コンパイルプロセスの開始:make-j 8 CC=distccコンパイルプールホスト数とネイティブリソースの状況に応じてjob数を調整し、最適なパフォーマンスを得る.ccacheとの併用
android政府は、構築環境にccacheサポートを追加しているため、コンパイル効率を向上させるためにccache機能を簡単に開くことができます.具体的な方法は次のとおりです.
$ export USE_CCACHE=1
$ export CCACHE_DIR=/path_of_your_choice/.ccache
$ prebuilt/linux-x86/ccache/ccache -M 20G
このうち,20 Gは推奨値であり,実際にはコンパイルマシンの具体的な状況に応じて調整できる.
コンパイル期間またはコンパイルが終了したら、「ccache-s」コマンドを使用してキャッシュヒットを表示できます.
dmucsによる負荷等化
dmucsサーバとしてホストを選択します.設定:
/etc/default/dmucsを変更し、dmucsを有効にする:SERVERをyes に変更する
変更/etc/dmucs.confファイル、コンパイルプールの構成:ファイルの元の説明フォーマットに基づいて、コンパイルプールのホストに追加します.dmucsサービスの開始:service start dmucs 各コンパイルホスト上で負荷パブリケーションクライアントを実行する:loadavg-sホストアドレス&この場合、コンパイルを開始するときに使用できます.
make -j8 CC=gethost distcc
を使用して、負荷分散をサポートする分散コンパイルプロセスを有効にします.
 
FAQ
pumpタイムズpythonエラーを実行する既知のバグです.解決方法はhttps://bugs.launchpad.net/distcc/+bug/511585 コンパイル時pumpレポートホストはcppをサポートしていません.環境変数の作成時にホストがサポートするコンパイルタイプを指定する必要があります.たとえば、export DISTCC_HOSTS=’localhost compilehost,lzo,cpp’ 参考文献
distcc公式サイト:http://code.google.com/p/distcc/distcc公式ドキュメント:http://distcc.googlecode.com/svn/trunk/doc/web/index.html 「分散コンパイル環境での負荷分散」:http://www.ibm.com/developerworks/cn/aix/library/0905_yangyi_distcc/index.html dmucs公式サイト:http://dmucs.sourceforge.net