GNUによって並列に起動されるすべてのプロセスのメモリ使用量を制限できますか?ジョブ数を制限する方法があることを知っていますが、メモリ使用量を事前に簡単に予測できない場合は、このパラメータを調整するのが難しい場合があります。
私の場合は、プロセスメモリに厳しい制限があるHPCでプログラムを実行しています。たとえば、ノードに使用可能なRAMが72 GBの場合、バッチシステムは70 GBを超えるジョブを終了します。また、Exchangeに直接タスクを作成してアーカイブすることはできません。
niceload
プロセスが実行される前に現在のメモリ使用量を確認できるように見えるGNUパラレルパッケージが付属しています。しかし、どのように使用するのかよくわかりません。
答え1
短い答えは次のとおりです。
ulimit -m 1000000
ulimit -v 1000000
これにより、各プロセスは1 GBのRAMに制限されます。
実際、「正しい」方法でメモリを制限することは非常に複雑です。 RAMが1GBだとしましょう。プロセスは10秒ごとに開始され、プロセスごとに1秒あたり1MBを追加します。そのため、140秒後に次の結果が表示されます。
10██▎
20██████▍
30██████████▌
40██████████████▋
50██████████████████▊
60██████████████████████▉
70███████████████████████████
80███████████████████████████████▏
90███████████████████████████████████▎
100██████████████████████████████████████▍
110██████████████████████████████████████████▌
120██████████████████████████████████████████████▋
130██████████████████████████████████████████████████▊
140██████████████████████████████████████████████████████▉
総RAM容量は1050MBなので、何かを削除する必要があります。どの職業が殺すのに適していますか? 140ですか(狂ったと仮定)? 10ですか(実行するのに時間が最も少なくなるからです)?
私の経験によれば、メモリの問題に対処する作業はしばしば非常に予測可能であるか(ビットマップ変換など)、ほとんど予測できません。非常に予測可能なタスクの場合は、事前に計算を実行して実行できるタスクの数を確認できます。
予測できない状況では、システムがメモリを大量に消費するいくつかのタスクを開始し、そのタスクが完了したらシステムにメモリを少なくするより多くのタスクを開始させることが理想的です。しかし、どのタスクが時間がかかるのか、どのタスクが少し時間がかかるのか、どのタスクが時間がかかるのかを事前に知ることはできません。一部のタスクの一般的な寿命は、非常に小さなメモリから長時間実行された後、より大きなメモリに拡張されることです。このような職業と狂った職業を区別することは困難です。
誰かが私に多くのアプリケーションに適した方法でこれを行うためのよく設計された方法を指摘すると、GNU Parallelが拡張される可能性があります。
答え2
2014年からは状況が変わりました。
これでGitバージョンe81a0ebaが利用可能になりました。--memsuspend
--memsuspend size (alpha testing)
Suspend jobs when there is less than 2 * size memory free. The size can be
postfixed with K, M, G, T, P, k, m, g, t, or p which would multiply the size
with 1024, 1048576, 1073741824, 1099511627776, 1125899906842624, 1000,
1000000, 1000000000, 1000000000000, or 1000000000000000, respectively.
If the available memory falls below 2 * size, GNU parallel will suspend some
of the running jobs. If the available memory falls below size, only one job
will be running.
If a single job takes up at most size RAM, all jobs will complete without
running out of memory. If you have swap available, you can usually lower
size to around half the size of a single jobs - with the slight risk of
swapping a little.
Jobs will be resumed when more RAM is available - typically when the oldest
job completes.