4

個々のオブジェクトのディスクから170個のファイル(たとえば、テキストファイル)をロードし、常にメモリに保持するアプリケーションがあります。これらのファイルをディスクからロードすると、メモリが1回割り当てられます。したがって、メモリの断片化はありません。また、FastMMを使用して、アプリケーションがメモリリークを起こさないようにします。

アプリケーションは、これらすべてのファイルを相互に比較して、類似点を見つけます。単純化しすぎると、テキスト文字列を比較すると言えますが、文字列間の違いを許容する必要があるため、アルゴリズムははるかに複雑です。各ファイルは約300KBです。メモリ(それを保持するオブジェクト)にロードすると、約0.4MBのRAMが必要になります。したがって、実行中のアプリは約60MBまたはRAM(ワーキングセット)を必要とします。データを約15分間処理します。問題は、4000万を超えるページフォールトを生成することです。

なんで?約2GBの空きRAMがあります。私が知っていることから、ページフォールトは遅いです。彼らは私のプログラムをどれだけ遅くしていますか?これらのページフォールトを減らすためにプログラムを最適化するにはどうすればよいですか?データの局所性と関係があると思います。誰かがこれ(Delphi)のいくつかのサンプルアルゴリズムを知っていますか?

更新:
しかし、ページフォールトの数を見ると(タスクマネージャーの他のアプリケーションは私の近くにありません)、メモリレイアウトを最適化する(ページフォールトを減らす)ことができれば、アプリケーションの速度を上げることができると思います)。


Delphi 7、Win 7 32ビット、RAM 4GB(3GB表示、2GB空き)。

4

3 に答える 3

3

警告 - 私はページ フォールトの問題に対処しているだけです。

よくわかりませんが、メモリ マップ ファイルの使用を検討したことはありますか? このように、Windows はファイル自体を (メインのページング ファイル pagrefile.sys ではなく) ページング ファイルとして使用します。ファイルが読み取り専用の場合、Windows は必要に応じてファイル自体からデータをロードするだけなので、ページング ファイルを介してページをディスクに書き出す必要がないため、ページ フォールトの数は理論的には減少するはずです。

ファイルのページインとページアウトを減らすには、データを一方向に調べて、新しいデータが読み取られるときに古いページを永久に破棄できるようにする必要があります。ここで、ファイルを再度調べてデータをキャッシュするというトレードオフが発生します。キャッシュはどこかに保存する必要があります。

メモリ マップ ファイルは、Windows が .dll および .exe をロードする方法であることに注意してください。私はそれらを使用して、メモリ制限に達することなくギガバイトのファイルをスキャンしました(当時は RAM の GB ではなく MB でした)。

ただし、あなたが説明したデータから、ovverファイルに戻らない機能により、進行中の再ページングの量が削減されることをお勧めします。

于 2010-10-15T11:53:22.743 に答える
1

私のマシンでは、30 分以上の合計 CPU 時間の後に 4M のページ フォールトがあると報告されている開発者スタジオで、ほとんどのページ フォールトが報告されています。半分の時間で 10 倍の量を得ることができます。そして、私のシステムではメモリが不足しています。したがって、40M の障害は多いように思えます。

メモリリークが発生している可能性があります。

ワーキング セットは、アプリケーションで使用されている物理メモリのみです。メモリをリークしてそれに触れないと、ページアウトされます。仮想メモリの使用量 (またはページ ファイルの使用量) が増加することがわかります。これらのページは、ヒープ メモリがヒープをウォークインするときにスワップ インされ、ウィンドウによって再びスワップ アウトされる可能性があります。

大量の RAM があるため、スワップ アウトされたページは他の誰も必要としないため、物理メモリに残ります。(RAM から復元されたページはソフト フォールトとしてカウントされ、ディスクからはハード フォールトとしてカウントされます)

于 2010-10-15T12:57:29.930 に答える
0

指数関数的なサイズ変更システムを使用していますか?

ロード中にメモリのブロックをあまりにも小さな増分で拡大すると、システムから常に大きなブロックが要求され、データがコピーされ、古いブロックが解放される可能性があります (fastmm が非常に大きなブロックを OS から直接 (割り当て解除) すると仮定します)。 )。

おそらく、これにより、OS がアプリのプロセスからメモリを解放してから再度追加するというループが発生し、最初の書き込みでページ フォールトが発生する可能性があります。

また、非常に大きなファイルの Tstringlist.load* メソッドも避けてください。IIRC は、必要なスペースを 2 倍消費します。

于 2010-10-15T18:25:59.230 に答える