2

Let's say that I have 10 GBs of RAM and unlimited swap.

I want to run 10 jobs in parallel (gnu parallel is an option but not the only one necessarily). These jobs progressively need more and more memory but they start small. These are CPU hungry jobs, each running at 1 core.

For example, assume that each job runs for 10 hours and starts at 500MB of memory and when it finishes it needs 2GBs, memory increasing linearly. So, if we assume that they increase linearly, at 6 hours and 40 minutes these jobs will exceed the 10GBs of ram available.

How can I manage these jobs so that they always run in RAM, pausing the execution of some of them while letting the others run?

Can GNU parallel do this?

2
  • 1
    I'd say no. You'd need an external tool monitoring processes' RAM usage and issuing SIGSTOP/SIGCONT when appropriate (hoping this doesn't interfere with parallel's method of waiting on processes).
    – A.B
    Commented Jun 24, 2020 at 16:13
  • @A.B Thanks. I think at this point I would have to write a job manager for this specific case.
    – orestisf
    Commented Jun 25, 2020 at 8:30

2 Answers 2

3

Things have changed since June.

Git version e81a0eba now has --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.
1
  • Thank you! That's great.
    – orestisf
    Commented Jan 21, 2021 at 14:52
0

No. But you can kill them and retry them:

memeater() {
  # Simple example that eats 10 MB/second up to 1 GB
  perl -e '$|=1;
    print "start @ARGV\n";
    for(1..100) {
      `sleep 0.1`;
      push @a, "a"x10_000_000;
    }
    print "end @ARGV\n";' $@;
}
export -f memeater

# Only start a job if there is 20 GB RAM free.
# Kill the youngest job when there is 10 GB RAM free.
parallel --retries 100 -j0 --delay 0.1 --memfree 20G memeater ::: {1..100}

If you add --lb you can see that some jobs are started but killed before they can end. They will then later be started again - up to 100 times, after which GNU Parallel gives up on that job.

1
  • Thanks, but it is important to not kill the process
    – orestisf
    Commented Jun 29, 2020 at 14:31

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .