2015-12-31 17 views
7

ロードグローバルリデュースという2つの手順に基づいてMPIアプリケーションを検討してください。簡単にするために、ソフトウェアはそのように記述されていますが、まだ多くのことが進行中です。したがって、純粋にMap/Reduce問題ではありません。 負荷ステップの間大規模計算後のC++プログラムのヒープサイズの縮小

、各所与のノード内のすべてのランクがキューイングされ、唯一のランクのノードの全てメモリへのフルアクセスを持つように。この設計の理由は、ロードステージ中に大容量のIOブロックが読み込まれ、メモリ内にロードする必要があります。の前に、ローカル縮退が発生する可能性があります。この結果をと呼びます。という名前の変数myRankVectorです。 変数myRankVectorが取得されると、IOブロックが解放されます。変数myRankVector自体が終了した後にランクが唯一myRankVectorを保持する2〜3 GBに使用する必要があり、その作成中にノードがすべてメモリを使用することができながらので、少ないメモリを使用しています。ノードでglobalReduce段階で

は、ノード内のすべてのランクは、それらに対応するglobalReduceロードしていたと予想されます。

これは私の問題です。私は絶対にメモリリークがないことを保証していますが(私は共有ポインタを使用してプログラムし、私はValgrindなどで二重チェックしました)、私はヒープがデストラクタはIOブロックを解放しました。キューの次のランクがその仕事をするようになると、前のランクと同じように多くのメモリを要求し始めます。もちろん、プログラムはLinuxが "メモリ不足です:xxx(xxxxxxxx)xxxx子を犠牲にする "。これがなぜそのような場合であるかは明らかです。キューの2番目のランクはすべてのメモリを使用したいが、1番目のランクは大きなヒープを残しています。

この質問の文脈を設定した後、手動でC++のヒープサイズを減らして実際に使用されていないメモリを解放する方法がありますか?

ありがとうございました。

+2

そのヒープは次のようになり、大きな計算を行うための子プログラムをexecし/有用ではないかもしれませんが、あなたがフォーク可能性それが終了したときに「本当に解放された」。 –

+4

コードを見る必要があります。問題は、2番目のランクが解放されたメモリを再利用しない理由です。 –

+0

すべてのランクのループ内で、1)ランクベクトルを取得し、2)ランクベクトルにアクセスして別のコアに固定した別のスレッドを起動する、各ノードで1つのプロセスを使用するのはなぜですか?そして、主要なメモリ使用量はすべて同じプロセスにあり、並列性を使用しながら問題を解決します。 –

答えて

1

この質問の文脈を設定した後、手動でC++のヒープサイズを減らして実際に使用されていないメモリを解放する方法はありますか?

これはオペレーティングシステムに依存しますが、おそらくこれは可能ではありません。

ほとんどのオペレーティングシステムでは、1つのプロセスから完全に完了して終了するまで、実行したメモリ割り当てが残ります。

1

ヒープはlinuxでmmapを使用して実装されています。独自のヒープを使用する必要があります。ヒープは処分してmunmapすることができます。

munmapは、必要なスペースを解放します。

boost : poolのコードを見て、基礎となるヒープを個別に管理できるようにします。

私の経験では、stdのコンテナはカスタムアロケータで管理するのが非常に難しいです。

0

このメモリを共有したくない場合でも、共有メモリで問題を解決できますか? "load"フェーズで共有メモリのブロックを割り当て、 "myRankVector"を計算した後で共有メモリのブロックを解除することができます。

(たshmget、にshmat、にshmdt、shmctl(...、IPC_RMIDを参照してください。))

関連する問題