並べ替えを使用する私のCプログラムは、最初は他の時間より10倍遅く実行されます。整数のファイルを使用してソートし、数値を変更してもプログラムはより高速に実行されます。PCを再起動すると、最初のプログラムの実行速度が10倍遅くなります。私time
は時間を数えるために使用します。
7 に答える
オペレーティングシステムは、データが不要になった場合でもRAMにデータを保持するため(これは「キャッシュ」と呼ばれます)、プログラムが再度実行されると、そこからすべてのデータが取得され、ディスクI/Oはありません。データを変更した場合でも、その変更は最初にRAMで行われ、ファイルに書き込まれた後もそこにとどまります。
ただし、RAMに永久に残るわけではありません。他の何かのためにメモリが必要な場合、キャッシュは削除されます。その時点で、ディスクアクセスが必要になります(そして、その時点で再びRAMにキャッシュされます)。
これが、再起動後の最初のアクセスが常に遅い理由です。データはファイルから読み取られなかったため、まだキャッシュされていません。
あなたは仮説を立て、それらを現実に立ち向かわなければなりません。あなたが合理的に作ることができる最初のものは、それがキャッシングの問題のようなにおいがするということです!
それらの質問を自問してください:
- データは空きRAMに収まりますか(=ファイルはOS FSキャッシュによってキャッシュされますか?)
- 私のデータはCPUデータキャッシュに収まりますか?
私のデータはHDD内部キャッシュに収まりますか?
破棄するのが最も簡単な仮説はFSキャッシュです。Linuxでは
sync; echo 3 > /proc/sys/vm/drop_caches
、プログラムを呼び出すたびに発行します。1つ目は、キャッシュされたデータが物理メディア(ハードドライブ)に確実に届くようにし、2つ目は、ファイルシステムキャッシュのコンテンツをメモリから削除します。「物理メディア」はHDDキャッシュ自体である可能性があるため、注意してください... Linuxでは、コマンドを使用してこの「ライトバック」キャッシュを無効にでき
hdparm -W 0 <device>
ます。たとえば、ドライブを使用している場合は、sda
このキャッシュが機能しhdparm -W 0 /dev/sda
ます。テストが終了したら、再度有効にすることをお勧めします:)もう1つの仮説はCPUキャッシュです。x86WindowsでCPUキャッシュフラッシュを実行するにはどうすればよいですか。およびCPUL1およびL2キャッシュをクリアする方法
まあ、それはそれらの1つであるかもしれないし、そうでないかもしれませんが、それは試みを害することはありません:)
プログラムがネットワークアクセスを行う場合、それが最初の遅延の原因である可能性があります。多くのネットワークプロトコルは、設定に時間がかかります。いくつかの例:
- DNS:プログラムがネットワークアクセスを行う場合、ホスト名をIPアドレスに解決する必要がある可能性があります。初めてローカルキャッシュにデータを入力するには、少なくともネットワークラウンドトリップが必要になります。以下のリクエストは短くなります。
- ネットワーク化されたファイルシステム(NFS、CIFSなど):ファイルを開くことはネットワークを介して発生する可能性があります。
- 一見無害に見えるライブラリ機能でさえ、ネットワークアクセスを必要とする場合があります。ホストのユーザーリストは、リモートディレクトリサーバー上にある可能性があります。
このことから、低レベルのトレースツールを使用して、時間が費やされている場所を確認できます。Linuxでは、基本的なツールはstrace -r
です。おそらく他のシステムにも同様のツールがいくつかあります。コンパイラにはプロファイラーも付属している必要があります(つまりgprof
、GCCまたはValgrind用)。
非常によく似た問題がありましたが、大きなファイルをロードしていなかったため、最初の実行時間が長いことに困惑していました(キャッシュが問題になることはありませんでした)。
この答えは私を正しい方向に向けました-それは私のリアルタイムのアンチウイルス保護でした。プログラムを再コンパイルするたびに、悪意のある可能性があるとして再スキャンします。プロジェクトパスを「例外」としてAvira(私の場合)のリアルタイムウイルス保護に追加しました。
最初の実行でのプログラムの実行が迅速になりました!
測定時間には2つの要素があります
ディスクからファイルを読み取り、それをメモリにロードしている場合-そしてソート:
1)ファイルを読み取って配列に保存する時間2)並べ替えの時間
これらは別々に測定されましたか?
これをチェックできますか? Linuxバッファキャッシュの無効化
再起動する代わりに、キャッシュをクリアして実験を繰り返しても同じ結果が得られる場合は、ファイルバッファのキャッシュ効果が考慮されていないと推測できます。
これは目新しいことではありません。あなたのプログラムだけでなく、多くの人気のある商用ソフトウェアがこの問題に直面しています。
まず、遅い拳時間の実行に関するこのMATLABの記事を確認してください
C#やJavaなどの仮想マシンで実行される他のプログラミング言語の場合、これは非常に一般的です。 http://en.wikipedia.org/wiki/Just-in-time_compilation#Startup_delay_and_optimizations
キャッシングはCで発生する十分な理由ですが、それでも10xは非常に長い期間です。再起動後に、システムが他のリソースをロードしていた可能性もあります。
より良い結果を得るには、再起動後、たとえば10分後にプログラムを実行する必要があります。その時点で、すべてのスタートアップアプリケーションがロードされます。(10分----起動アプリケーションの数と各アプリケーションの起動にかかる時間によって異なります)
これは、コンパイラの最適化により、結果がキャッシュされTemoparal Locality
、アクティベーションレコードが保存され、リンク段階でバインディングオブジェクトを再度リロードする必要がないため、時間も節約されます。