ツナ缶雑記

ぐうたらSEのブログです。主にマイクロソフト系技術を中心に扱います。

.NET アプリケーションのビルドにはコア数は必要なのか

f:id:masatsuna:20210602200410p:plain

前回まで、 CPU の差異による .NET Core アプリケーションのビルド時間を計測、検証してきました。 ここまでの結果から、「 CPU を新しくハイパワーなものに変更することで、ビルド時間を大きく短縮することができる」ことが明らかになりました。 しかし、前回検証した Core i7 9700K と Ryzen 9 5900X の検証結果から、実は CPU のシングルスレッド性能より、コア数の差がビルド時間に影響を与えるのではないか、という仮説が生まれました。 今回はこの仮説がどの程度正しいのか検証していこうと思います。

環境

今回検証に使用するマシンは以下の通りです。

項目
CPU AMD Ryzen 9 5900X(PBO は有効に設定)
メモリ DDR4 32GB × 2枚(3200MHz)
記憶装置 1TB NVMe M.2 SSD(PCIe 4.0)
マザーボード MSI B550 TOMAHAWK
CPUクーラー Nocture NH-D15

この PC に Hyper-V をインストールし、 Windows 10 の仮想マシンを作成します。 作成するマシンには、 16GB のメモリを割り当てます。 CPU の仮想プロセッサ数を 4 個、 8 個、 12 個とします。

検証内容

検証は .NET 5 のアプリケーションをビルドし、ビルド時間を比較する方法で行います。 対象のソースコードは、 2021 年 5 月初旬に取得したものを使用します。 各アプリケーションは、 NuGet パッケージを参照しているため、事前にパッケージをすべてローカルにダウンロードした状態でビルドを行います。 ローカルファイル内にパッケージがあれば、ダウンロードする処理は行われないため、ネットワークの影響を限りなく無視することができます。

今回検証の対象となるアプリケーションは、以下の 2 つを利用します。

eShopOnWeb

github.com

こちらはマイクロソフト社が開発している .NET Core のリファレンスとなるアプリケーションです。 リファレンスとして使用するもので、プロジェクトの数も 9 つしかありません。

Entity Framework Core

github.com

.NET Core で使用できる代表的な O/R マッパーです。 こちらはそれなりに規模が大きく、 46 プロジェクトで構成されています。

検証手順

eShopOnWeb

上述のリポジトリからソースコード一式を取得します。 取得したディレクトリをカレントディレクトリに設定し、コマンドプロンプトから以下のコマンドを実行します。

dotnet restore eShopOnWeb.sln

これで NuGet パッケージをローカルにダウンロードできます。 続いて、 CPU がアイドル状態になり、温度も一定になったことを確認してから、以下のコマンドを実行します。

dotnet build eShopOnWeb.sln

実行すると、実行時間が最後に表示されるので、その時間を記録します。 この作業を各環境で 7 回ずつ実行します。

Entity Framework Core

上述のリポジトリからソースコード一式を取得します。 取得したディレクトリをカレントディレクトリに設定し、コマンドプロンプトから以下のコマンドを実行します。

restore.cmd

これで NuGet パッケージをローカルにダウンロードできます。 続いて、 CPU がアイドル状態になり、温度も一定になったことを確認してから、以下のコマンドを実行します。

build.cmd

実行すると、実行時間が最後に表示されるので、その時間を記録します。 この作業を各環境で 7 回ずつ実行します。

検証結果

eShopOnWeb のビルド時間

f:id:masatsuna:20210524204157p:plain

Entity Framework Core のビルド時間

f:id:masatsuna:20210524204208p:plain

結果を見てみましょう。 まずどちらの結果を見ても、プロセッサ数が 4 個の場合、明らかにパフォーマンス劣化が起きています。 プロセッサ数が 8 個以上ある場合、規模が小さいうちはそれほど大きな差はありませんでした。

しかし、規模が大きいプロジェクトでは、プロセッサ数 12 個と 8 個で平均で約 2.5 秒の差がついています。

考察

やはりプロセッサ数が少ないと、ビルド時間に多大な影響が出ることが明らかです。 eShopOnWeb のプロジェクトは、かなり規模の小さなものであると思います。 それであっても、プロセッサ数が 4 個になると性能差が明らかにわかるようになります。 率にすると 5% 程度の差があるようです。

規模が大きくなると、さらにその差は顕著についていきます。 Entity Framework Core のビルド時間は、 4 Core と 8 Core で約 12 秒の差がついています。 率にすると、 27% 程の差がついていることになります。

12 Core まで増やすと、規模の小さなプロジェクトではほとんどビルド時間に差が出なくなっていきます。 規模の大きなプロジェクトでも 6% 程度の差に収まっています。

以上の結果から考えると、最低限プロセッサ数 8 個を確保したほうが、エンジニアとしては幸せになれるということでしょう。

Azure Pipelines のビルドエージェント

ここまでの話は、ビルドマシンとして使う場合にも当てはまります。 例えば Azure Pipelines で利用できる Microsoft Hosted のビルドエージェントは、 Azure の VM でいうところの Standard_DS2_v2*1 を利用しています。 Standard_DS2_v2 は、仮想プロセッサ数 2 つの VM で、ここまでの検証結果から考えると、かなり貧弱なマシンであると言えます。 規模が小さいうちはあまり問題にならないかもしれませんが、プロジェクト数が増えたり、規模が大きくなったりすると、なかなかしんどい結果になることが予想できます。

実際にそれなりに大きな規模のプロジェクトの場合、8 Core くらいの VM を Self Hosted Agent として準備すると、驚くほどビルド時間が短縮できます。 ビルド時間がローカルの開発マシンと比較して長くかかるような現象が見られたら、スケールアップしてコア数を増やすことで、ビルド時間を短縮できる可能性が高いことを示せたと思います。

ただし、 8 Core を超えるマシンを準備しても、ビルド速度という意味ではあまり大きな改善が見込めないかもしれません。 もちろんプロジェクトの構成によっては、並列ビルドが有効に働き、効果が発揮できる可能性も否定できません。 しかし、費用対効果という意味では、 8 Core に軍配が上がる可能性が高くなりそうです。

まとめ

今回は、コア数の差が.NET アプリケーションのビルド時間に影響を与えるかどうか検証してきました。 その結果、コア数はかなり重要な要素であり、コア数が増えた方がビルド時間を短縮できることがわかりました。 また .NET アプリケーションのビルドには、 8 Core くらいのマシンがコストパフォーマンスが良い、という結果が得られました。

今回もなかなか興味深い結果であったと思います。 そして、これまで言われてきた「プログラム開発にはシングルスレッド性能のほうが重要である」という定説は、現在の .NET アプリケーションの開発では、あまり当てはまらないことも確認できました。

ここまで数回にわたって、 .NET アプリケーションのビルドに関するパフォーマンス調査を行ってきました。 次回は、最近開発で利用することの増えてきたモバイルノート PC におけるビルド時間を、 Ryzen 9 5900X と比較してみようと思います。

*1:2021/5/31 現在