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

16コアのRyzen 9 5950xを使用して100万行のC++コードを2分未満でコンパイルする

cppparallelcompile

最近リリースされたAMD Ryzen 9 5950xは、16コア/32スレッドを実現しており、この32スレッドを用いてC++の並列コンパイルを実行すれば、どのようなパフォーマンスが得られるのか、興味深いところです。この記事の執筆時点(2020年12月)で、AMD Ryzen 9 5950xのシングルコアCPUベンチマークスコアは、3515前後で、最高点を獲得しています。一方、C++Builderは、C++によってWindowsアプリをすばやく構築できるRADツールであり、通常のコンパイルオプションのほか、最新バージョンでは、Ryzen 5950xパワーハウスの32スレッドすべてを使用して、C++プロジェクト内の複数のファイルを同時コンパイルできる「TwineCompile」というアドオンを利用できます。以前の2つのブログ記事では、5950xのベンチマークに最大75万行のDelphiコードをコンパイルし、300のネイティブWindowsアプリを並列ビルドしています。

今回C++の並列コンパイルのテストのために使用したプロジェクトは、128個のフォームを持ち、25万4千行あまりのC++コードのある大規模なC++ Windowsアプリケーションです。これらのフォームは、C++クロスプラットフォーム(FMX)サンプルリポジトリから取得した50のプロジェクトからの流用です。50個のフォームを2、3回使用することで、128という数を実現しています。当初、このプロジェクトは、64コア / 128スレッドを装備したAMD Ryzen Threadripper 3990x用のベンチマークとして構築されました。いずれにせよ、プロジェクトに128のフォームを追加したら、128のユニットのそれぞれに、いくつかの汎用的なC++コードを追加して、それぞれが1000行を超えるようにしました。各プロジェクトのワークロードは異なるため、皆さんのプロジェクトでの結果は異なる場合があることにご留意ください。さまざまなC++言語機能とプロジェクト構成が、コンパイル時間を左右するファクターになる可能性があります。

Ryzenのイメージ(提供:AMD)

ベンチマークマシンAMD Ryzen 9 5950xの完全なスペックは、AMD Ryzen 9 5950xに、64GB DDR4 3200MHz RAM、1TB NVMe SSD + 2TB HDD、NVIDIA GeForce RTX 3070 8GBを搭載し、Windows 10 Proがインストールされています。C++Builderの並列コンパイルのCPUとディスクI/Oの状況監視には、Task Manager DeLuxe(Delphiによって構築)を使用しました。Task Manager DeLuxe(TMX)は、Windowsシステムに関する情報量がとても豊富ですばらしいツールです。TMXはMiTeCから入手できます。ここでは、TMXが提供しているのと同じ情報にアクセスできる、さまざまなDelphiコンポーネントも用意されています。以下は、TMXが提供する32 CPUスレッドビューです。この画面ショットは、C++Builderの標準コンパイラによる通常の同期モードでのコンパイル中に取得したものです。画面ショットを見ると、コンパイル時に単一コアのみを同時使用していることが分かります。

次に、C++BuilderでTwineCompileを使用してC++並列コンパイルを実行した直後の、TMXの画面ショットを見てみましょう。この画面ショットでは、すべてのスレッドを使ってコンパイルしていることが分かります。32スレッドすべてがどのように使用されたかを確認できるほか、AMD Ryzen 9 5950xが最大4.9GHzまで(画面ショット上では4.2GHz)ターボブーストする様子が、CPUクロック速度モニターで確認できます。ここで注意すべき興味深い点は、ターボブーストが3.9GHzから4.9GHzの間で一定していないため、実行するごとにベンチマーク結果が数秒ずつ変化することです。

AMD Ryzen 9 5950xのCPUアーキテクチャについて詳しく知りたい方は、こちらのビデオをご覧ください。AMDがZen3アーキテクチャについて解説しています。

では、数字の比較をしていきましょう。C++Builderには、いくつもの種類のビルドオプションがあります。デバッグビルド(-O0)と、さまざまな最適化フラグ(-O1、-O2、-O3)を選択できるリリースビルドです。各フラグは、それぞれ異なる最適化ターゲット設定を持ちます。-O1は可能な限り最小のコードを生成し、-O2は可能な限り最速のコード、-O3は最も最適化が施されたコードを生成します。エンバカデロによれば、-O3を用いると、-O2の最大2倍の速度向上を実現できます。

デバッグビルドは、4つの最適化レベルの中でも最速です。これは特に、通常コンパイル時に違いが出てきます。それは、リリースビルドの方がデバッグビルドよりも、1分近く時間がかかるためです。並列コンパイルを使用した場合、ビルドプロセスはデバッグモードとリリースモードの双方で非常に高速なため、すべてのスコアが僅差となり、ほとんど問題になりませんでした。最初のグラフは、396秒で完了する通常のC++デバッグビルド(-O0)と、33秒で完了する並列C++デバッグビルド(-O0)の比較です(12倍も高速です!)。1秒あたりのコンパイル行数で見ると、-O0オプションでのTwineCompileによる並列コンパイルでは約7,696行/秒、通常の-00オプションでのデバッグビルドでは、641行/秒でした。

2番目のグラフでは、通常のC++リリースビルド(-O1)が404秒で完了するのに対し、並列コンパイルによるリリースビルド(-O1)は32秒で完了しています(これも約12倍高速です!)。並列コンパイルでの所要時間は、ターボブーストの値(3.9GHz~4.9GHz)によって異なります。1秒あたりのコンパイル行数で見ると、-O1オプションでTwineCompileによる並列コンパイルでは約7,937行/秒、通常の-O1オプションでのビルドでは628行/秒でした。

3番目のグラフでは、通常のC++リリースビルド(-O2)が449秒で完了するのに対し、並列コンパイルによるリリースビルド(-O2)は37秒で完了しています(これも約12倍高速です!)。並列コンパイルでの所要時間は、ターボブーストの値(3.9GHz~4.9GHz)によって異なります。1秒あたりのコンパイル行数で見ると、-O2オプションでTwineCompileによる並列コンパイルでは約6,864行/秒、通常の-O2オプションでのビルドでは565行/秒でした。

最後の4番目のグラフでは、通常のC++リリースビルド(-O3)が450秒で完了するのに対し、並列コンパイルによるリリースビルド(-O3)は36秒で完了しています(これも約12倍高速です!)。並列コンパイルでの所要時間は、ターボブーストの値(3.9GHz~4.9GHz)によって異なります。およそ36秒~40秒の間に収まっています。1秒あたりのコンパイル行数で見ると、-O3オプションでTwineCompileによる並列コンパイルでは約7,055行/秒、通常の-O3オプションでのビルドでは564行/秒でした。

並列コンパイルによる生産性の向上は、劇的な効果があると言っても過言ではないでしょう。大規模なC++アプリをわずか30秒あまりでコンパイルできることで、より高速なイタレーションが可能になります(つまり、Delphiで可能なイタレーションと同様のパフォーマンスが期待できます)。今回、Windowsプロジェクトのサイズを大きくするために、128個のフォームと25万4千行あまりのコードを用いました。それは確かに(2〜3のフォームしかない)小さなプロジェクトではありませんが、(数百万行のコードを持つ)巨大プロジェクトでもありません。

さて、ここでDelphi10.4.1コンパイラとC++Builderの並列コンパイルを比較してみましょう。このシリーズの最初のブログでは、AMD Ryzen 9 5950x CPUでジェネリクスを用いた処理量の多いObject Pascalコードを、約61,500行/秒でコンパイルしました。つまり、100万行のジェネリクスコードを含む処理量の多いObject Pascalコードを16秒でコンパイルできると推定できます。最速のパフォーマンスを記録したC++Builder並列ビルド(-O1)は、7,937行/秒でコンパイルできます。これは、100万行のC++コードを約126秒でコンパイルできると推定できる値です。C++Builderで通常のコンパイル(-O1)を実行したときは628行/秒のパフォーマンスであり、100万行のC++コードをコンパイルするには1592秒かかると推定できます。このように、C++Builderの並列コンパイルは、通常のコンパイルよりも桁違いに速いため、コンパイル速度の面でもDelphiの生産性に近づくことができます。

最新のハードウェア、特にAMD Ryzen 9 5950xは、16コア/32スレッドを備え優れた性能を発揮しますが、Ryzen 9 5950xのCPUは現時点では実際に入手するのはまだ困難です。そこで、それよりも前のマシンでTwineCompileを使用した場合はどうでしょうか?実際、過去8年間、日々の開発業務に4コア/8スレッドのi7-3770を使用してきました。このマシンの仕様は、Intel i7-3770、16GB RAM、1TB SSD、Windows 10 Homeといったところです。シングルスレッドのCPUベンチマークスコアが2069であるのに対し、5950xでは3515を記録しています。私が8年間で実際に行った唯一のアップグレードは、ストレージをSamsung 860 EVO 1TB SSDに変更することでした。これは、コンパイル時間に大きな違いをもたらしました。TMXを再度使い、i7-37708スレッドマシンでの通常コンパイルと並列コンパイル時の画面ショットをキャプチャーしました。最初に、C++Builderの通常コンパイルでの表示です。画面ショットでも分かるように、C++コードのコンパイルに、わずか30%ほどのCPUしか使用していません。

次に、同じ128個のフォームと25万4千行のコードを持つC++Builderプロジェクトを、もう一度i7-3770マシンで並列コンパイルしてみましょう。ご覧のように、4コア/8スレッドすべてにアクセスし、マシンの全機能を用いてコンパイルしています。

同じ128個のフォームを持つC++Builderプロジェクトを、このマシンで通常コンパイルしたときと並列コンパイルした場合の数値を比較してみましょう。最初のグラフでは、通常のC++デバッグビルド(-O0)が1023秒で完了するのに対し、並列C++デバッグビルド(-O0)では170秒で完了しています(6倍高速です!)。1秒あたりのコンパイル行数で見ると、TwineCompileによる-O0オプションの並列コンパイルでは約1494行/秒、通常の-O0オプションでのデバッグビルドは、248行/秒でした。

2番目のグラフでは、通常のC++リリースビルド(-O2)が935秒、並列C++リリースビルド(-O2)が142秒で完了します(こちらも約6倍高速です!)。1秒あたりのコンパイル行数で見ると、TwineCompileによる-O2オプションの並列コンパイルでは約1788行/秒、通常の-O2オプションでのデバッグビルドは271行/秒でした。興味深いのは、AMD Ryzen 9 3950xマシンではデバッグビルドがリリースビルドよりも高速であったのに対し、ここの旧式マシンではデバッグビルドの方が遅いことです。確実なデータではありませんが、デバッグビルドがリリースビルドよりもサイズが大きいことが影響している可能性があります。そのため、ソリッドステートハードドライブ(SSD)の速度が、コンパイル速度に影響を与えているのではないかと推測できます。

旧式のハードウェアであっても、C++Builderの並列コンパイルはコンパイル時間の大幅な短縮が可能であり、劇的な生産性向上を図ることができます。旧式のマシンを使用していて、Samsung 860 EVOのようなSSDを装備していない場合、SSDの装着は、通常のハードドライブよりもはるかに優れたパフォーマンスを実現する簡単なアップグレードになります。あるいは、クアッドコアではない古いマシンを使用している方は、比較的低コストで旧式のクアッドコアマシンを入手するのもひとつの手です。

いずれにしても、使用しているハードウェアに関係なく、(少なくとも2つ以上のコアを搭載しているなら)TwineCompileを用いた並列コンパイルによって最新のC++Builderを使用すれば、C++プロジェクトのコンパイル速度を大幅に向上させることができます。このブログ記事では、最新のAMD Ryzen 9 5950x 16コア/32スレッドを用いてベンチマークを実施し、最終的に、イタレーションのスピードアップを図ることで生産性を劇的に向上できることを証明しました。128個のフォームと25万4千行あまりのコードを含む比較的大規模なWindows C++プロジェクトは、16コア/32スレッドを用いた並列コンパイルにより、約30〜40秒でコンパイルすることができました。信じられないような劇的なスピードアップです。古いマシンを用いた通常のコンパイルでは、同じプロジェクトで15~17分もの時間を要しました。

Windows(およびiOS)アプリケーションをC++言語を用いて構築するには、最新のC++Builderが最適な環境を提供します。シングルコアの古いマシンでは、100万行のC++コードをコンパイルするのに60分もかかる恐れがありました。しかし、最新のハードウェアを用いて並列コンパイルを利用すれば、わずか2分しかかからないのです。並列コンパイルは、C++のランタイムパフォーマンスのスピードや能力を犠牲にすることなく、C++開発で必要とされる生産性をもたらすのです。C++Builder 10.4.1で、劇的な生産性を実現するC++開発を始めてください。

C++Builderのコンパイラの詳細については、Embarcadero DocWikiをご覧ください。

C++Builder / Delphi / RAD Studio 10.4.2リリース

リンカのメモリ最適化、例外処理システムの改善など、C++言語に関連する品質改良のほか、新しいWindows向けコンポーネント、IDEの開発生産性強化など、最新プラットフォーム向けのアプリケーション開発をより効率化するアップデートが数多く施されています。

C++BuilderならびにRAD Studio最新バージョンの情報については、こちらのページをご覧ください。


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 を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

読む価値があります...
大規模なC++プロジェクトのビルド時間をTwineCompileで高速化

IN THE ARTICLES