Controlling Concurrency

ojAlgo v47.3 was released 2019-08-08. The main new features are:

  • New, long overdue, functionality to help control multithreading
  • Support for (some) Generalised Eigenvalue Problems
  • A bunch of minor changes and improvements. To get a complete list of what’s changed check out the changelog.

Controlling Concurrency

ojAlgo is multithreaded – some operations are automatically divided to run in multiple threads. You don’t have to do anything for this to happen.

ojAlgo senses what hardware you’re running on and adapts to it. By default ojAlgo assumes it is allowed to max out the available hardware. This is something you may want to limit in a production environment.

There are (potentially) 3 thread pools / executor services used by ojAlgo:

  1. All low level math code use the same, ojAlgo-specific, org.ojalgo.concurrent.DaemonPoolExecutor instance. The instance always exists – nothing you can do about that. You can control the core number of threads in the pool, and if various algorithms actually multithread or not. And if they do multithread; then to how many parts to they divide the task. You only control this partially and indirectly. The example code below demonstrates how to do it. Most importantly this involves limiting the OjAlgoUtils.ENVIRONMENT.
  2. The IntegerSolver class (optimisation MIP solver) uses a private ForkJoinPool. This pool is not used for anything else and is only activated if you actually use the IntegerSolver. Its parallelism is derived from OjAlgoUtils.ENVIRONMENT.
  3. It is possible to use streams with various ojAlgo types, and if you do they can optionally be parallel. In that case they would use the ForkJoinPool.commonPool(). Please note that ojAlgo makes no direct/explicit use of this pool, but the default behaviour of any parallel stream is to use the common pool.

Example Code

Console Output

class ControllingConcurrency
ojAlgo
2019-08-07


The 'environment' that ojAlgo detected and adapts to
3GB/16threads HW=12GB/16threads,2xL3:8MB/8threads,8cores:32kB/2threads

Execution time (no configuration): 222.167222ms

The, now limited, environment that ojAlgo will adapt to
3GB/4threads HW=12GB/16threads,2xL3:8MB/8threads,8cores:32kB/2threads
CPU units: 1
CPU cores: 2
CPU threads: 4

Execution time (limited environment): 315.185725ms

Execution time (limited environment and high thresholds): 1384.959443ms

Recommendations

  • Make sure ojAlgo correctly identifies what hardware you running. Print the OjAlgoUtils.ENVIRONMENT to check that.
  • If you need/want to limit the environment ojAlgo will adapt to, then use one of the supplied methods in OjAlgoUtils.
  • Modifying the operations’ concurrency thresholds (as in the above example) is a clumsy way to tamper with a library that tries to be fine-tuned. Try to avoid doing this!

Leave a Reply