2012-06-21 6 views
7

私は、Fortranで書かれた流体の流れと熱伝達の解析プログラムを最適化するために取り組んでいます。私が大規模かつ大規模なメッシュシミュレーションを実行しようとすると、私はメモリ制限の問題に遭遇しています。しかし、メッシュはそれほど大きなものではありません。典型的なCFDコードを実行するには、わずか50万のセルと小さなピーナッツが必要です。私の問題で80 GBのメモリを要求しても、仮想メモリが不十分でクラッシュしています。Fortranアレイのメモリ管理

私は、どのような配列がそのすべてのメモリを突き詰めているのか、いくつか推測しています。特に(28801,345600)に割り当てられています。私の計算で間違っている場合は私を修正しますが、倍精度配列は値ごとに8ビットです。したがって、この配列のサイズは28801 * 345600 * 8 = 79.6 GBになりますか?

ここで、この配列の大半は計算中にゼロになるので、格納する必要はありません。私は、はるかに小さな配列で作業するためにゼロ以外の値を格納するだけのソリューションアルゴリズムを変更することができると思います。しかし、私はサイズを縮小するために正しい配列を探していることを確認したい。最初に、上記の配列サイズを正しく計算しましたか?第二に、実行時にFortranの配列サイズをMBまたはGBで表示させる方法がありますか?最もメモリを消費する配列を印刷するだけでなく、実行時にコードのメモリ要件がどのように変化しているかを確認することに興味があります。

+3

これを実行しているマシンで実際にどのくらいのメモリがありますか?また、あなたの仮定で間違っている* double *精度は8ビットではなく、8ビットです。それはおよそ74.16 GBのデータ(1000ではなく1024の累乗)になります。また、私はあなたが4日分のデータ(345600秒= 60 * 60 * 24 * 4)をやっていると仮定して正しいですか? –

+0

Mike、これはノードごとに最大96 GBのメモリを持つクラスタ上で実行されています要求。バイト対ビットの混乱とそれをクリアするためのおかげで申し訳ありませんが、私は右の野球場にあるので、配列のサイズは間違いなく問題です。 345600はモデルメッシュ内のセル数に関連し、時間とは関係ありません。 – rks171

+0

@ user104629:なぜ80GBのメモリの連続した配列を割り当てることができないのかという理由の1つです。 –

答えて

4

仮想メモリを搭載したシステムでは、メモリ使用量が非常にあいまいに定義されています。大量のメモリ(大容量の仮想メモリのサイズ)を割り当てることができますが、実際にはそのうちのほんの一部しか実際に使用されていません(小さい住宅セットのサイズ - RSS)。

UNIXシステムでは、呼び出しスレッド/プロセス/プロセスの子プロセスが使用しているシステムリソースの量に関する情報を返すgetrusage(2)システムコールを提供します。特に、プロセス開始後に到達したRSSの最大値を提供します。 getrusage(2)を呼び出し、rusage構造体のru_maxrssフィールドの値を返す単純なFortran呼び出し可能ヘルパー関数を書くことができます。

Linuxで動作しており、移植性に気にしない場合は、/proc/self/statusから開いて読むことができます。 - here様々な分野の

... 
VmPeak:  9136 kB 
VmSize:  7896 kB 
VmLck:   0 kB 
VmHWM:  7572 kB 
VmRSS:  6316 kB 
VmData:  5224 kB 
VmStk:  88 kB 
VmExe:  572 kB 
VmLib:  1708 kB 
VmPTE:  20 kB 
... 

説明:これは、とりわけその疑似ファイル単純なテキストは、プロセスの仮想メモリの使用状況に関する統計情報を持つ複数の行が含まれています。あなたはほとんどVmData,、VmHWMおよびVmSizeに興味があります。 を通常のファイルとしてOPEN()で開き、完全にあなたのFortranコードで処理することができます。

ulimit -aulimit -aHで設定されているメモリの制限も参照してください。ハード仮想メモリのサイズ制限を超えている可能性があります。分散リソースマネージャ(SGE/OGE、Torque/PBS、LSFなど)を介してジョブを送信する場合は、ジョブのために十分なメモリを要求していることを確認してください。

+1

クール、アドバイスありがとう。移植性は私の心配ではないので、私はメモリ使用量を見るために/ proc/self/statusルートを使うつもりだと思います。 ulimit -aは仮想メモリが無制限であることを示しました。 DDTとTotalViewを使用して、コードメモリ内のどこを食べているのかを調べることができるという提案もありました。 – rks171

+0

TotalViewにはいくつかの高度なメモリデバッグ機能がありますが、私はそれを広範に使用していません。少なくとも、どのデバッガであれ、メモリエラーが発生した場所を示すことができます。結局、それは記憶枯渇とは違うものになるかもしれません。 –

+0

それはちょうど私の頭を越えました - あなたのクラスタノードはスワップレスですか?はいの場合は、システム全体のメモリが枯渇している可能性があり、Linux OOMキラーが蹴飛ばされている可能性があります。 –