1

非常に大きなファイルで動作する Windows 7 - 64 ビット用の C/C++ プログラムを作成しました。最後のステップでは、入力ファイル (10GB 以上) から行を読み取り、それらを出力ファイルに書き込みます。入力ファイルへのアクセスはランダムで、書き込みはシーケンシャルです。編集: このアプローチの主な理由は、RAM の使用量を減らすことです。

私が基本的に読む部分で行うことは次のとおりです:(申し訳ありませんが、非常に短く、おそらくバグがあります)

void seekAndGetLine(char* line, size_t lineSize, off64_t pos, FILE* filePointer){
  fseeko64(filePointer, pos, ios_base::beg);
  fgets(line, lineSize, filePointer);
}

通常、このコードは高速とは言えませんが、非常に特殊な条件下では非常に遅くなります。ファイルの他の部分で別のマシンでパフォーマンスの低下が発生するか、まったく発生しないため、動作は決定論的ではないようです。ディスク操作がない間、プログラムが完全に読み取りを停止することさえあります。

別の症状は、使用されている RAM のようです。私のプロセスは RAM を一定に保ちますが、システムが使用する RAM が非常に大きくなることがあります。いくつかの RAM ツールを使用した後、Windows マップ ファイルが数 GB に成長することがわかりました。この動作は、プロセスのさまざまな部分でさまざまなマシンで発生するため、ハードウェアにも依存しているようです。

私が知る限り、この問題は SSD には存在しないため、HDD の応答時間と関係があることは間違いありません。

私の推測では、Windows キャッシングはどういうわけか「奇妙」になっていると思います。キャッシュが機能している限り、プログラムは高速です。しかし、キャッシングが失敗すると、動作は「読み取り停止」または「キャッシュ サイズ拡大」のいずれかになり、場合によっては両方になります。私は Windows キャッシュ アルゴリズムの専門家ではないので、説明をいただければ幸いです。また、Windows を C/C++ から外して、キャッシュを操作/停止/強制する方法はありますか。

私はしばらくこの問題を探しているので、すでにいくつかのトリックを試しましたが、うまくいきませんでした:

  • filePointer = fopen(ファイル名, "rbR"); //RAM がいっぱいになるまでキャッシュをいっぱいにする
  • 読み取り/書き込みの大規模なバッファリングにより、2 つが相互に干渉するのを防ぎます

前もって感謝します

4

2 に答える 2

3

アプリケーションが行うことの全体像に応じて、別のアプローチを取ることができます - おそらく次のようなものです:

  1. 入力ファイルから必要な行を決定し、行番号をリストに保存します
  2. 行番号のリストを並べ替える
  3. 入力ファイルを一度順番に読み、必要な行を取り出します (特に大きなギャップがある場合は、次の行を探してそれを取得することをお勧めします)。
  4. 取得している行のリストが十分に小さい場合は、出力前に並べ替えるためにそれらをメモリに保存できます。そうでない場合は、それらをより小さな一時ファイルに貼り付け、そのファイルを現在のアルゴリズムの入力として使用して、最終出力の行を並べ替えます。

これは間違いなくより複雑なアプローチですが、キャッシング サブシステムにとって非常に親切であり、その結果、パフォーマンスが大幅に向上する可能性があります。

于 2012-06-01T17:38:23.550 に答える
3

巨大なファイルへの真のランダム アクセスは、キャッシュ アルゴリズムにとって最悪のケースです。可能な限りキャッシュを無効にすることをお勧めします。

キャッシングには複数のレベルがあります。

  • CRT ライブラリ (f- 関数を使用しているため)
  • OS とファイルシステム
  • おそらくドライブ自体に搭載されています

CRT の f 関数を介した I/O 呼び出しを、Windows API の同等の関数 (CreateFile、ReadFile など) に置き換えると、CRT キャッシュをなくすことができます。また、キャッシュ戦略に影響を与えるランダム アクセスを行うことを OS に警告することもできます。FILE_FLAG_RANDOM_ACCESSや などのオプションを参照してくださいFILE_FLAG_NO_BUFFERING

実験して測定する必要があります。

また、アルゴリズムの仕組みを再検討する必要がある場合もあります。シークは本当にランダムですか? 順序が整うように、おそらくバッチでそれらを並べ替えることはできますか? 一度にファイルの比較的小さな領域へのアクセスを制限できますか? 巨大なファイルを小さなファイルに分割して、一度に 1 つずつ作業できますか? ドライブと特定のファイルの断片化のレベルを確認しましたか?

于 2012-06-01T16:56:30.007 に答える