You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
268 lines
8.2 KiB
C
268 lines
8.2 KiB
C
3 weeks ago
|
/*=========================================================================
|
||
|
|
||
|
Program: Visualization Toolkit
|
||
|
Module: vtkSMPTools.h
|
||
|
|
||
|
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
|
||
|
All rights reserved.
|
||
|
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
|
||
|
|
||
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
||
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||
|
PURPOSE. See the above copyright notice for more information.
|
||
|
|
||
|
=========================================================================*/
|
||
|
/**
|
||
|
* @class vtkSMPTools
|
||
|
* @brief A set of parallel (multi-threaded) utility functions.
|
||
|
*
|
||
|
* vtkSMPTools provides a set of utility functions that can
|
||
|
* be used to parallelize parts of VTK code using multiple threads.
|
||
|
* There are several back-end implementations of parallel functionality
|
||
|
* (currently Sequential, TBB and X-Kaapi) that actual execution is
|
||
|
* delegated to.
|
||
|
*/
|
||
|
|
||
|
#ifndef vtkSMPTools_h
|
||
|
#define vtkSMPTools_h
|
||
|
|
||
|
#include "vtkCommonCoreModule.h" // For export macro
|
||
|
#include "vtkObject.h"
|
||
|
|
||
|
#include "vtkSMPThreadLocal.h" // For Initialized
|
||
|
#include "vtkSMPToolsInternal.h"
|
||
|
|
||
|
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||
|
#ifndef __VTK_WRAP__
|
||
|
namespace vtk
|
||
|
{
|
||
|
namespace detail
|
||
|
{
|
||
|
namespace smp
|
||
|
{
|
||
|
template <typename T>
|
||
|
class vtkSMPTools_Has_Initialize
|
||
|
{
|
||
|
typedef char (&no_type)[1];
|
||
|
typedef char (&yes_type)[2];
|
||
|
template <typename U, void (U::*)()>
|
||
|
struct V
|
||
|
{
|
||
|
};
|
||
|
template <typename U>
|
||
|
static yes_type check(V<U, &U::Initialize>*);
|
||
|
template <typename U>
|
||
|
static no_type check(...);
|
||
|
|
||
|
public:
|
||
|
static bool const value = sizeof(check<T>(nullptr)) == sizeof(yes_type);
|
||
|
};
|
||
|
|
||
|
template <typename T>
|
||
|
class vtkSMPTools_Has_Initialize_const
|
||
|
{
|
||
|
typedef char (&no_type)[1];
|
||
|
typedef char (&yes_type)[2];
|
||
|
template <typename U, void (U::*)() const>
|
||
|
struct V
|
||
|
{
|
||
|
};
|
||
|
template <typename U>
|
||
|
static yes_type check(V<U, &U::Initialize>*);
|
||
|
template <typename U>
|
||
|
static no_type check(...);
|
||
|
|
||
|
public:
|
||
|
static bool const value = sizeof(check<T>(0)) == sizeof(yes_type);
|
||
|
};
|
||
|
|
||
|
template <typename Functor, bool Init>
|
||
|
struct vtkSMPTools_FunctorInternal;
|
||
|
|
||
|
template <typename Functor>
|
||
|
struct vtkSMPTools_FunctorInternal<Functor, false>
|
||
|
{
|
||
|
Functor& F;
|
||
|
vtkSMPTools_FunctorInternal(Functor& f)
|
||
|
: F(f)
|
||
|
{
|
||
|
}
|
||
|
void Execute(vtkIdType first, vtkIdType last) { this->F(first, last); }
|
||
|
void For(vtkIdType first, vtkIdType last, vtkIdType grain)
|
||
|
{
|
||
|
vtk::detail::smp::vtkSMPTools_Impl_For(first, last, grain, *this);
|
||
|
}
|
||
|
vtkSMPTools_FunctorInternal<Functor, false>& operator=(
|
||
|
const vtkSMPTools_FunctorInternal<Functor, false>&);
|
||
|
vtkSMPTools_FunctorInternal<Functor, false>(const vtkSMPTools_FunctorInternal<Functor, false>&);
|
||
|
};
|
||
|
|
||
|
template <typename Functor>
|
||
|
struct vtkSMPTools_FunctorInternal<Functor, true>
|
||
|
{
|
||
|
Functor& F;
|
||
|
vtkSMPThreadLocal<unsigned char> Initialized;
|
||
|
vtkSMPTools_FunctorInternal(Functor& f)
|
||
|
: F(f)
|
||
|
, Initialized(0)
|
||
|
{
|
||
|
}
|
||
|
void Execute(vtkIdType first, vtkIdType last)
|
||
|
{
|
||
|
unsigned char& inited = this->Initialized.Local();
|
||
|
if (!inited)
|
||
|
{
|
||
|
this->F.Initialize();
|
||
|
inited = 1;
|
||
|
}
|
||
|
this->F(first, last);
|
||
|
}
|
||
|
void For(vtkIdType first, vtkIdType last, vtkIdType grain)
|
||
|
{
|
||
|
vtk::detail::smp::vtkSMPTools_Impl_For(first, last, grain, *this);
|
||
|
this->F.Reduce();
|
||
|
}
|
||
|
vtkSMPTools_FunctorInternal<Functor, true>& operator=(
|
||
|
const vtkSMPTools_FunctorInternal<Functor, true>&);
|
||
|
vtkSMPTools_FunctorInternal<Functor, true>(const vtkSMPTools_FunctorInternal<Functor, true>&);
|
||
|
};
|
||
|
|
||
|
template <typename Functor>
|
||
|
class vtkSMPTools_Lookup_For
|
||
|
{
|
||
|
static bool const init = vtkSMPTools_Has_Initialize<Functor>::value;
|
||
|
|
||
|
public:
|
||
|
typedef vtkSMPTools_FunctorInternal<Functor, init> type;
|
||
|
};
|
||
|
|
||
|
template <typename Functor>
|
||
|
class vtkSMPTools_Lookup_For<Functor const>
|
||
|
{
|
||
|
static bool const init = vtkSMPTools_Has_Initialize_const<Functor>::value;
|
||
|
|
||
|
public:
|
||
|
typedef vtkSMPTools_FunctorInternal<Functor const, init> type;
|
||
|
};
|
||
|
} // namespace smp
|
||
|
} // namespace detail
|
||
|
} // namespace vtk
|
||
|
#endif // __VTK_WRAP__
|
||
|
#endif // DOXYGEN_SHOULD_SKIP_THIS
|
||
|
|
||
|
class VTKCOMMONCORE_EXPORT vtkSMPTools
|
||
|
{
|
||
|
public:
|
||
|
//@{
|
||
|
/**
|
||
|
* Execute a for operation in parallel. First and last
|
||
|
* define the range over which to operate (which is defined
|
||
|
* by the operator). The operation executed is defined by
|
||
|
* operator() of the functor object. The grain gives the parallel
|
||
|
* engine a hint about the coarseness over which to parallelize
|
||
|
* the function (as defined by last-first of each execution of
|
||
|
* operator() ).
|
||
|
*/
|
||
|
template <typename Functor>
|
||
|
static void For(vtkIdType first, vtkIdType last, vtkIdType grain, Functor& f)
|
||
|
{
|
||
|
typename vtk::detail::smp::vtkSMPTools_Lookup_For<Functor>::type fi(f);
|
||
|
fi.For(first, last, grain);
|
||
|
}
|
||
|
//@}
|
||
|
|
||
|
//@{
|
||
|
/**
|
||
|
* Execute a for operation in parallel. First and last
|
||
|
* define the range over which to operate (which is defined
|
||
|
* by the operator). The operation executed is defined by
|
||
|
* operator() of the functor object. The grain gives the parallel
|
||
|
* engine a hint about the coarseness over which to parallelize
|
||
|
* the function (as defined by last-first of each execution of
|
||
|
* operator() ).
|
||
|
*/
|
||
|
template <typename Functor>
|
||
|
static void For(vtkIdType first, vtkIdType last, vtkIdType grain, Functor const& f)
|
||
|
{
|
||
|
typename vtk::detail::smp::vtkSMPTools_Lookup_For<Functor const>::type fi(f);
|
||
|
fi.For(first, last, grain);
|
||
|
}
|
||
|
//@}
|
||
|
|
||
|
/**
|
||
|
* Execute a for operation in parallel. First and last
|
||
|
* define the range over which to operate (which is defined
|
||
|
* by the operator). The operation executed is defined by
|
||
|
* operator() of the functor object. The grain gives the parallel
|
||
|
* engine a hint about the coarseness over which to parallelize
|
||
|
* the function (as defined by last-first of each execution of
|
||
|
* operator() ). Uses a default value for the grain.
|
||
|
*/
|
||
|
template <typename Functor>
|
||
|
static void For(vtkIdType first, vtkIdType last, Functor& f)
|
||
|
{
|
||
|
vtkSMPTools::For(first, last, 0, f);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Execute a for operation in parallel. First and last
|
||
|
* define the range over which to operate (which is defined
|
||
|
* by the operator). The operation executed is defined by
|
||
|
* operator() of the functor object. The grain gives the parallel
|
||
|
* engine a hint about the coarseness over which to parallelize
|
||
|
* the function (as defined by last-first of each execution of
|
||
|
* operator() ). Uses a default value for the grain.
|
||
|
*/
|
||
|
template <typename Functor>
|
||
|
static void For(vtkIdType first, vtkIdType last, Functor const& f)
|
||
|
{
|
||
|
vtkSMPTools::For(first, last, 0, f);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Initialize the underlying libraries for execution. This is
|
||
|
* not required as it is automatically called before the first
|
||
|
* execution of any parallel code. However, it can be used to
|
||
|
* control the maximum number of threads used when the back-end
|
||
|
* supports it (currently Simple and TBB only). Make sure to call
|
||
|
* it before any other parallel operation.
|
||
|
* When using Kaapi, use the KAAPI_CPUCOUNT env. variable to control
|
||
|
* the number of threads used in the thread pool.
|
||
|
*/
|
||
|
static void Initialize(int numThreads = 0);
|
||
|
|
||
|
/**
|
||
|
* Get the estimated number of threads being used by the backend.
|
||
|
* This should be used as just an estimate since the number of threads may
|
||
|
* vary dynamically and a particular task may not be executed on all the
|
||
|
* available threads.
|
||
|
*/
|
||
|
static int GetEstimatedNumberOfThreads();
|
||
|
|
||
|
/**
|
||
|
* A convenience method for sorting data. It is a drop in replacement for
|
||
|
* std::sort(). Under the hood different methods are used. For example,
|
||
|
* tbb::parallel_sort is used in TBB.
|
||
|
*/
|
||
|
template <typename RandomAccessIterator>
|
||
|
static void Sort(RandomAccessIterator begin, RandomAccessIterator end)
|
||
|
{
|
||
|
vtk::detail::smp::vtkSMPTools_Impl_Sort(begin, end);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* A convenience method for sorting data. It is a drop in replacement for
|
||
|
* std::sort(). Under the hood different methods are used. For example,
|
||
|
* tbb::parallel_sort is used in TBB. This version of Sort() takes a
|
||
|
* comparison class.
|
||
|
*/
|
||
|
template <typename RandomAccessIterator, typename Compare>
|
||
|
static void Sort(RandomAccessIterator begin, RandomAccessIterator end, Compare comp)
|
||
|
{
|
||
|
vtk::detail::smp::vtkSMPTools_Impl_Sort(begin, end, comp);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
#endif
|
||
|
// VTK-HeaderTest-Exclude: vtkSMPTools.h
|