Have an amazing solution built in RAD Studio? Let us know. Looking for discounts? Visit our Special Offers page!
C++RAD Studioニュース

C++Builder 12.2で高速な並列コンパイルを行うためのポイント

C++Builder 12.2の新しいWin64ツールチェーンでは、オプションのデフォルト設定で高速な並列ビルドが有効になっています。これによってマシンスペック(コア数やRAMが多い)に応じて高いパフォーマンスを発揮します。さらにC++コードのファイル数が多いほどビルドで生じるオーバーヘッドが減少するという特徴があります。

このブログでは、C++Builder 12.2による高速な並列コンパイルに関する実用的な情報を紹介させていただきます。

使用方法

C++Builder 12.2をインストールし、Windows 64-bitのモダンC++プラットフォームを使用すると、デフォルトでオンになります。設定は不要です。[実行] または [ビルド] をクリックするだけで、並列で実行されます。

プロジェクトのビルドが高速化されること以外にその効果を確認したい場合は、タスクマネージャでbcc64xプロセスの状況をご覧ください。bcc64xプロセスがご利用のマシンのコア数のおよそ2倍の数のスレッドで実行され、CPU使用率が100%に近づいているのが確認できるはずです。

オプション設定の説明は、こちらのドキュメントをご覧ください。例えば、–jobsパラメータとバッチコンパイルを使用します。「サブプロセスの数」をデフォルトの0に設定すると、同時に実行できる並列コンパイルの数が設定されます。0は、可能な限り多く(コア数の約2倍)を使用する設定となります。

ただデフォルト設定は一切変更しないことをお勧めします。なぜならば、デフォルト設定が最も高速にビルドが実行できるように設定されているためです。

もしオプション設定を確認したい場合、例えば、設定が正しいかどうかがわからない場合や、パフォーマンスの向上が見られない場合には、以下のオプション設定を確認してください。

1 20
2 11
  1. プロジェクトでWindows 64ビットのモダンプラットフォームが選択され、アクティブになっていることを確認してください。
  2. プロジェクトオプションを開き、ドロップダウンメニューで「すべての構成」が選択されていることを確認してください。
  3. ビルド > C++ コンパイラ の”バッチコンパイルを有効にする” を「true」に設定する必要があります。また他のターゲット構成がこのオプションを上書きしていないことを再度確認してください。これは、高い継承レベルでデフォルト設定されているはずです。
  4. プロジェクトプロパティ > 一般 > サブプロセスの数を「0」に設定してください。これにより、すべてのコアが使用されます。

CIおよびDevOpsのビルド/ビルドサーバー

ビルドサーバー上でアプリケーションをビルドする場合、CMakeを使用しているか、あるいはコマンドラインでmsbuildを使用してビルドしているケースが考えられます。例えば、「msbuild MyProject.cbproj」のようにターゲットを指定している場合などです。

もしそのケースに該当する場合は、.cbprojファイルを新しいツールチェーンでビルドするように設定すると、デフォルトで可能な限りのコアを使用してビルドされることが確認できます。そのため設定を変更する必要はありません。

手動で作成されたビルド スクリプトなど、bcc64x.exe を手動で呼び出す場合は、12.2 Patch 1 がインストールされていることを確認してください。これにより、IDE 外部のコマンドラインで –jobs パラメータを使用してこの機能が有効になります。例えば、コマンド ラインから以下のように実行します。

上記のバッチ処理の例では、すべてのC++ファイルを一度に処理し、すべてのコアを使用する(サブプロセス数=0) を設定し、ジョブ(並列ビルド)を実行します。

効率性

C++Builder 12.2のコンパイラシステムでは、新しいバージョンの-jobsを使用しており、旧バージョンよりもはるかに効率的です。エンバカデロの社内テストでは、社内でのコンパイラのバッチ処理と並列処理の処理能力も、ninjaやその他の一般的なビルドツールを使用するよりも効率的であることが示されています。

ただし、設計の効率性は良いですが、実際のコンパイルではCPU の使用量が膨大になります。

新しいC++Builderのコンパイラでは、可能な限り多くのコアとRAMを搭載したPCマシンで利用することをお勧めします。

例えば、目安として20コアと 64 GB の RAM を搭載しているPCがお勧めです。さらにコア数とRAMは多ければ多いほど高いパフォーマンスを発揮するため、より高速なビルドを望むのであれば、できるだけ高いスペックのPCでご利用ください。

ヒント:ビルド中はbcc64x.exeのメモリ使用量に注意してください。割り当てられたすべてのコアが使用されます。複雑なC++コードでは、ファイルごとに大量のメモリを使用することがあり、その合計は膨大なものになります。例えば、20個のファイルがそれぞれ1GBを使用すると、20GBのRAMを使用することになります。さらに個々のファイルがそれぞれ3GBに膨れ上がると、ビルドの1セグメントで26GBのRAMを使用することになります。したがって、使用可能なメモリ以上のメモリ量が必要となり、ディスクスワップが発生しないように注意する必要があります。この動作は、ご自身のC++コードに大きく依存するため、ビルドを実行してソース上でどのような動作をするかを確認する必要があります。つまり、ソースをビルドする際に、より多くのRAMが必要かどうかを確認する必要があります。「サブプロセスの数」の設定で使用するコアの数を制限することも可能ですが、この状況では、代わりに RAM を増やすことをお勧めします。

最終的にはご自身のC++コードで実行し、その動作を確認をいただいた上で必要に応じてサーバーまたはビルド マシンを調整してください。

新しいコンパイラシステムは、コンパイルするファイルの数に応じて拡張します。オーバーヘッドはありますが、C++コードを増やすほどオーバーヘッドは小さくなります。したがって、10 個のファイルをコンパイルするよりも 100 個のファイルをコンパイルする方が効率的です。つまり、大規模なアプリケーションのビルドに最適です。(新しいリンカも大幅に高速化され、大規模なリンクセット/アプリケーションをビルド可能なこともご留意ください。)

現実的な結果

cb 12 2 launch slide parallel builds

以前、エンバカデロのウェビナーで紹介した上記のスライドでは、合成生成されたコード (5000 ファイル、360,000 行のコード) を使用したコンパイラのパフォーマンスの結果を比較したデータです。実際のアプリケーションでは、パフォーマンスはこの結果とは異なります。特にSTLを多用した複雑なコードでは、他の業界標準ソリューションにかなり近いパフォーマンスが得られることが分かりました。

では、実際のアプリケーションではどのようなことが期待できるのでしょうか?

エンバカデロでは最近、C++Builder 12.2に関するウェビナーを行い、小規模なデモアプリの実際の結果を紹介しました。このデモではSTLを使用しているため、上記のスライドのグラフほどにはパフォーマンスが向上しないコードの例となります。さらに、このプロジェクトは最も効率の悪いケースですが、それでも大幅な改善が見られます。

なぜ最も効率の悪いケースなのでしょうか? デモアプリにはわずか6つのC++ファイルしかなく、4コアのマシンで実行しているからです。つまり、並列でコンパイルされ、CPUを数秒以上飽和させることができません(4 つのファイルをバッチ処理し、残りの 2 つを 4 つのコアでバッチ処理するので、コンピュータのリソースを半分しか使用できないと考えてください)。さらに、このような少量のコードでは、ビルドのオーバーヘッドがより顕著に現れますため、これはオーバーヘッドと効率がどのように機能するかを示す優れた例です。

新旧のコンパイラシステムを使用してアプリケーションのビルド結果を比較したチャートは、以下の通りです。

一番上は、従来の方法でファイルを 1 つずつ順番にビルドする方法です。まず、プリコンパイルヘッダーを生成します。これはシングルコアを使用して 9 秒かかりました。次に、6 つのファイルすべてを 1 つずつコンパイルし、27.8 秒かかりました。その後、リンクを行い、5秒かかりました。

下記のスライドのグラフの結果は、左から以下の色で表示されています。

  • はプリコンパイル済みヘッダーのオーバーヘッド
  • はコードのコンパイル
  • はリンク
cb 12 2 old vs new system build performance comparison

プリコンパイルヘッダーをビルドする必要があります(青色)。これはシングルコアで10秒かかり、並列化を開始する前に完了する必要があります。これはオーバーヘッドであり、実際にコンパイルに費やす時間が長ければ長いほど、相対的な時間は短縮されます。

しかし、その後すぐに並列ビルド(赤色)に入り、合計コンパイル時間は5.8秒です。(あくまで一例ですが、検証したPCは4コアVMで4.8倍の高速化であり、27.8秒から5.8秒に短縮されました)

次にリンクの実行です。(黄色) これには 1 秒かかります。これもオーバーヘッドですが、新しいリンカは非常に高速で、ここでは 5倍高速であることに注目してください。

つまり、CPU が飽和状態になり、ファイル数が増えるほど、CPU がより長時間飽和状態になり、他のビルド部分の相対的なオーバーヘッドが縮小されるため、効率が上がります。

クラシックコンパイラとの比較

従来のWin32版のBorlandコンパイラ(以降、クラシックコンパイラ)をまだ使用している方からよくある質問は、「どうすれば クラシックコンパイラと同じくらい高速になるのか?」ということです。。2000年代の終わりからアップデートされていないクラシックコンパイラは、より高速ですが、できることは限られています。Clangはより多くのことを行いますが、より多くの時間を要します。この質問をされている方にとっては、ビルド時間と製品機能(例えば、最適化、言語サポート、ライブラリなど)のどちらを重視しているかと言えば、ビルドに要する時間に重きを置いているように感じました。

そのテストでは、十分な数のコアを使用すると、クラシックコンパイラに近づく傾向があることが示されています。正確な数値はC++コードによって異なりますが、あるコードベースで実施したテストでは、10~12コア数でクラシックコンパイラと同等の速度が得られました。ただC++コードによっては、これより速くなる場合もあれば、遅くなる場合もあります。

以上によりエンバカデロからの提案は、できるだけコア数とRAMを多く搭載した高いスペックのPCを利用することです。十分なコア数があれば、クラシックコンパイラよりも高速化できると考えるべきでしょう。クラシックコンパイラを使用している場合は、新しいWin64ツールチェーンへアップグレードを強くお勧めします。

まとめ

このブログの情報が皆様のお役に立てば幸いです。適切な設定ではデフォルトでオンになっているため、12.2 (またはそれ以降) をインストールし、新しいWin64ツールチェーンを使用していることを確認するだけで、この機能が利用できるようになります。(古いWin64ツールチェーンではサポートされていません。) 

将来的に古いWin64ツールチェーンは廃止予定となっていますので、新しいWin64ツールチェーンへの移行をご検討ください。

そして新しいWin64ツールチェーンは、パフォーマンスの大幅な向上につながるでしょう (「アップデートをインストールしてプラットフォームを使用するだけで、設定を構成せずに実現する」というのは、かなりクールだと思います)。

特にクラシックコンパイラを使用している場合は、ぜひ検討してみてください。

See What's New in 12.2 Athens See What's New in 12.2 Athens Dev Days of Summer 2-24

Reduce development time and get to market faster with RAD Studio, Delphi, or C++Builder.
Design. Code. Compile. Deploy.
Start Free Trial   Upgrade Today

   Free Delphi Community Edition   Free C++Builder Community Edition

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

IN THE ARTICLES