web-dev-qa-db-ja.com

C ++をコンパイルするためにWindowsをLinuxのように高速にするにはどうすればよいですか?

これはそれほどプログラミングの問題ではないことは知っていますが、関連性があります。

私はかなり 大規模なクロスプラットフォームプロジェクト に取り組んでいます。 WindowsではVC++ 2008を使用します。Linuxではgccを使用します。プロジェクトには約4万個のファイルがあります。 Windowsは、同じプロジェクトのコンパイルとリンクにおいて、Linuxよりも10倍から40倍遅いです。どうすれば修正できますか?

Linuxでは20秒、Windowsでは3分を超える単一の変更インクリメンタルビルド。どうして? Linuxに「ゴールド」リンカーをインストールして、その時間を7秒に短縮することもできます。

同様に、gitはLinuxでWindowsよりも10倍から40倍高速です。

Gitの場合、gitはWindowsを最適な方法で使用していない可能性がありますが、VC++ですか?マイクロソフトは独自の開発者を可能な限り生産的にしたいと考えていると思いますが、コンパイルの高速化はそのために大いに役立ちます。たぶん彼らは開発者にC#を勧めようとしているのでしょうか?

簡単なテストとして、たくさんのサブフォルダーがあるフォルダーを見つけて、

dir /s > c:\list.txt

windowsで。 2回実行し、2回目の実行のタイミングを合わせて、キャッシュから実行します。ファイルをLinuxにコピーし、同等の2回の実行を行い、2回目の実行の時間を計ります。

ls -R > /tmp/list.txt

まったく同じ仕様のワークステーションが2台あります。 12ギガバイトのRAM、8コア、3.0 GHzのHP Z600。 〜400kファイルのフォルダーでは、Windowsは40秒かかり、Linuxは1秒未満かかります。

Windowsを高速化するために設定できるレジストリ設定はありますか?何が得られますか?


コンパイル時間に関連するわずかに関連するいくつかのリンク。必ずしもI/Oではありません。

138
gman

筋金入りのWindowsシステムハッカーがやって来ない限り、党派的なコメント(これはやらない)と推測(これは私がやろうとしていること)を超えることはないだろう。

  1. ファイルシステム-同じファイルシステムで同じ操作(dirを含む)を試してください。 this に遭遇しました。これは、さまざまなパラメーターのいくつかのファイルシステムのベンチマークです。

  2. キャッシング。私はかつてLinuxでRAMディスクでコンパイルを実行しようとしましたが、カーネルがキャッシュを処理する方法のおかげで、ディスクで実行するよりも遅いことがわかりました。 Linuxの場合は、パフォーマンスが非常に異なる理由である可能性があります。

  3. Windowsの依存関係の仕様が不適切です。おそらく、Windowsのクロム依存関係の仕様は、Linuxの場合ほど正確ではありません。これにより、小さな変更を加えると、不要なコンパイルが発生する場合があります。 Windowsで同じコンパイラツールチェーンを使用してこれを検証できる場合があります。

32
Noufal Ibrahim

いくつかのアイデア:

  1. 8.3名を無効にします。これは、多数のファイルと比較的少数のフォルダーを持つドライブでは大きな要因になる可能性があります。fsutil behavior set disable8dot3 1
  2. より多くのフォルダーを使用します。私の経験では、NTFSはフォルダーごとに約1000を超えるファイルで減速し始めます。
  3. MSBuildで並列ビルドを有効にします。 「/ m」スイッチを追加するだけで、CPUコアごとにMSBuildのコピーが自動的に開始されます。
  4. ファイルをSSDに置く-ランダムI/Oに非常に役立ちます。
  5. 平均ファイルサイズが4KBをはるかに超える場合は、平均ファイルサイズにほぼ相当する、より大きなクラスターサイズでファイルシステムを再構築することを検討してください。
  6. ファイルが最適化されていることを確認してください。断片化されたファイルは大量のディスクシークを引き起こし、スループットが40倍以上になります。 sysinternalsの「contig」ユ​​ーティリティ、または組み込みのWindowsデフラグツールを使用します。
  7. 平均ファイルサイズが小さく、使用しているパーティションが比較的いっぱいになっている場合、断片化されたMFTで実行している可能性がありますが、これはパフォーマンスに悪影響を及ぼします。また、1Kより小さいファイルはMFTに直接保存されます。上記の「contig」ユ​​ーティリティが役立つ場合があります。または、MFTサイズを増やす必要がある場合があります。次のコマンドは、ボリュームの25%に2倍になります:fsutil behavior set mftzone 2最後の数値を3または4に変更して、サイズをさらに12.5%ずつ増やします。コマンドを実行した後、再起動してからファイルシステムを作成します。
  8. 最終アクセス時刻を無効にします:fsutil behavior set disablelastaccess 1
  9. インデックスサービスを無効にする
  10. ウイルス対策ソフトウェアおよびスパイウェア対策ソフトウェアを無効にするか、少なくとも関連するフォルダーを無視するように設定します。
  11. OSおよびページングファイルとは異なる物理ドライブにファイルを配置します。別の物理ドライブを使用すると、Windowsは両方のドライブにパラレルI/Oを使用できます。
  12. コンパイラフラグをご覧ください。 Windows C++コンパイラには多数のオプションがあります。本当に必要なものだけを使用していることを確認してください。
  13. OSがページプールバッファに使用するメモリ量を増やしてみてください(十分なRAM最初)があることを確認してください:fsutil behavior set memoryusage 2
  14. Windowsエラーログをチェックして、ディスクエラーがときどき発生していないことを確認します。
  15. 物理ディスクに関連するパフォーマンスカウンターを見て、ディスクの負荷を確認してください。長いキューの長さまたは転送ごとの長い時間は悪い兆候です。
  16. ディスクパーティションの最初の30%は、未加工の転送時間の点で、ディスクの他の部分よりもはるかに高速です。狭いパーティションは、シーク時間を最小限に抑えるのにも役立ちます。
  17. RAIDを使用していますか?その場合、RAIDタイプの選択を最適化する必要がある場合があります(RAID-5はコンパイルなどの書き込みが多い操作には適していません)
  18. 不要なサービスを無効にします
  19. フォルダーのデフラグ:すべてのファイルを別のドライブにコピー(ファイルのみ)、元のファイルを削除、すべてのフォルダーを別のドライブにコピー(空のフォルダーのみ)、元のフォルダーを削除、元のドライブをデフラグ、フォルダー構造を最初にコピーします、ファイルをコピーします。 Windowsが大きなフォルダーを一度に1ファイルずつ作成すると、フォルダーは断片化されて遅くなります。 (「コンティグ」もここで役立つはずです)
  20. I/OバウンドでCPUサイクルに余裕がある場合は、ディスク圧縮をオンにしてみてください。 CPUのコストをいくらか抑えつつ、高圧縮性ファイル(ソースコードなど)の大幅な高速化を実現できます。
28
RickNZ

NTFSは毎回ファイルアクセス時間を節約します。あなたはそれを無効にしてみることができます: "fsutil behavior set disablelastaccess 1"(再起動)

24
Agent_L

Visual C++の問題は、私が知る限り、コンパイラチームがこのシナリオを最適化することは優先事項ではないことです。その解決策は、プリコンパイル済みヘッダー機能を使用することです。これは、Windows固有のプロジェクトが行ったことです。ポータブルではありませんが、機能します。

さらに、Windowsには通常、ウイルススキャナーと、buidフォルダーを監視している場合にビルド時間を完全に台無しにする可能性があるシステム復元および検索ツールがあります。 Windows 7リソースモニターは、それを見つけるのに役立ちます。 ここに返信 vc ++ビルド時間を最適化するためのいくつかのさらなるヒントとともに、本当に興味があるなら。

20
user180326

LinuxでWindows仮想マシンを実行すると、WindowsのIOの速度低下のかなりの部分を取り除くことができました。

そうすることで、作業中の大規模(250Kloc)C++プロジェクトのコンパイル時間を15分から約6分に短縮することができました。

17
bfrog

これを行うのが難しいのは、C++自体が拡散する傾向があり、コンパイルプロセスが多くの小さな個々のファイルに及ぶためです。これはLinuxが得意であり、Windowsは得意ではありません。 Windows用の非常に高速なC++コンパイラを作成する場合は、すべてをRAMに保持し、できるだけファイルシステムに触れないようにしてください。

これは、より高速なLinux C++コンパイルチェーンを作成する方法でもありますが、ファイルシステムが既に多くのチューニングを行っているため、Linuxではそれほど重要ではありません。

この理由は、Unixの文化によるものです。歴史的に、ファイルシステムのパフォーマンスは、WindowsよりもUnixの世界ではるかに高い優先事項でした。 Windowsではこれが優先事項ではなかったと言うのではなく、Unixではそれがより高い優先事項であったというだけです。

  1. ソースコードへのアクセス。

    制御できないものは変更できません。 Windows NTFSソースコードへのアクセスの欠如は、パフォーマンスを改善するためのほとんどの努力がハードウェアの改善によるものであることを意味します。つまり、パフォーマンスが遅い場合は、ハードウェア(バス、記憶媒体など)を改善することで問題を回避します。問題を解決するのではなく、問題を回避する必要がある場合にのみ、できることはたくさんあります。

    Unixソースコードへのアクセスは(オープンソースの前でさえ)より広範でした。したがって、パフォーマンスを改善したい場合は、最初にソフトウェアで(より安く簡単に)、次にハードウェアで対処します。

    その結果、Unixファイルシステムを研究し、パフォーマンスを改善する新しい方法を見つけて博士号を取得した人が世界中にたくさんいます。

  2. Unixは多くの小さなファイルの傾向があります。 Windowsは、少数(または単一)の大きなファイルを使用する傾向があります。

    Unixアプリケーションは、多くの小さなファイルを処理する傾向があります。ソフトウェア開発環境を考えてみましょう。多くの小さなソースファイルで、それぞれ独自の目的があります。最終段階(リンク)では1つの大きなファイルが作成されますが、それはわずかな割合です。

    その結果、Unixには、ファイルを開いたり閉じたり、ディレクトリをスキャンしたりするための高度に最適化されたシステムコールがあります。 Unixの研究論文の歴史は、ディレクトリアクセス(ルックアップと全ディレクトリスキャン)、初期ファイルのオープンなどの改善に多くの考慮を払った数十年にわたるファイルシステムの最適化に及びます。

    Windowsアプリケーションは、1つの大きなファイルを開き、長時間開いたままにし、完了したら閉じます。 MS-Wordを考えてください。 msword.exe(または何でも)はファイルを1回開き、数時間追加し、内部ブロックを更新します。ファイルのオープンを最適化する価値は、無駄な時間です。

    Windowsのベンチマークと最適化の歴史は、長いファイルを読み書きできる速度にあります。それが最適化されます。

    悲しいことに、ソフトウェア開発は最初の状況に向かっています。ヘック、Unix用の最高のワードプロセッシングシステム(TeX/LaTeX)は、各章を異なるファイルに入れて、それらをすべて#includeすることをお勧めします。

  3. Unixは高性能に焦点を当てています。 Windowsはユーザーエクスペリエンスに重点を置いています

    Unixはサーバールームで開始されました。ユーザーインターフェイスはありません。ユーザーに見えるのはスピードだけです。したがって、速度が優先されます。

    Windowsはデスクトップ上で起動しました。ユーザーは表示内容のみを気にし、UIを表示します。したがって、パフォーマンスよりもUIの改善に多くのエネルギーが費やされます。

  4. Windowsエコシステムは、計画的な陳腐化に依存しています。新しいハードウェアがわずか1年か2年先にあるのに、なぜソフトウェアを最適化するのですか?

    私は陰謀説を信じていませんが、もしそうなら、Windows文化ではパフォーマンスを改善するインセンティブが少ないことを指摘します。 Windowsビジネスモデルは、時計仕掛けのような新しいマシンを購入する人々に依存しています。 (だからこそ、MSがオペレーティングシステムを遅く出荷したり、Intelがチップのリリース日を逃したりすると、数千の企業の株価が影響を受けることになります。)これは、新しいハードウェアを購入するように人々に伝えることにより、パフォーマンスの問題を解決するインセンティブがあることを意味します。実際の問題を改善することによってではなく、オペレーティングシステムの速度を低下させます。 Unixは予算が限られているアカデミアから来ており、ファイルシステムを高速化する新しい方法を発明することで博士号を取得できます。アカデミアの誰かが注文書を発行して問題を解決するためのポイントを獲得することはめったにありません。 Windowsでは、ソフトウェアを遅くする陰謀はありませんが、エコシステム全体は計画的な陳腐化に依存しています。

    また、Unixはオープンソースであるため(そうでなくても誰もがソースにアクセスできました)、退屈している博士課程の学生はコードを読んで、コードを改善することで有名になります。これはWindowsでは発生しません(MSにはアカデミックにWindowsのソースコードへのアクセスを提供するプログラムがあり、ほとんど利用されません)。次のUnix関連のパフォーマンスペーパーをご覧ください。 http://www.eecs.harvard.edu/margo/papers/ または、Osterhaus、Henry Spencer、その他による論文の歴史を調べてください。ヘック、Unix史上最大の(そして最も楽しい)討論の1つは、OsterhausとSelzerの間の行き来でした http://www.eecs.harvard.edu/margo/papers/usenix95-lfs/補足/rebuttal.html Windowsの世界ではそのようなことは起きていません。ベンダーが互いに1対1になっているのを見るかもしれませんが、最近はイノベーションがすべて標準化団体レベルにあるように思われるため、それははるかに稀であるようです。

それは私がそれを見る方法です。

更新:Microsoftから出てくる新しいコンパイラチェーンを見ると、彼らがしていることの多くがそれを作るので、あなたは非常に楽観的です。ツールチェーン全体をRAMに保持しやすく、繰り返し作業を減らします。非常に印象的なもの。

15
TomOnTime

増分リンク

VC 2008ソリューションが.lib出力を持つ複数のプロジェクトとして設定されている場合、[ライブラリ依存関係入力を使用]を設定する必要があります。これにより、リンカーが.lib。(そして実際にインクリメンタルリンクにします。)

ディレクトリトラバーサルパフォーマンス

元のマシンでディレクトリをクロールすることと、別のマシンで同じファイルを使用して新しく作成したディレクトリをクロールすることを比較するのは少し不公平です。同等のテストが必要な場合は、おそらくソースマシン上のディレクトリの別のコピーを作成する必要があります。 (それでもまだ遅いかもしれませんが、それはディスクフラグメンテーション、短いファイル名、バックグラウンドサービスなど、いくつもの原因による可能性があります。)dir /sは、実際のファイルトラバーサルパフォーマンスを測定することよりも、出力の書き込みに関係しています。 dir /s /b > nulは、巨大なディレクトリを持つ私のマシンでは遅いです。

7
MSN

大規模なクロスプラットフォームプロジェクトをどのように構築しますか? LinuxおよびWindows用の一般的なメイクファイルを使用している場合、メイクファイルがWindows上で高速になるように設計されていないと、Windowsのパフォーマンスが10倍低下する可能性があります。

LinuxおよびWindows用の共通(GNU)メイクファイルを使用して、クロスプラットフォームプロジェクトのメイクファイルを修正しました。 Makeは、レシピの各行に対してsh.exeプロセスを開始しているため、WindowsとLinuxのパフォーマンスが異なります。

GNU make documentation

.ONESHELL:

この問題は解決するはずですが、この機能は(現在)Windows makeではサポートされていません。そのため、レシピを単一の論理行に書き換える(たとえば、現在のエディター行の最後に; \または\を追加する)ことは非常にうまくいきました!

5
V15I0N

私見これはすべてディスクI/Oパフォーマンスに関するものです。規模の大きさから、Windowsでは多くの操作がディスクに送られるのに対して、Linuxではメモリで処理されます。つまり、Linuxの方がキャッシュが優れています。 Windowsでの最適なオプションは、ファイルを高速ディスク、サーバー、またはファイルシステムに移動することです。ソリッドステートドライブを購入するか、ファイルをRAMディスクまたは高速NFSサーバーに移動することを検討してください。

ディレクトリトラバーサルテストを実行しましたが、結果は報告されたコンパイル時間に非常に近く、これはCPU処理時間やコンパイラ/リンカーアルゴリズムとはまったく関係がないことを示唆しています。

上記のように、クロムディレクトリツリーを走査する測定時間:

  • NTFS上のWindows Home Premium 7(8GB Ram):32秒
  • NTFS上のUbuntu 11.04 Linux(2GB Ram):10秒
  • Ext4上のUbuntu 11.04 Linux(2GB Ram):0.6秒

テストでは、クロムソースを取得しました(両方ともwin/linuxの下で)

git clone http://github.com/chromium/chromium.git 
cd chromium
git checkout remotes/Origin/trunk 

走った時間を測定する

ls -lR > ../list.txt ; time ls -lR > ../list.txt # bash
dir -Recurse > ../list.txt ; (measure-command { dir -Recurse > ../list.txt }).TotalSeconds  #Powershell

アクセスタイムスタンプ、ウイルススキャナーを無効にし、ウィンドウ(> 2Gb RAM)の下でキャッシュマネージャーの設定を増やしました-目立った改善はありませんでした。事実、LinuxはWindowsの4分の1のRAMで50倍のパフォーマンスを発揮します。

数字が間違っていると主張したい人のために-何らかの理由で-それを試してみて、あなたの調査結果を投稿してください。

4
b7kich

nmakeの代わりにjomを使用してみてください

ここで入手: http://qt.gitorious.org/qt-labs/jom

実際には、nmakeはコアの1つだけを使用しているので、jomはマルチコアプロセッサを使用するnmakeのクローンです。

GNU makeは、-jオプションのおかげでそのまま使用できます。これは、Microsoft nmakeと比べて速度が速い理由かもしれません。

jomは、異なるプロセッサ/コアで異なるmakeコマンドを並列に実行することで機能します。違いを感じてみてください!

2
OpenNingia

Gnu makeとWindows上のMinGWツールのその他のツールを使用して、観測を1つだけ追加します。ツールがIP経由でも通信できない場合でもホスト名を解決するようです。これは、MinGWランタイムの初期化ルーチンが原因だと思います。ローカルDNSプロキシを実行すると、これらのツールを使用してコンパイル速度を向上させることができました。

VPN接続を並行して開いたときに、ビルド速度が10倍ほど低下したため、頭痛がする前に。この場合、これらのすべてのDNSルックアップはVPNを通過しました。

この観察結果は、MinGWベースだけでなく、他のビルドツールにも適用される可能性があり、その間は最新のMinGWバージョンで変更される可能性があります。

1
V15I0N

私は最近、Gnu makeを使用してmingw bash.exeを win-bash のバージョンに置き換えることで、WindowsでGnu makeを使用してコンパイルを約10%高速化する別の方法をアーカイブできました。

(win-bashは、インタラクティブな編集に関してあまり快適ではありません。)

0
V15I0N