bug #466: better fix for the race condition: this new patch add an initParallel()

function which must be called at the initialization time of any multi-threaded
application calling Eigen from multiple threads.
This commit is contained in:
Gael Guennebaud 2012-06-14 14:24:15 +02:00
parent a3e700db72
commit b9f25ee656
4 changed files with 65 additions and 6 deletions

View File

@ -329,9 +329,9 @@ using std::ptrdiff_t;
#include "src/Core/GeneralProduct.h"
#include "src/Core/TriangularMatrix.h"
#include "src/Core/SelfAdjointView.h"
#include "src/Core/products/GeneralBlockPanelKernel.h"
#include "src/Core/products/Parallelizer.h"
#include "src/Core/products/CoeffBasedProduct.h"
#include "src/Core/products/GeneralBlockPanelKernel.h"
#include "src/Core/products/GeneralMatrixVector.h"
#include "src/Core/products/GeneralMatrixMatrix.h"
#include "src/Core/SolveTriangular.h"

View File

@ -26,7 +26,7 @@
#define EIGEN_GENERAL_BLOCK_PANEL_H
namespace Eigen {
namespace internal {
template<typename _LhsScalar, typename _RhsScalar, bool _ConjLhs=false, bool _ConjRhs=false>
@ -44,8 +44,7 @@ inline void manage_caching_sizes(Action action, std::ptrdiff_t* l1=0, std::ptrdi
{
static std::ptrdiff_t m_l1CacheSize = 0;
static std::ptrdiff_t m_l2CacheSize = 0;
#pragma omp threadprivate(m_l1CacheSize,m_l2CacheSize)
if(m_l1CacheSize==0)
if(m_l2CacheSize==0)
{
m_l1CacheSize = manage_caching_sizes_helper(queryL1CacheSize(),8 * 1024);
m_l2CacheSize = manage_caching_sizes_helper(queryTopLevelCacheSize(),1*1024*1024);

View File

@ -57,12 +57,23 @@ inline void manage_multi_threading(Action action, int* v)
}
}
}
/** Must be call first when calling Eigen from multiple threads */
inline void initParallel()
{
int nbt;
internal::manage_multi_threading(GetAction, &nbt);
std::ptrdiff_t l1, l2;
internal::manage_caching_sizes(GetAction, &l1, &l2);
}
/** \returns the max number of threads reserved for Eigen
* \sa setNbThreads */
inline int nbThreads()
{
int ret;
manage_multi_threading(GetAction, &ret);
internal::manage_multi_threading(GetAction, &ret);
return ret;
}
@ -70,9 +81,11 @@ inline int nbThreads()
* \sa nbThreads */
inline void setNbThreads(int v)
{
manage_multi_threading(SetAction, &v);
internal::manage_multi_threading(SetAction, &v);
}
namespace internal {
template<typename Index> struct GemmParallelInfo
{
GemmParallelInfo() : sync(-1), users(0), rhs_start(0), rhs_length(0) {}
@ -121,6 +134,7 @@ void parallelize_gemm(const Functor& func, Index rows, Index cols, bool transpos
if(threads==1)
return func(0,rows, 0,cols);
Eigen::initParallel();
func.initParallelSession();
if(transpose)

View File

@ -0,0 +1,46 @@
namespace Eigen {
/** \page TopicMultiThreading Eigen and multi-threading
\section TopicMultiThreading_MakingEigenMT 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: \c -fopenmp
* ICC: \c -openmp
* MSVC: check the respective option in the build properties.
You can control the number of thread that will be used using either the OpenMP API or Eiegn's API using the following priority:
\code
OMP_NUM_THREADS=n ./my_program
omp_set_num_threads(n);
Eigen::setNbThreads(n);
\endcode
Unless setNbThreads has been called, Eigen uses the number of threads specified by OpenMP. You can restore this bahavior by calling \code setNbThreads(0); \endcode
You can query the number of threads that will be used with:
\code
n = Eigen::nbThreads(n);
\endcode
You can disable Eigen's multi threading at compile time by defining the EIGEN_DONT_PARALLELIZE preprocessor token.
Currently, the following algorithms can make use of multi-threading:
* general matrix - matrix products
* PartialPivLU
\section TopicMultiThreading_UsingEigenWithMT 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 \b before creating the threads:
\code
#include <Eigen/Core>
int main(int argc, char** argv)
{
Eigen::initParallel();
...
}
\endcode
In the case your application is parallelized with OpenMP, you might want to disable Eigen's own parallization as detailed in the previous section.
*/
}