CPLEX usage of RAM when solving continuous models

Xavier Nodet
4 min readFeb 24, 2021

The memory consumption while solving a model with CPLEX (as with any similar solver) can sometimes be an issue. The amount of RAM available in computers increases regularly, but so does the size of the models that our users want to solve. So let’s look at some data about memory usage.

We’ll focus first on continuous problems, and the results here apply to MIP models that can be solved with few nodes. For MIP models that require many nodes, please look at this other post.

I selected two models that solved around in around 10 to 30 seconds to run these experiments. This is enough to show what can happen in various phases of the search.

Here are the statistics for the two models:

Objective sense      : Minimize
Variables : 428032 [Fix: 58909, Box: 369123]
Objective nonzeros : 428032
Linear constraints : 986069 [Equal: 986069]
Nonzeros : 4280320
RHS nonzeros : 0
Variables : Min LB: 0.000000 Max UB: 446730.0
Objective nonzeros : Min : 2.238489e-06 Max : 0.05263158
Linear constraints :
Nonzeros : Min : 1.000000 Max : 1.000000
RHS nonzeros : Min : all zero Max : all zero

and

Objective sense      : Minimize
Variables : 5052622
Objective nonzeros : 5052622
Linear constraints : 212 [Equal: 212]
Nonzeros : 21288118
RHS nonzeros : 212
Variables : Min LB: 0.000000 Max UB: all infinite
Objective nonzeros : Min : 300.0000 Max : 1456.290
Linear constraints :
Nonzeros : Min : 1.000000 Max : 16.00000
RHS nonzeros : Min : 1.000000 Max : 1.000000

These models are certainly not big by any means: we regularly see models that have a few million variables, and a few hundred thousand constraints.

Generally speaking, in this article, the amounts of RAM reported will be the result of running CPLEX on my Mac using /usr/bin/time -l to report the maximum resident set size. This measure is not absolutely consistent from one run to another, but close enough for this purpose.

What we find with these two models is that, to read them, CPLEX used at most 241 million bytes for the first, and 1137 million bytes for the other. And, from now on, I will use ‘MB’ or ‘GB’ where I really mean millions or billions of bytes… So 240 MB and 1.1 GB.

A default solve of these LP models will use CPLEX concurrent LP. When at least 4 cores are available, this combined algorithm uses Primal, Dual and Barrier in parallel, stopping when the fastest one finds the solution. For our two models, the maximum amount of memory used is respectively 2.3 GB and 6.5 GB.

CPLEX has a specific setting that can be used to reduce the usage of RAM. It’s known as emphasis memory. Using this parameter can give you a very nice improvement of the memory consumption. Of course, the performance may suffer: that’s a tradeoff that you’ll have to investigate. With the first model, the amount of RAM decreases from 2.3 GB to 770 MB. And with the second model, it goes from 6.5 GB to 5.0 GB. Quite some gains already.

Given that the default is to run three algorithms in parallel (Primal, Dual and Barrier), it makes sense that running only one of them would reduce the memory consumption. And indeed this is the case. Here are the memory consumptions for respectively Primal, Dual and Barrier :

  • 780 MB, 780 MB, 780 MB for the first model
  • 3.0 GB, 3.0 GB and 3.4 GB for the second model

There are at least two things worth noting: the amount of memory used was similar between the different algorithms, and 2 to 3 times lower than the default. So running a single algorithm when solving an LP can be very interesting if the RAM consumption is a challenge!

On the other hand, when running a single algorithm, adding ‘emphasis memory’ doesn’t bring much change. It’s quite effective on Concurrent Opt, not so much, at least for these models, on each individual algorithm. But your mileage may vary, and you may want to do these experiments on your own models.

One may wonder whether the memory used by Barrier depends on the number of threads that it can use. Remember that, unlike Primal and Dual, Barrier is a parallel algorithm that has a very good speedup with the number of threads. But it turns out that the memory used doesn’t depend on the number of threads. Or, at least, not in a very visible way. Similarly, the crossover phase that is included by default when running barrier doesn’t increase the memory consumption.

The conclusion of this short experiment would be that, on LPs, and therefore on the initial processing of MIPs, emphasis memory helps, and selecting a single algorithms helps even more.

--

--

Xavier Nodet

Customer Advocate for Decision Optimization at IBM