1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-04 13:13:25 +03:00

0030618: Modeling Algorithms, BOPTools_Parallel - avoid using map for thread-local contexts without TBB

OSD_Parallel::ToUseOcctThreads() - new flag allowing to use OCCT threads implementation even when compiled with TBB (for testing).
Added new command dparallel for managing default Thread Pool.
OSD_Parallel::For() now avoid creation of universal iterator in simplest case.

BOPTools_Parallel - eliminated redundant typedefs/explicit instantiations of templates.
Added functor using array of per-thread context instead of a map.
This commit is contained in:
kgv
2019-03-29 00:14:36 +03:00
committed by apn
parent aafe169f89
commit fc867b96a5
25 changed files with 416 additions and 489 deletions

View File

@@ -171,6 +171,34 @@ namespace {
}
#endif
static Standard_Boolean OSD_Parallel_ToUseOcctThreads =
#ifdef HAVE_TBB
Standard_False;
#else
Standard_True;
#endif
}
//=======================================================================
//function : ToUseOcctThreads
//purpose :
//=======================================================================
Standard_Boolean OSD_Parallel::ToUseOcctThreads()
{
return OSD_Parallel_ToUseOcctThreads;
}
//=======================================================================
//function : SetUseOcctThreads
//purpose :
//=======================================================================
void OSD_Parallel::SetUseOcctThreads (Standard_Boolean theToUseOcct)
{
#ifdef HAVE_TBB
OSD_Parallel_ToUseOcctThreads = theToUseOcct;
#else
(void )theToUseOcct;
#endif
}
//=======================================================================

View File

@@ -14,6 +14,7 @@
#ifndef OSD_Parallel_HeaderFile
#define OSD_Parallel_HeaderFile
#include <OSD_ThreadPool.hxx>
#include <Standard_Type.hxx>
#include <memory>
#include <type_traits>
@@ -242,6 +243,24 @@ private:
const Functor& myFunctor;
};
//! Wrapper redirecting functor taking element index to functor taking also thread index.
template<class Functor>
class FunctorWrapperForThreadPool
{
public:
FunctorWrapperForThreadPool (const Functor& theFunctor) : myFunctor(theFunctor) {}
void operator() (int theThreadIndex, int theElemIndex) const
{
(void )theThreadIndex;
myFunctor (theElemIndex);
}
private:
FunctorWrapperForThreadPool (const FunctorWrapperForThreadPool&);
void operator= (const FunctorWrapperForThreadPool&);
const Functor& myFunctor;
};
private:
//! Simple primitive for parallelization of "foreach" loops, e.g.:
@@ -250,19 +269,33 @@ private:
//! @endcode
//! Implementation of framework-dependent functionality should be provided by
//! forEach_impl function defined in opencascade::parallel namespace.
//! @param theBegin the first index (incusive)
//! @param theBegin the first index (inclusive)
//! @param theEnd the last index (exclusive)
//! @param theFunctor functor providing an interface "void operator(InputIterator theIter){}"
//! performing task for the specified iterator position
//! @param theNbItems number of items passed by iterator, -1 if unknown
Standard_EXPORT static void forEach (UniversalIterator& theBegin,
UniversalIterator& theEnd,
const FunctorInterface& theFunctor,
Standard_Integer theNbItems);
Standard_EXPORT static void forEachOcct (UniversalIterator& theBegin,
UniversalIterator& theEnd,
const FunctorInterface& theFunctor,
Standard_Integer theNbItems);
//! Same as forEachOcct() but can be implemented using external threads library.
Standard_EXPORT static void forEachExternal (UniversalIterator& theBegin,
UniversalIterator& theEnd,
const FunctorInterface& theFunctor,
Standard_Integer theNbItems);
public: //! @name public methods
//! Returns number of logical proccesrs.
//! Returns TRUE if OCCT threads should be used instead of auxiliary threads library;
//! default value is FALSE if alternative library has been enabled while OCCT building and TRUE otherwise.
Standard_EXPORT static Standard_Boolean ToUseOcctThreads();
//! Sets if OCCT threads should be used instead of auxiliary threads library.
//! Has no effect if OCCT has been built with no auxiliary threads library.
Standard_EXPORT static void SetUseOcctThreads (Standard_Boolean theToUseOcct);
//! Returns number of logical processors.
Standard_EXPORT static Standard_Integer NbLogicalProcessors();
//! Simple primitive for parallelization of "foreach" loops, equivalent to:
@@ -271,7 +304,7 @@ public: //! @name public methods
//! theFunctor(*anIter);
//! }
//! @endcode
//! @param theBegin the first index (incusive)
//! @param theBegin the first index (inclusive)
//! @param theEnd the last index (exclusive)
//! @param theFunctor functor providing an interface "void operator(InputIterator theIter){}"
//! performing task for specified iterator position
@@ -294,7 +327,14 @@ public: //! @name public methods
UniversalIterator aBegin(new IteratorWrapper<InputIterator>(theBegin));
UniversalIterator aEnd (new IteratorWrapper<InputIterator>(theEnd));
FunctorWrapperIter<InputIterator,Functor> aFunctor (theFunctor);
forEach(aBegin, aEnd, aFunctor, theNbItems);
if (ToUseOcctThreads())
{
forEachOcct (aBegin, aEnd, aFunctor, theNbItems);
}
else
{
forEachExternal (aBegin, aEnd, aFunctor, theNbItems);
}
}
}
@@ -304,7 +344,7 @@ public: //! @name public methods
//! theFunctor(anIter);
//! }
//! @endcode
//! @param theBegin the first index (incusive)
//! @param theBegin the first index (inclusive)
//! @param theEnd the last index (exclusive)
//! @param theFunctor functor providing an interface "void operator(int theIndex){}"
//! performing task for specified index
@@ -315,17 +355,25 @@ public: //! @name public methods
const Functor& theFunctor,
const Standard_Boolean isForceSingleThreadExecution = Standard_False)
{
if (isForceSingleThreadExecution || (theEnd - theBegin) == 1)
const Standard_Integer aRange = theEnd - theBegin;
if (isForceSingleThreadExecution || aRange == 1)
{
for (Standard_Integer it (theBegin); it != theEnd; ++it)
theFunctor(it);
}
else if (ToUseOcctThreads())
{
const Handle(OSD_ThreadPool)& aThreadPool = OSD_ThreadPool::DefaultPool();
OSD_ThreadPool::Launcher aPoolLauncher (*aThreadPool, aRange);
FunctorWrapperForThreadPool<Functor> aFunctor (theFunctor);
aPoolLauncher.Perform (theBegin, theEnd, aFunctor);
}
else
{
UniversalIterator aBegin(new IteratorWrapper<Standard_Integer>(theBegin));
UniversalIterator aEnd (new IteratorWrapper<Standard_Integer>(theEnd));
FunctorWrapperInt<Functor> aFunctor (theFunctor);
forEach(aBegin, aEnd, aFunctor, theEnd - theBegin);
forEachExternal (aBegin, aEnd, aFunctor, aRange);
}
}

View File

@@ -27,14 +27,14 @@
#include <tbb/task_scheduler_init.h>
//=======================================================================
//function : forEach
//function : forEachExternal
//purpose :
//=======================================================================
void OSD_Parallel::forEach (UniversalIterator& theBegin,
UniversalIterator& theEnd,
const FunctorInterface& theFunctor,
Standard_Integer theNbItems)
void OSD_Parallel::forEachExternal (UniversalIterator& theBegin,
UniversalIterator& theEnd,
const FunctorInterface& theFunctor,
Standard_Integer theNbItems)
{
try
{

View File

@@ -14,9 +14,6 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
// Version of parallel executor used when TBB is not available
#ifndef HAVE_TBB
#include <OSD_Parallel.hxx>
#include <OSD_ThreadPool.hxx>
@@ -142,13 +139,13 @@ namespace
}
//=======================================================================
//function : forEach
//purpose :
//function : forEachOcct
//purpose :
//=======================================================================
void OSD_Parallel::forEach (UniversalIterator& theBegin,
UniversalIterator& theEnd,
const FunctorInterface& theFunctor,
Standard_Integer theNbItems)
void OSD_Parallel::forEachOcct (UniversalIterator& theBegin,
UniversalIterator& theEnd,
const FunctorInterface& theFunctor,
Standard_Integer theNbItems)
{
const Handle(OSD_ThreadPool)& aThreadPool = OSD_ThreadPool::DefaultPool();
const Standard_Integer aNbThreads = theNbItems != -1 ? Min (theNbItems, aThreadPool->NbDefaultThreadsToLaunch()) : -1;
@@ -156,4 +153,18 @@ void OSD_Parallel::forEach (UniversalIterator& theBegin,
aLauncher.Perform (theBegin, theEnd, theFunctor);
}
// Version of parallel executor used when TBB is not available
#ifndef HAVE_TBB
//=======================================================================
//function : forEachExternal
//purpose :
//=======================================================================
void OSD_Parallel::forEachExternal (UniversalIterator& theBegin,
UniversalIterator& theEnd,
const FunctorInterface& theFunctor,
Standard_Integer theNbItems)
{
forEachOcct (theBegin, theEnd, theFunctor, theNbItems);
}
#endif /* ! HAVE_TBB */

View File

@@ -16,6 +16,7 @@
#include <OSD_ThreadPool.hxx>
#include <OSD.hxx>
#include <OSD_Parallel.hxx>
#include <Standard_Atomic.hxx>
#include <TCollection_AsciiString.hxx>

View File

@@ -18,7 +18,6 @@
#include <NCollection_Array1.hxx>
#include <OSD_Thread.hxx>
#include <OSD_Parallel.hxx>
#include <Standard_Atomic.hxx>
#include <Standard_Condition.hxx>
#include <Standard_Mutex.hxx>