50

コミットごとに、buildbot で 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++ でコンパイル時間を短縮するためにできることはありますか?

4

12 に答える 12

17

VC++ コンパイラが遅くなる原因の 1 つは、非自明なconst値型の具体的なインスタンスを初期化するヘッダー ファイルがある場合です。これは、タイプの定数std::stringまたは GUID で発生する場合があります。コンパイル時間とリンク時間の両方に影響します。

単一の dll の場合、これにより 10 倍の速度低下が発生しました。それらをプリコンパイル済みヘッダー ファイルに入れるか、ヘッダーで宣言して cpp ファイルで初期化すると役立ちます。

ウイルス スキャナーを調べて、コンパイル済みのヘッダーを試してみてください。そうしないと、VC++ を最大限に活用することはできません。

そうそう、VC++ は一時ファイルを作成して後で移動するため、%TMP% フォルダーがビルドの書き込み先と同じパーティションにあることを確認してください。

于 2010-02-16T19:23:59.667 に答える
10

相互に依存しているプロジェクトは、並列化が不可能であることを意味するものではありません。ビルドシステムは、重大な依存関係を把握して回避するのに十分スマートです。そうでなければ、gcc は 4 コアを使用できません。

したがって (他の手順に加えて)、/MP を使用して Visual Studio でマルチプロセッシングを有効にしてみませんか ( http://msdn.microsoft.com/en-us/library/bb385193.aspxを参照)。

于 2010-02-12T11:38:29.990 に答える
6

How are you building the Visual Studio projects? Are you just running the ide (devenv) with the project and /build or do you have a makefile similar to what I assume you are using for gcc. I'm assuming that both builds use a similar makefile but I thought it worth checking.

Are you using precompiled headers for either compiler? If you're NOT using precompiled headers for VS then you might like to switch to using them. Personally I'd recommend using the #pragma hdrstop approach rather than a single all inclusive header file but if you're currently NOT using precompiled headers and want to try it out a single all inclusive header file that is force included (using the /FI compiler command line switch) can be tested quickly without any code changes.

I wrote about both /FI and #pragma hdrstop here: http://www.lenholgate.com/blog/2004/07/fi-stlport-precompiled-headers-warning-level-4-and-pragma-hdrstop.html

于 2010-02-12T12:08:16.950 に答える
6

It's not the direct answer for the question but at my company we are using IncrediBuild for distributed compilation. It really speeds up the compilation process. http://incredibuild.com/visual_studio.htm

于 2010-02-12T18:11:37.357 に答える
3

John Lakos による「Large-Scale C++ Software Design」という本には、大規模なプロジェクトのコードと設計を構築するためのヒントがたくさんあります。コンパイルを高速化するための多くのヒントが含まれています。Visual C++ とは直接関係ありませんが、とにかく読む価値があります。

于 2010-08-05T11:50:46.190 に答える
1

まず、ほとんどの場合、同じプロジェクトのデバッグ構成とリリース構成を並行してビルドできます。

また、あなたの説明はひどく遅いように聞こえます-VC ++でプリコンパイル済みヘッダーを使用していないか、それらを誤って使用していないようです-それらは特にコンパイル時間を改善することを目的としています。

于 2010-02-12T11:22:15.483 に答える
1

完全な再構築を強制しない限り、依存関係のチェックに問題がある可能性があります。

いくつかの静的ライブラリを作成できます。めったに変更されないコードをライブラリに入れます。

プログラムの構築で最も遅い部分:

  1. ファイルの開閉。
  2. ソース ファイルの解析と翻訳。

一般に、リンクと実行可能ファイルの作成フェーズが最も高速です。

次のことを決定しましたか。

  1. どのフェーズが最も遅いですか?
  2. コンパイルが最も遅いファイルはどれですか?

効率を判断するときは、常にプロファイルを (何らかの方法で) 行うことを忘れないでください。

于 2010-02-12T17:47:45.600 に答える
0

そのような違いがあるのは非常に奇妙に思えます...しかし、ビジュアルのマルチコアを利用できない理由もありません!

基本的に、4つのコンパイルモードがあります:(デバッグ/リリース)x(32ビット/ 64ビット)、それぞれが互いに完全に独立しているため、利用可能な4つのコアを最大限に活用して、4つを完全に並列で実行できます。または、VisualStudioでもMultiProcessorアプローチを試してみてください。

しかし、それはそれをカットするつもりはありません。150分対10分は大きなギャップです。私の個人的な経験から、コンパイル時間を短縮するには2つの主要な要因があります。

  • すべてのファイルをローカルディスクで使用し(必要に応じてリモートディスクからのレプリケーションを使用)、すべてのファイルをローカルでも作成します(.o .so)
  • すべてのコアを自由に使用できます。可能であれば、マルチマシン(distccなど)を使用することもできます。
于 2010-02-12T11:44:35.727 に答える
0

同じマシンでビルドしていますか? 同じOSを使用していますか?Cygwin の GCC と、Cygwin をホストする Windows 内で実行されている VirtualBox マシンの GCC を比較すると、3 ~ 10 倍の範囲で速度の違いが見られました。

于 2010-02-12T11:37:58.120 に答える
0

ヘッダー ファイルの変更が複数の cpp ファイルに影響する場合でも、一度に 1 つの cpp ファイルをコンパイルしてリンクします。これは、Visual Studio マクロで実現できます。

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
于 2010-02-27T14:21:05.993 に答える
0

これがまだ問題であるかどうか、およびメナタイムでどれだけ改善されたかはわかりませんが、それでもmsbuildが1つのプロジェクト内で同時にオーケストレーションする方法を知らないということです(いくつかのコードゲンがない限り、各cppは個別にビルド可能でなければなりません) - codegens は別のプロジェクトに移動するのが最適です) ドライバー開発キットまたは .NET SSCLIをダウンロードする必要があります。どちらも、うまく並列化することが知られている nmake ビルドを持っているからです。SSCLI にはビルド ビルド セットアップが既にあります。DDK にビルド サンプルがいくつかある場合は、最初から作成する必要があります。

また、 MSBuildの並列化に関する少し古い記事では、詳細には触れていませんが、実際の msbuild と msbuild + sln の違いについて言及しています。/MP と /Gm が唯一の問題である場合は、ラボ ビルド用の .proj ファイルを編集するために、小さなスクリプトまたは C# exe を作成する必要がある場合があります。または、プロジェクトで明示的なコマンド ライン オーバーライドを使用し、env var からそのオプションを取得します。

于 2010-10-25T01:33:17.180 に答える