これはそれほどプログラミングの問題ではないことは知っていますが、関連性があります。
私はかなり 大規模なクロスプラットフォームプロジェクト に取り組んでいます。 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ではありません。
どうやら Windows 7ではなくWindows 10でプロセスを閉じるとグローバルロックが保持されるという問題があります 。複数のコア、したがって複数のプロセスでコンパイルすると、この問題が発生します。
/analyse
オプションは、Webブラウザをロードするため、perfに悪影響を与える可能性があります 。 (ここでは関係ありませんが、知っておくと便利です)
筋金入りのWindowsシステムハッカーがやって来ない限り、党派的なコメント(これはやらない)と推測(これは私がやろうとしていること)を超えることはないだろう。
ファイルシステム-同じファイルシステムで同じ操作(dir
を含む)を試してください。 this に遭遇しました。これは、さまざまなパラメーターのいくつかのファイルシステムのベンチマークです。
キャッシング。私はかつてLinuxでRAMディスクでコンパイルを実行しようとしましたが、カーネルがキャッシュを処理する方法のおかげで、ディスクで実行するよりも遅いことがわかりました。 Linuxの場合は、パフォーマンスが非常に異なる理由である可能性があります。
Windowsの依存関係の仕様が不適切です。おそらく、Windowsのクロム依存関係の仕様は、Linuxの場合ほど正確ではありません。これにより、小さな変更を加えると、不要なコンパイルが発生する場合があります。 Windowsで同じコンパイラツールチェーンを使用してこれを検証できる場合があります。
いくつかのアイデア:
fsutil behavior set disable8dot3 1
fsutil behavior set mftzone 2
最後の数値を3または4に変更して、サイズをさらに12.5%ずつ増やします。コマンドを実行した後、再起動してからファイルシステムを作成します。fsutil behavior set disablelastaccess 1
fsutil behavior set memoryusage 2
NTFSは毎回ファイルアクセス時間を節約します。あなたはそれを無効にしてみることができます: "fsutil behavior set disablelastaccess 1"(再起動)
Visual C++の問題は、私が知る限り、コンパイラチームがこのシナリオを最適化することは優先事項ではないことです。その解決策は、プリコンパイル済みヘッダー機能を使用することです。これは、Windows固有のプロジェクトが行ったことです。ポータブルではありませんが、機能します。
さらに、Windowsには通常、ウイルススキャナーと、buidフォルダーを監視している場合にビルド時間を完全に台無しにする可能性があるシステム復元および検索ツールがあります。 Windows 7リソースモニターは、それを見つけるのに役立ちます。 ここに返信 vc ++ビルド時間を最適化するためのいくつかのさらなるヒントとともに、本当に興味があるなら。
LinuxでWindows仮想マシンを実行すると、WindowsのIOの速度低下のかなりの部分を取り除くことができました。
そうすることで、作業中の大規模(250Kloc)C++プロジェクトのコンパイル時間を15分から約6分に短縮することができました。
これを行うのが難しいのは、C++自体が拡散する傾向があり、コンパイルプロセスが多くの小さな個々のファイルに及ぶためです。これはLinuxが得意であり、Windowsは得意ではありません。 Windows用の非常に高速なC++コンパイラを作成する場合は、すべてをRAMに保持し、できるだけファイルシステムに触れないようにしてください。
これは、より高速なLinux C++コンパイルチェーンを作成する方法でもありますが、ファイルシステムが既に多くのチューニングを行っているため、Linuxではそれほど重要ではありません。
この理由は、Unixの文化によるものです。歴史的に、ファイルシステムのパフォーマンスは、WindowsよりもUnixの世界ではるかに高い優先事項でした。 Windowsではこれが優先事項ではなかったと言うのではなく、Unixではそれがより高い優先事項であったというだけです。
ソースコードへのアクセス。
制御できないものは変更できません。 Windows NTFSソースコードへのアクセスの欠如は、パフォーマンスを改善するためのほとんどの努力がハードウェアの改善によるものであることを意味します。つまり、パフォーマンスが遅い場合は、ハードウェア(バス、記憶媒体など)を改善することで問題を回避します。問題を解決するのではなく、問題を回避する必要がある場合にのみ、できることはたくさんあります。
Unixソースコードへのアクセスは(オープンソースの前でさえ)より広範でした。したがって、パフォーマンスを改善したい場合は、最初にソフトウェアで(より安く簡単に)、次にハードウェアで対処します。
その結果、Unixファイルシステムを研究し、パフォーマンスを改善する新しい方法を見つけて博士号を取得した人が世界中にたくさんいます。
Unixは多くの小さなファイルの傾向があります。 Windowsは、少数(または単一)の大きなファイルを使用する傾向があります。
Unixアプリケーションは、多くの小さなファイルを処理する傾向があります。ソフトウェア開発環境を考えてみましょう。多くの小さなソースファイルで、それぞれ独自の目的があります。最終段階(リンク)では1つの大きなファイルが作成されますが、それはわずかな割合です。
その結果、Unixには、ファイルを開いたり閉じたり、ディレクトリをスキャンしたりするための高度に最適化されたシステムコールがあります。 Unixの研究論文の歴史は、ディレクトリアクセス(ルックアップと全ディレクトリスキャン)、初期ファイルのオープンなどの改善に多くの考慮を払った数十年にわたるファイルシステムの最適化に及びます。
Windowsアプリケーションは、1つの大きなファイルを開き、長時間開いたままにし、完了したら閉じます。 MS-Wordを考えてください。 msword.exe(または何でも)はファイルを1回開き、数時間追加し、内部ブロックを更新します。ファイルのオープンを最適化する価値は、無駄な時間です。
Windowsのベンチマークと最適化の歴史は、長いファイルを読み書きできる速度にあります。それが最適化されます。
悲しいことに、ソフトウェア開発は最初の状況に向かっています。ヘック、Unix用の最高のワードプロセッシングシステム(TeX/LaTeX)は、各章を異なるファイルに入れて、それらをすべて#includeすることをお勧めします。
Unixは高性能に焦点を当てています。 Windowsはユーザーエクスペリエンスに重点を置いています
Unixはサーバールームで開始されました。ユーザーインターフェイスはありません。ユーザーに見えるのはスピードだけです。したがって、速度が優先されます。
Windowsはデスクトップ上で起動しました。ユーザーは表示内容のみを気にし、UIを表示します。したがって、パフォーマンスよりもUIの改善に多くのエネルギーが費やされます。
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に保持しやすく、繰り返し作業を減らします。非常に印象的なもの。
VC 2008ソリューションが.lib出力を持つ複数のプロジェクトとして設定されている場合、[ライブラリ依存関係入力を使用]を設定する必要があります。これにより、リンカーが.lib。(そして実際にインクリメンタルリンクにします。)
元のマシンでディレクトリをクロールすることと、別のマシンで同じファイルを使用して新しく作成したディレクトリをクロールすることを比較するのは少し不公平です。同等のテストが必要な場合は、おそらくソースマシン上のディレクトリの別のコピーを作成する必要があります。 (それでもまだ遅いかもしれませんが、それはディスクフラグメンテーション、短いファイル名、バックグラウンドサービスなど、いくつもの原因による可能性があります。)dir /s
は、実際のファイルトラバーサルパフォーマンスを測定することよりも、出力の書き込みに関係しています。 dir /s /b > nul
は、巨大なディレクトリを持つ私のマシンでは遅いです。
大規模なクロスプラットフォームプロジェクトをどのように構築しますか? LinuxおよびWindows用の一般的なメイクファイルを使用している場合、メイクファイルがWindows上で高速になるように設計されていないと、Windowsのパフォーマンスが10倍低下する可能性があります。
LinuxおよびWindows用の共通(GNU)メイクファイルを使用して、クロスプラットフォームプロジェクトのメイクファイルを修正しました。 Makeは、レシピの各行に対してsh.exe
プロセスを開始しているため、WindowsとLinuxのパフォーマンスが異なります。
GNU make documentation
.ONESHELL:
この問題は解決するはずですが、この機能は(現在)Windows makeではサポートされていません。そのため、レシピを単一の論理行に書き換える(たとえば、現在のエディター行の最後に; \または\を追加する)ことは非常にうまくいきました!
私見これはすべてディスクI/Oパフォーマンスに関するものです。規模の大きさから、Windowsでは多くの操作がディスクに送られるのに対して、Linuxではメモリで処理されます。つまり、Linuxの方がキャッシュが優れています。 Windowsでの最適なオプションは、ファイルを高速ディスク、サーバー、またはファイルシステムに移動することです。ソリッドステートドライブを購入するか、ファイルをRAMディスクまたは高速NFSサーバーに移動することを検討してください。
ディレクトリトラバーサルテストを実行しましたが、結果は報告されたコンパイル時間に非常に近く、これはCPU処理時間やコンパイラ/リンカーアルゴリズムとはまったく関係がないことを示唆しています。
上記のように、クロムディレクトリツリーを走査する測定時間:
テストでは、クロムソースを取得しました(両方とも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倍のパフォーマンスを発揮します。
数字が間違っていると主張したい人のために-何らかの理由で-それを試してみて、あなたの調査結果を投稿してください。
nmakeの代わりにjomを使用してみてください
ここで入手: http://qt.gitorious.org/qt-labs/jom
実際には、nmakeはコアの1つだけを使用しているので、jomはマルチコアプロセッサを使用するnmakeのクローンです。
GNU makeは、-jオプションのおかげでそのまま使用できます。これは、Microsoft nmakeと比べて速度が速い理由かもしれません。
jomは、異なるプロセッサ/コアで異なるmakeコマンドを並列に実行することで機能します。違いを感じてみてください!
Gnu makeとWindows上のMinGWツールのその他のツールを使用して、観測を1つだけ追加します。ツールがIP経由でも通信できない場合でもホスト名を解決するようです。これは、MinGWランタイムの初期化ルーチンが原因だと思います。ローカルDNSプロキシを実行すると、これらのツールを使用してコンパイル速度を向上させることができました。
VPN接続を並行して開いたときに、ビルド速度が10倍ほど低下したため、頭痛がする前に。この場合、これらのすべてのDNSルックアップはVPNを通過しました。
この観察結果は、MinGWベースだけでなく、他のビルドツールにも適用される可能性があり、その間は最新のMinGWバージョンで変更される可能性があります。
私は最近、Gnu makeを使用してmingw bash.exeを win-bash のバージョンに置き換えることで、WindowsでGnu makeを使用してコンパイルを約10%高速化する別の方法をアーカイブできました。
(win-bashは、インタラクティブな編集に関してあまり快適ではありません。)