GNU 并行限制内存使用

GNU 并行限制内存使用

是否可以限制GNU并行启动的所有进程的内存使用?我意识到有一些方法可以限制作业数量,但在不容易提前预测内存使用情况的情况下,调整此参数可能会很困难。

在我的特定情况下,我在 HPC 上运行程序,其中进程内存有硬限制。例如,如果节点上有 72GB 可用 RAM,则批处理系统将杀死超过 70GB 的作业。我也无法直接将作业生成到交换并将其保留在那里。

GNU 并行包附带了niceload,它似乎允许在进程运行之前检查当前内存使用情况。但是我不确定如何使用它。

答案1

简短的回答是:

ulimit -m 1000000
ulimit -v 1000000

这会将每个进程限制为 1 GB RAM。

实际上,以“正确”的方式限制内存极其复杂:假设您有 1 GB RAM。每 10 秒启动一个进程,每个进程每秒多使用 1 MB。所以 140 秒后你会得到这样的结果:

10██▎                                                          
20██████▍                                                      
30██████████▌                                                  
40██████████████▋                                              
50██████████████████▊                                          
60██████████████████████▉                                      
70███████████████████████████                                  
80███████████████████████████████▏                             
90███████████████████████████████████▎                         
100██████████████████████████████████████▍                     
110██████████████████████████████████████████▌                 
120██████████████████████████████████████████████▋             
130██████████████████████████████████████████████████▊         
140██████████████████████████████████████████████████████▉     

这总计为 1050 MB RAM,所以现在您需要删除一些东西。杀掉什么职业才是正确的?是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.

相关内容