4

ハードディスクからファイルを読み取り、ファイル内のデータに対して何らかの処理を行う C++ プログラムがあります。ファイルの読み取りに標準の Win32 API を使用しています。私の問題は、このプログラムがときどき非常に高速であるのに、突然、以前の速度の 1/6 に遅くなることです。複数の実行で同じファイルを何度も読み取ると、通常、最初の実行が最も遅くなります。その後、他のファイルセットを読み取るまで速度を維持します。したがって、私の明らかな推測は、ディスク アクセス時間をプロファイリングすることでした。perfmon ユーティリティを使用して、プログラムの IO Read Bytes/sec を測定しました。そして、予想通り、読み取ったバイト数に大きな差 (約 5 倍) がありました。私の質問は次のとおりです。

(1)。OS (私の場合は Windows) は、最近読み取ったファイルをどこかにキャッシュして、その後の読み込みを高速化しますか?

(2)。読み取ったすべてのファイルが同じディレクトリに存在することを保証できる場合、それらをハードディスクに配置して、ディスク アクセス時間を短縮する方法はありますか?

このために私にできることはありますか?

4

7 に答える 7

8

1)Windowsは、最近読み取ったファイルをメモリにキャッシュします。『Windows Internals 』には、これがどのように機能するかについての優れた説明が含まれています。最新バージョンのWindowsは、使用履歴に基づいてディスクの内容をメモリにプリエンプティブにフェッチしようとするSuperFetchと、フラッシュドライブにキャッシュできるReadyBoostを使用して、ランダムアクセスを高速化します。これらはすべて、最初の実行後にディスクからデータにアクセスする速度を向上させます。

2)ディレクトリは実際にはディスク上のレイアウトに影響を与えません。ドライブを最適化すると、ファイルデータがグループ化されます。Windows Vista以降では、ディスクが自動的に最適化されます。理想的には、大規模なシーケンシャル読み取りを実行し、書き込みを最小限に抑える必要があります。小さなランダムアクセスと読み取りを伴うインターリーブ書き込みは、パフォーマンスを大幅に低下させます。Windows Performance Toolkitを使用して、ディスクアクセスのプロファイルを作成できます。

于 2009-09-29T18:27:07.400 に答える
8

あなたの番号付きの質問はすでに回答されているようです。ハード ドライブの読み取り速度を向上させるために何ができるかまだ疑問に思っている場合は、次のヒントを参考にしてください。

  • 可能な場合は、ラッパー ライブラリ (や などReadFile) ではなく、OS 関数 ( など) を使用して読み取ります。多くのラッパーは、より多くのレベルのバッファリングを導入しています。iostreamsstdio
  • FILE_FLAG_SEQUENTIAL_SCAN順番に読み取り、フラグを使用して順番に読み取ることを Windows に知らせます。
  • 読み取りのみを行う (書き込みはしない) 場合は、必ず読み取り専用にファイルを開いてください。
  • バイトや文字ではなく、チャンクで読み取ります。
  • 理想的には、チャンクはディスクのクラスタ サイズの倍数にする必要があります。
  • クラスターに合わせたオフセットでディスクから読み取ります。
  • ページ境界でメモリに読み込みます。(大きなチャンクを割り当てている場合は、おそらくページ アラインメントです。)
  • 高度: ファイルの最初の部分だけを読み取った後に計算を開始できる場合は、オーバーラップ I/O を使用して、計算とその後の読み取りを可能な限り並列化することができます。
于 2009-09-30T20:11:47.063 に答える
3

はい、Windows (および最新の OS のほとんど) は最近読み取ったファイル データを未使用の RAM に保持するため、近い将来そのファイル データが再び要求された場合に、RAM で既に使用可能になり、ディスク アクセスを回避できます。

ディスク アクセスを高速化する限り、ドライブのデフラグを試すこともできますが、あまり効果があるとは思えません。ドライブへのアクセスは、RAM アクセスに比べて単純に遅いため、RAM キャッシングによって高速化が実現します。

于 2009-09-29T18:20:34.967 に答える
2

診断テストとして、最初の読み込みにかかる時間を正確に測定できますか?

次に、それを使用して転送速度を決定します。次に、その転送速度を取得して、 HD Tuneを実行したときに得られるものと比較できます。価値のあることとして、私はこれを自分で実行し、Western Digital RE3 ドライブ (より高速な 7200 RPM SATA ドライブの 1 つ) で最小 44.2 MB/秒、平均 87 MB/秒、最大 110 MB/秒の読み取り速度を得ました。

これらすべてのポイントは、自分のアプリケーションが最善を尽くしているかどうかを確認することです。つまり、キャッシュを除けば、ハード ドライブの能力よりも速くファイルを読み取ることはできません。したがって、その限界に達している場合は、それ以上何もする必要はありません。

于 2009-09-29T18:47:07.733 に答える
2

また、テスト中にメモリ不足にならないようにしてください。perfmon を実行し、読み取り中の物理ドライブの [Memory] ​​> [Available Bytes] および [PhysicalDisk] > [Disk Read Bytes/sec] を監視します。プロセスの I/O を監視することも良い考えです。後者はすべての I/O (ネットワークを含む) を結合することに注意してください。

1 台の平均的な SATA ドライブからのシーケンシャル読み取りでは、50 MB/秒を期待する必要があります。良好なストライプ シリアル SCSI ドライブを 2 台使用すると、約 220 MB/s が得られます。使用可能なメモリがゼロに近づいている場合は、それが問題です。最初の読み取りを行った後もフラットなままである場合は、アプリに関係があります。

于 2009-09-30T03:00:50.817 に答える
1

contigと呼ばれる Microsoft ユーティリティを使用して、ディスク上の 1 つのファイルを最適化したり、フラグメント化されていない新しいファイルを作成したりできます。

于 2009-09-29T18:56:34.283 に答える
0

クレイジーな答えについては、情報を最速の部分に配置するようにドライブをフォーマットしてみて、それが役立つかどうかを確認してください。

Tom's Hardwareは、それがどのように行われるかについてレビューしました。

于 2009-09-30T20:34:49.443 に答える