コミットごとに、ビルドボットで2つのC++プロジェクトをコンパイルしています。どちらも約1000ファイルで、1つは100 kloc、もう1つは170 klocです。コンパイル時間は、gcc(4.4)とVisual C++(2008)で大きく異なります。
1つのプロジェクトのVisual C++コンパイルには20分かかります。プロジェクトは互いに依存しているため、複数のコアを利用することはできません。結局、デバッグとリリースの両方のプロジェクトを32ビットと64ビットで完全にコンパイルするには、2時間半以上かかります。
1つのプロジェクトのgccコンパイルには4分かかります。 4つのコアで並列化でき、約1分10秒かかります。 2つのプロジェクトの4つのバージョン(デバッグ/リリース、32/64ビット)用の8つのビルドはすべて、10分未満でコンパイルされます。
Visual C++のコンパイル時間はどうなっていますか?彼らは基本的に5倍遅いです。
C++ klocのコンパイルに予想される平均時間はどれくらいですか?私の場合、vc ++では7 s/kloc、gccでは1.4 s/klocです。
Visual C++でコンパイル時間を短縮するために何かできることはありますか?
VC++コンパイラーを遅くする1つのことは、重要でないconst
値型の具象インスタンスを初期化するヘッダーファイルがある場合です。これは、std::string
タイプの定数またはGUIDで発生する場合があります。コンパイル時間とリンク時間の両方に影響します。
単一のDLLの場合、これにより10倍の速度低下が発生しました。それらをプリコンパイル済みヘッダーファイルに入れるか、ヘッダーで宣言してcppファイルで初期化するだけで役立ちます。
ウイルススキャナーを調べてください。VC++が最適な状態で表示されない場合は、プリコンパイル済みヘッダーを試してください。
そうです、そして、%TMP%フォルダーがビルドが書き込まれる場所と同じパーティションにあることを確認してください。VC++は一時ファイルを作成して後で移動するためです。
相互に依存するプロジェクトは、並列化が不可能であることを意味しません。ビルドシステムは、重要な依存関係を把握して回避するのに十分なほどスマートです。そうでなければ、gccは4つのコアを使用できません。
(他の手順に加えて)/ MPを使用してVisual Studioでマルチプロセッシングを有効にしてみてください( http://msdn.Microsoft.com/en-us/library/bb385193.aspx を参照)。 。
Visual Studioプロジェクトをどのように構築していますか?プロジェクトと/build
でide(devenv)を実行しているだけですか、それとも、gccに使用していると私が想定しているのと同じようなメイクファイルがありますか。私は両方のビルドが同様のメイクファイルを使用すると想定していますが、チェックする価値があると思いました。
どちらのコンパイラにもプリコンパイル済みヘッダーを使用していますか? VSのプリコンパイル済みヘッダーを使用していない場合は、それらを使用するように切り替えることができます。個人的には、単一のオールインクルーシブヘッダーファイルではなく#pragma hdrstop
アプローチを使用することをお勧めしますが、現在プリコンパイル済みヘッダーを使用しておらず、強制的にインクルードされる単一のオールインクルーシブヘッダーファイルを試してみたい場合( /FI
コンパイラコマンドラインスイッチ)は、コードを変更せずにすばやくテストできます。
ここで/FI
と#pragma hdrstop
の両方について書きました: http://www.lenholgate.com/blog/2004/07/fi-stlport-precompiled-headers-warning-level-4 -and-pragma-hdrstop.html
それは質問の直接の答えではありませんが、私の会社では分散コンパイルにIncrediBuildを使用しています。それはコンパイルプロセスを本当にスピードアップします。 http://incredibuild.com/visual_studio.htm
John Lakos著の本「Large-Scale C++ Software Design」には、大規模プロジェクト向けのコードと設計の構造化に関する多くのヒントがあります。コンパイルの高速化に関する多くのヒントを含みます。 Visual C++とは直接関係ありませんが、とにかく読む価値があります。
コンパイル時間を短縮するテクニックについて2つの記事を書きました。これらの手法の中には、コンパイル時間の改善に役立つ可能性がある プリコンパイル済みヘッダー および nity builds に関する投稿があります。彼らは技術を透過的に処理するCMakeスクリプトを同梱しています。
完全な再構築を強制しない限り、おそらく依存関係のチェックに問題があります。
いくつかの静的ライブラリを作成できます。ほとんど変更されないコードをライブラリーに入れます。
プログラム構築の最も遅い部分:
一般に、リンクと実行可能ファイルの作成フェーズが最速です。
あなたは決めましたか:
効率を決定するときは、常に(何らかの方法で)プロファイルすることを忘れないでください。
まず、ほとんどの場合、同じプロジェクトのデバッグ構成とリリース構成を並行してビルドできます。
また、あなたが説明するものはひどく遅いように聞こえます-VC++でプリコンパイル済みヘッダーを使用していないか、またはそれらを誤って使用していないように見えます-それらは特にコンパイル時間を改善することを目的としています。
これがまだ問題であるかどうか、そしてメナタイムでどの程度の改善が得られたかはわかりませんが、msbuildが1つのプロジェクト内で同時にオーケストレーションする方法を知らない場合(コード生成がない場合、各cppは個別にビルド可能である必要があります) -codegensは別のプロジェクトに移動するのが最適です)ドライバー開発キットまたは.NETをダウンロードする必要があります [〜#〜] sscli [〜#〜] どちらもnmake、buildが知られているため、物事をうまく平行化します。 SSCLIには既にビルドビルドセットアップが用意されています。DDKにいくつかのビルドサンプルがある場合は、最初からやり直す必要があります。
また、少し古臭い MSBuildに関する記事 並列化については詳しく説明していませんが、実際のmsbuildとmsbuild + slnの違いについて言及しています。/MPと/ Gmが唯一の問題である場合、ラボビルドの.projファイルを編集するために、小さなスクリプトまたはC#exeを作成する必要がある場合があります。または、プロジェクトで明示的なcmd行のオーバーライドを使用して、env varからそのオプションを取得します。
header-file-changesが複数のcppファイルに影響する場合でも、一度に1つのcppファイルをコンパイルしてリンクします。これはビジュアルスタジオマクロで実行できます。
Dim WithEvents myTimer As Timers.Timer
Sub CompileAndLinkCurrentCppFile()
DTE.ExecuteCommand("Build.Compile")
myTimer = New Timers.Timer
myTimer.Interval = 0.05
myTimer.Start()
End Sub
Sub myTimer_Elapsed(ByVal ee As Object, ByVal dd As Timers.ElapsedEventArgs) Handles myTimer.Elapsed
If DTE.Solution.SolutionBuild.BuildState <> vsBuildState.vsBuildStateInProgress And DTE.Solution.SolutionBuild.LastBuildInfo <> 1 Then
myTimer.Stop()
DTE.ExecuteCommand("Build.Link")
End If
End Sub
同じマシンで構築していますか?同じOSを使用していますか? CygwinのGCCと、CygwinをホストするWindows内で実行されているVirtualBoxマシンのGCCを比較すると、3〜10倍の速度の違いが見られます。
そのような違いがあるのは非常に奇妙に思われます...しかし、Visualのマルチコアを利用できない理由もありません!
基本的には、4つのコンパイルモードがあります:(デバッグ/リリース)x(32ビット/ 64ビット)、それぞれが完全に独立しており、4つのコアを完全に活用して、4つのコアを最大限に活用できます。または、単にVisual Studioでマルチプロセッサのアプローチも試してください。
しかし、それはそれをカットするつもりはありません。 150分と10分は大きなギャップです。私の個人的な経験から、コンパイル時間を短縮するには2つの主要な要素があります。