web-dev-qa-db-ja.com

仮想マシンのCPUコアを増やすとコンパイル時間が遅くなるのはなぜですか?

[編集#2] VMWareの誰かが私にVMWare Fusionのコピーを見つけてくれたら、VirtualBoxとVMWareの比較と同じように喜んでやりたいと思います。どういうわけか私は、VMWareハイパーバイザーがハイパースレッディング用により適切に調整されると思います(私の回答も参照してください)

不思議な何かを見ています。 Windows 7 x64仮想マシンでコアの数を増やすと、全体のコンパイル時間はincreasesではなく減少します。コンパイルは通常、中間処理(依存関係のマッピング後)のように並列処理に非常に適しています。各.c/.cpp/.cs/whateverファイルでコンパイラインスタンスを呼び出して、リンカーが取得する部分オブジェクトを構築できます。以上。だから、コンパイルは実際にはコア数で非常にうまくスケーリングすると想像していました。

しかし、私が見ているのは:

  • 8コア:1.89秒
  • 4コア:1.33秒
  • 2コア:1.24秒
  • 1コア:1.15秒

これは、特定のベンダーのハイパーバイザー実装(私の場合はtype2:virtualbox)に起因する単なる設計成果物ですか、それともハイパーバイザー実装をより単純にするために、より多くのVMに普及していますか?非常に多くの要因があるので、私はこの振る舞いに賛成と反対の両方で議論をすることができるようです-誰かが私よりもこれについてもっと知っているなら、私はあなたの答えを読みたいと思います。

ありがとうシド

[edit:addressingコメント]

@MartinBeckett:コールドコンパイルは破棄されました。

@MonsterTruck:直接コンパイルするオープンソースプロジェクトが見つかりませんでした。素晴らしいだろうが、今私の開発環境を台無しにすることはできません。

@Mr Lister、@ philosodad:VirtualBoxを使用して8つのハードウェアスレッドを作成するため、エミュレーションなしで1:1マッピングにする必要があります

@Thorbjorn:VMおよび小さなVS2012プロジェクト用に6.5GBあります-ページファイルをゴミ箱に入れたり出したりしてスワップしていることはほとんどありません。

@All:誰かがオープンソースのVS2010/VS2012プロジェクトを指すことができる場合、それは私の(独自の)VS2012プロジェクトよりも優れたコミュニティリファレンスになる可能性があります。オーチャードとDNNは、VS2012でコンパイルするために環境を微調整する必要があるようです。 VMWare Fusionを使用している人にもこれが表示されるかどうかを確認したい(VMWareとVirtualBoxの区分化の場合)

テストの詳細:

  • ハードウェア:Macbook Pro Retina
    • CPU:Core i7 @ 2.3Ghz(クアッドコア、ハイパースレッド= Windowsタスクマネージャーで8コア)
    • メモリ:16 GB
    • ディスク:256GB SSD
  • ホストOS:Mac OS X 10.8
  • VMタイプ:VirtualBox 4.1.18(タイプ2ハイパーバイザー)
  • ゲストOS:Windows 7 x64 SP1
  • コンパイラ:3つのC#AzureプロジェクトでソリューションをコンパイルするVS2012
    • 「VSCommands」と呼ばれるVS2012プラグインによるコンパイル時間の測定
    • すべてのテストは5回実行され、最初の2回の実行は破棄され、最後の3回は平均されます
17
DeepSpace101

回答:遅くなることはありません。CPUコアの数に応じてスケールアップします。元の質問で使用されたプロジェクトは、「小さすぎる」(実際にはトン開発であるが、コンパイラー用に小さい/最適化されている)のメリットを享受する複数のコア。作業を分散する方法を計画したり、複数のコンパイラプロセスを生成したりするのではなく、この小規模で、すぐに作業を連続して行うのが最善です。

これは、質問へのコメント(および私の個人的な好奇心)に基づいて私が行った新しい実験に基づいています。私はより大きなVSプロジェクトを使用しました-Umbraco CMSの ソースコード は、オープンソースであり、ソリューションファイルを直接ロードして再構築できるためです(ヒント:ロードumbraco_675b272bb0a3\src\umbraco.sln VS2010/VS2012)。

今、私が見ているのは私が期待しているものです、つまりコンパイルはスケールアップします!!まあ、私が見つけたのである時点まで:

Table of results

要点:

  • 新しいVMコアにより、VirtualBoxプロセス内に新しいOS Xスレッドが生成されます
  • コンパイル時間は期待どおりにスケールアップします(コンパイルは十分に長いです)
  • 8 VMコアでは、ペナルティが大きい(50%ヒット)ため、VirtualBox内でコアエミュレーションが発生する可能性があります)
  • 上記は、OS Xが4つのハイパースレッドコア(8 h/wスレッド)をVirtualBoxの8コアとして提示できないために発生する可能性があります。

その最後のポイントにより、「アクティビティモニター」(CPU履歴)を介してすべてのコアのCPU履歴を監視しました。

OS X CPU history graph

要点:

  • 1つのVMコアでは、アクティビティは4つのHWコア間でホッピングしているようです。コアレベルで熱を均等に分散することは理にかなっています。

  • 4つの仮想コア(および27のVirtualBox OS Xスレッドまたは全体で約800 OS Xスレッド)であっても、奇数のHWスレッド(1,3,5,7)でさえ、ほぼ飽和したHWスレッド(0,2,4,6)のみほぼ0%です。おそらくスケジューラはハードウェアコアではなくハードウェアコアの観点から機能するので、OSX 64ビットカーネル/スケジューラはハイパースレッドCPU向けに最適化されていないのではないかと思いますか?または、8VMコアのセットアップを見ると、CPU使用率が高いときにそれらを使用し始めているのではないでしょうか。何かおかしいことが起こっています...まあ、それは一部のダーウィン開発者にとっては別の質問です...

[編集]:VMWare Fusionでも同じことを試したいです。たぶん、これは悪くないでしょう。これを商品として紹介しているのかなぁ….

フッター:

画像が消える場合、コンパイルタイムテーブルは(テキスト、醜い!)

Cores in    Avg compile      Host/OSX    Host/OSX CPU
   VM         times (sec)   Threads      consumption
    1           11.83            24        105-115%
    2           10.04            25        140-190%
    4            9.59            27        180-270%
    8           14.18            31        240-430%
12
DeepSpace101

これが発生する理由として考えられるのは1つだけです。それは、オーバーヘッドが利益を上回っていることです。

ホストマシンから実際のコアやプロセス、さらにはスレッドを割り当てるのではなく、複数のコアをエミュレートしている可能性があります。それは私にはかなりありそうなことであり、明らかにマイナスのスピードアップをもたらすでしょう。

もう1つの可能性は、プロセス自体が十分に並列化されておらず、並列化を試みたとしても、得ているよりも通信オーバーヘッドのコストが高くなることです。

6
philosodad

あなた一人じゃありません ...

Java i3でコンパイルするためにMaven 3.xを使用してJava $ ===を使用して同じことが以前にも起こりました。デフォルトに"4"にすると、スレッドはずっと遅くなり、50近くになりました2つのコアのみを使用するように明示的に指示するよりも%遅くなります。

ハイパースレッディングコンテキストの切り替えと重複するI/Oに関係していると思います。

それについて考え始めると、それは理にかなっています。システム全体の優れたプロファイリングツールを使用して、結果の悪化の原因を証明できます。

0
user7519