Eigen and multi-threading
Make Eigen run in parallel
Some Eigen's algorithms can exploit the multiple cores present in your hardware. To this end, it is enough to enable OpenMP on your compiler, for instance:
- GCC:
-fopenmp
- ICC:
-openmp
- MSVC: check the respective option in the build properties.
You can control the number of threads that will be used using either the OpenMP API or Eigen's API using the following priority:
OMP_NUM_THREADS=n ./my_program omp_set_num_threads(n); Eigen::setNbThreads(n);
Unless setNbThreads
has been called, Eigen uses the number of threads specified by OpenMP. You can restore this behavior by calling setNbThreads(0);
. You can query the number of threads that will be used with: n = Eigen::nbThreads( );
You can disable Eigen's multi threading at compile time by defining the EIGEN_
Currently, the following algorithms can make use of multi-threading:
- general dense matrix - matrix products
- PartialPivLU
- row-major-sparse * dense vector/matrix products
- ConjugateGradient with
Lower|Upper
as theUpLo
template parameter. - BiCGSTAB with a row-major sparse matrix format.
- LeastSquaresConjugateGradient
Indeed, the principle of hyper-threading is to run multiple threads (in most cases 2) on a single core in an interleaved manner. However, Eigen's matrix-matrix product kernel is fully optimized and already exploits nearly 100% of the CPU capacity. Consequently, there is no room for running multiple such threads on a single core, and the performance would drops significantly because of cache pollution and other sources of overheads. At this stage of reading you're probably wondering why Eigen does not limit itself to the number of physical cores? This is simply because OpenMP does not allow to know the number of physical cores, and thus Eigen will launch as many threads as cores reported by OpenMP.
Using Eigen in a multi-threaded application
In the case your own application is multithreaded, and multiple threads make calls to Eigen, then you have to initialize Eigen by calling the following routine before creating the threads:
#include <Eigen/Core> int main(int argc, char** argv) { Eigen::initParallel(); ... }
In the case your application is parallelized with OpenMP, you might want to disable Eigen's own parallelization as detailed in the previous section.