STLdoc
STLdocumentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
Public Member Functions | Private Member Functions | Static Private Member Functions | Private Attributes | List of all members
Concurrency::combinable< _Ty > Class Template Reference

The combinable<T> object is intended to provide thread-private copies of data, to perform lock-free thread-local sub-computations during parallel algorithms. At the end of the parallel operation, the thread-private sub-computations can then be merged into a final result. This class can be used instead of a shared variable, and can result in a performance improvement if there would otherwise be a lot of contention on that shared variable. More...

#include <ppl.h>

Public Member Functions

 combinable ()
 Constructs a new combinable object. More...
 
template<typename _Function >
 combinable (_Function _FnInitialize)
 Constructs a new combinable object. More...
 
 combinable (const combinable &_Copy)
 Constructs a new combinable object. More...
 
combinableoperator= (const combinable &_Copy)
 Assigns to a combinable object from another combinable object. More...
 
 ~combinable ()
 Destroys a combinable object. More...
 
_Ty & local ()
 Returns a reference to the thread-private sub-computation. More...
 
_Ty & local (bool &_Exists)
 Returns a reference to the thread-private sub-computation. More...
 
void clear ()
 Clears any intermediate computational results from a previous usage. More...
 
template<typename _Function >
_Ty combine (_Function _FnCombine) const
 Computes a final value from the set of thread-local sub-computations by calling the supplied combine functor. More...
 
template<typename _Function >
void combine_each (_Function _FnCombine) const
 Computes a final value from the set of thread-local sub-computations by calling the supplied combine functor once per thread-local sub-computation. The final result is accumulated by the function object. More...
 

Private Member Functions

 __declspec (align(64)) struct _Node
 
void _InitNew ()
 
void _InitCopy (const combinable &_Copy)
 
_Node * _FindLocalItem (unsigned long _Key, size_t *_PIndex)
 
_Node * _AddLocalItem (unsigned long _Key, size_t _Index)
 

Static Private Member Functions

static _Ty _DefaultInit ()
 

Private Attributes

_Node *volatile * _M_buckets
 
size_t _M_size
 
std::tr1::function< _Ty()> _M_fnInitialize
 

Detailed Description

template<typename _Ty>
class Concurrency::combinable< _Ty >

The combinable<T> object is intended to provide thread-private copies of data, to perform lock-free thread-local sub-computations during parallel algorithms. At the end of the parallel operation, the thread-private sub-computations can then be merged into a final result. This class can be used instead of a shared variable, and can result in a performance improvement if there would otherwise be a lot of contention on that shared variable.

Template Parameters
_TyThe data type of the final merged result. The type must have a copy constructor and a default constructor.

For more information, see Parallel Containers and Objects.

Constructor & Destructor Documentation

template<typename _Ty >
Concurrency::combinable< _Ty >::combinable ( )
inline

Constructs a new combinable object.

The first constructor initializes new elements with the default constructor for the type _Ty .

The second constructor initializes new elements using the initialization functor supplied as the _FnInitialize parameter.

The third constructor is the copy constructor.

See also
Parallel Containers and Objects
4234  {
4235  _InitNew();
4236  }
std::tr1::function< _Ty()> _M_fnInitialize
Definition: ppl.h:4530
static _Ty _DefaultInit()
Definition: ppl.h:4215
void _InitNew()
Definition: ppl.h:4471
template<typename _Ty >
template<typename _Function >
Concurrency::combinable< _Ty >::combinable ( _Function  _FnInitialize)
inlineexplicit

Constructs a new combinable object.

Template Parameters
_FunctionThe type of the initialization functor object.
Parameters
_FnInitializeA function which will be called to initialize each new thread-private value of the type _Ty . It must support a function call operator with the signature _Ty ().

The first constructor initializes new elements with the default constructor for the type _Ty .

The second constructor initializes new elements using the initialization functor supplied as the _FnInitialize parameter.

The third constructor is the copy constructor.

See also
Parallel Containers and Objects
4258  : _M_fnInitialize(_FnInitialize)
4259  {
4260  _InitNew();
4261  }
std::tr1::function< _Ty()> _M_fnInitialize
Definition: ppl.h:4530
void _InitNew()
Definition: ppl.h:4471
template<typename _Ty >
Concurrency::combinable< _Ty >::combinable ( const combinable< _Ty > &  _Copy)
inline

Constructs a new combinable object.

Parameters
_CopyAn existing combinable object to be copied into this one.

The first constructor initializes new elements with the default constructor for the type _Ty .

The second constructor initializes new elements using the initialization functor supplied as the _FnInitialize parameter.

The third constructor is the copy constructor.

See also
Parallel Containers and Objects
4278  : _M_size(_Copy._M_size), _M_fnInitialize(_Copy._M_fnInitialize)
4279  {
4280  _InitCopy(_Copy);
4281  }
size_t _M_size
Definition: ppl.h:4529
std::tr1::function< _Ty()> _M_fnInitialize
Definition: ppl.h:4530
void _InitCopy(const combinable &_Copy)
Definition: ppl.h:4478
template<typename _Ty >
Concurrency::combinable< _Ty >::~combinable ( )
inline

Destroys a combinable object.

4309  {
4310  clear();
4311  delete [] _M_buckets;
4312  }
void clear()
Clears any intermediate computational results from a previous usage.
Definition: ppl.h:4372
_Node *volatile * _M_buckets
Definition: ppl.h:4528

Member Function Documentation

template<typename _Ty >
Concurrency::combinable< _Ty >::__declspec ( align(64)  )
inlineprivate
4203  {
4204  unsigned long _M_key;
4205  _Ty _M_value;
4206  _Node* _M_chain;
4207 
4208  _Node(unsigned long _Key, _Ty _InitialValue)
4209  : _M_key(_Key), _M_value(_InitialValue), _M_chain(NULL)
4210  {
4211  }
4212  };
#define NULL
Definition: crtdbg.h:30
template<typename _Ty >
_Node* Concurrency::combinable< _Ty >::_AddLocalItem ( unsigned long  _Key,
size_t  _Index 
)
inlineprivate
4515  {
4516  _Node* _NewNode = new _Node(_Key, _M_fnInitialize());
4517  _Node* _TopNode;
4518  do
4519  {
4520  _TopNode = _M_buckets[_Index];
4521  _NewNode->_M_chain = _TopNode;
4522  } while (_InterlockedCompareExchangePointer(reinterpret_cast<void * volatile *>(&_M_buckets[_Index]), _NewNode, _TopNode) != _TopNode);
4523 
4524  return _NewNode;
4525  }
std::tr1::function< _Ty()> _M_fnInitialize
Definition: ppl.h:4530
_Node *volatile * _M_buckets
Definition: ppl.h:4528
void * _InterlockedCompareExchangePointer(void *volatile *, void *, void *)
template<typename _Ty >
static _Ty Concurrency::combinable< _Ty >::_DefaultInit ( )
inlinestaticprivate
4216  {
4217  return _Ty();
4218  }
template<typename _Ty >
_Node* Concurrency::combinable< _Ty >::_FindLocalItem ( unsigned long  _Key,
size_t _PIndex 
)
inlineprivate
4494  {
4495  _CONCRT_ASSERT(_PIndex != NULL);
4496 
4497  *_PIndex = _Key % _M_size;
4498 
4499  // Search at this index for an existing value.
4500  _Node* _CurrentNode = _M_buckets[*_PIndex];
4501  while (_CurrentNode != NULL)
4502  {
4503  if (_CurrentNode->_M_key == _Key)
4504  {
4505  return _CurrentNode;
4506  }
4507 
4508  _CurrentNode = _CurrentNode->_M_chain;
4509  }
4510 
4511  return NULL;
4512  }
size_t _M_size
Definition: ppl.h:4529
#define _CONCRT_ASSERT(x)
Definition: concrt.h:137
#define NULL
Definition: crtdbg.h:30
_Node *volatile * _M_buckets
Definition: ppl.h:4528
template<typename _Ty >
void Concurrency::combinable< _Ty >::_InitCopy ( const combinable< _Ty > &  _Copy)
inlineprivate
4479  {
4480  _M_buckets = new _Node*[_M_size];
4481  for (size_t _Index = 0; _Index < _M_size; ++_Index)
4482  {
4483  _M_buckets[_Index] = NULL;
4484  for (_Node* _CurrentNode = _Copy._M_buckets[_Index]; _CurrentNode != NULL; _CurrentNode = _CurrentNode->_M_chain)
4485  {
4486  _Node* _NewNode = new _Node(_CurrentNode->_M_key, _CurrentNode->_M_value);
4487  _NewNode->_M_chain = _M_buckets[_Index];
4488  _M_buckets[_Index] = _NewNode;
4489  }
4490  }
4491  }
size_t _M_size
Definition: ppl.h:4529
#define NULL
Definition: crtdbg.h:30
_Node *volatile * _M_buckets
Definition: ppl.h:4528
template<typename _Ty >
void Concurrency::combinable< _Ty >::_InitNew ( )
inlineprivate
4472  {
4474  _M_buckets = new _Node*[_M_size];
4475  memset((void*)_M_buckets, 0, _M_size * sizeof _M_buckets[0]);
4476  }
size_t _M_size
Definition: ppl.h:4529
_CRTIMP2 size_t __cdecl _GetCombinableSize()
_Node *volatile * _M_buckets
Definition: ppl.h:4528
template<typename _Ty >
void Concurrency::combinable< _Ty >::clear ( )
inline

Clears any intermediate computational results from a previous usage.

4373  {
4374  for (size_t _Index = 0; _Index < _M_size; ++_Index)
4375  {
4376  _Node* _CurrentNode = _M_buckets[_Index];
4377  while (_CurrentNode != NULL)
4378  {
4379  _Node* _NextNode = _CurrentNode->_M_chain;
4380  delete _CurrentNode;
4381  _CurrentNode = _NextNode;
4382  }
4383  }
4384  memset((void*)_M_buckets, 0, _M_size * sizeof _M_buckets[0]);
4385  }
size_t _M_size
Definition: ppl.h:4529
#define NULL
Definition: crtdbg.h:30
_Node *volatile * _M_buckets
Definition: ppl.h:4528
template<typename _Ty >
template<typename _Function >
_Ty Concurrency::combinable< _Ty >::combine ( _Function  _FnCombine) const
inline

Computes a final value from the set of thread-local sub-computations by calling the supplied combine functor.

Template Parameters
_FunctionThe type of the function object that will be invoked to combine two thread-local sub-computations.
Parameters
_FnCombineThe functor that is used to combine the sub-computations. Its signature is T (T, T) or T (const T&, const T&), and it must be associative and commutative.
Returns
The final result of combining all the thread-private sub-computations.
See also
Parallel Containers and Objects
4404  {
4405  _Node* _CurrentNode = NULL;
4406  size_t _Index;
4407 
4408  // Look for the first value in the set, and use (a copy of) that as the result.
4409  // This eliminates a single call (of unknown cost) to _M_fnInitialize.
4410  for (_Index = 0; _Index < _M_size; ++_Index)
4411  {
4412  _CurrentNode = _M_buckets[_Index];
4413  if (_CurrentNode != NULL)
4414  {
4415  break;
4416  }
4417  }
4418 
4419  // No values... return the initializer value.
4420  if (_CurrentNode == NULL)
4421  {
4422  return _M_fnInitialize();
4423  }
4424 
4425  // Accumulate the rest of the items in the current bucket.
4426  _Ty _Result = _CurrentNode->_M_value;
4427  for (_CurrentNode = _CurrentNode->_M_chain; _CurrentNode != NULL; _CurrentNode = _CurrentNode->_M_chain)
4428  {
4429  _Result = _FnCombine(_Result, _CurrentNode->_M_value);
4430  }
4431 
4432  // Accumulate values from the rest of the buckets.
4433  _CONCRT_ASSERT(_Index < _M_size);
4434  for (++_Index; _Index < _M_size; ++_Index)
4435  {
4436  for (_CurrentNode = _M_buckets[_Index]; _CurrentNode != NULL; _CurrentNode = _CurrentNode->_M_chain)
4437  {
4438  _Result = _FnCombine(_Result, _CurrentNode->_M_value);
4439  }
4440  }
4441 
4442  return _Result;
4443  }
size_t _M_size
Definition: ppl.h:4529
std::tr1::function< _Ty()> _M_fnInitialize
Definition: ppl.h:4530
#define _CONCRT_ASSERT(x)
Definition: concrt.h:137
#define NULL
Definition: crtdbg.h:30
_Node *volatile * _M_buckets
Definition: ppl.h:4528
template<typename _Ty >
template<typename _Function >
void Concurrency::combinable< _Ty >::combine_each ( _Function  _FnCombine) const
inline

Computes a final value from the set of thread-local sub-computations by calling the supplied combine functor once per thread-local sub-computation. The final result is accumulated by the function object.

Template Parameters
_FunctionThe type of the function object that will be invoked to combine a single thread-local sub-computation.
Parameters
_FnCombineThe functor that is used to combine one sub-computation. Its signature is void (T) or void (const T&), and must be associative and commutative.
See also
Parallel Containers and Objects
4460  {
4461  for (size_t _Index = 0; _Index < _M_size; ++_Index)
4462  {
4463  for (_Node* _CurrentNode = _M_buckets[_Index]; _CurrentNode != NULL; _CurrentNode = _CurrentNode->_M_chain)
4464  {
4465  _FnCombine(_CurrentNode->_M_value);
4466  }
4467  }
4468  }
size_t _M_size
Definition: ppl.h:4529
#define NULL
Definition: crtdbg.h:30
_Node *volatile * _M_buckets
Definition: ppl.h:4528
template<typename _Ty >
_Ty& Concurrency::combinable< _Ty >::local ( )
inline

Returns a reference to the thread-private sub-computation.

Returns
A reference to the thread-private sub-computation.
See also
Parallel Containers and Objects
4323  {
4325  size_t _Index;
4326  _Node* _ExistingNode = _FindLocalItem(_Key, &_Index);
4327  if (_ExistingNode == NULL)
4328  {
4329  _ExistingNode = _AddLocalItem(_Key, _Index);
4330  }
4331 
4332  _CONCRT_ASSERT(_ExistingNode != NULL);
4333  return _ExistingNode->_M_value;
4334  }
#define _CONCRT_ASSERT(x)
Definition: concrt.h:137
_CRTIMP long __cdecl GetCurrentThreadId()
_Node * _FindLocalItem(unsigned long _Key, size_t *_PIndex)
Definition: ppl.h:4493
#define NULL
Definition: crtdbg.h:30
_Node * _AddLocalItem(unsigned long _Key, size_t _Index)
Definition: ppl.h:4514
template<typename _Ty >
_Ty& Concurrency::combinable< _Ty >::local ( bool _Exists)
inline

Returns a reference to the thread-private sub-computation.

Parameters
_ExistsA reference to a boolean. The boolean value referenced by this argument will be set to true if the sub-computation already existed on this thread, and set to false if this was the first sub-computation on this thread.
Returns
A reference to the thread-private sub-computation.
See also
Parallel Containers and Objects
4350  {
4352  size_t _Index;
4353  _Node* _ExistingNode = _FindLocalItem(_Key, &_Index);
4354  if (_ExistingNode == NULL)
4355  {
4356  _Exists = false;
4357  _ExistingNode = _AddLocalItem(_Key, _Index);
4358  }
4359  else
4360  {
4361  _Exists = true;
4362  }
4363 
4364  _CONCRT_ASSERT(_ExistingNode != NULL);
4365  return _ExistingNode->_M_value;
4366  }
#define _CONCRT_ASSERT(x)
Definition: concrt.h:137
_CRTIMP long __cdecl GetCurrentThreadId()
_Node * _FindLocalItem(unsigned long _Key, size_t *_PIndex)
Definition: ppl.h:4493
#define NULL
Definition: crtdbg.h:30
_Node * _AddLocalItem(unsigned long _Key, size_t _Index)
Definition: ppl.h:4514
template<typename _Ty >
combinable& Concurrency::combinable< _Ty >::operator= ( const combinable< _Ty > &  _Copy)
inline

Assigns to a combinable object from another combinable object.

Parameters
_CopyAn existing combinable object to be copied into this one.
Returns
A reference to this combinable object.
4294  {
4295  clear();
4296  delete [] _M_buckets;
4297  _M_fnInitialize = _Copy._M_fnInitialize;
4298  _M_size = _Copy._M_size;
4299  _InitCopy(_Copy);
4300 
4301  return *this;
4302  }
size_t _M_size
Definition: ppl.h:4529
std::tr1::function< _Ty()> _M_fnInitialize
Definition: ppl.h:4530
void clear()
Clears any intermediate computational results from a previous usage.
Definition: ppl.h:4372
void _InitCopy(const combinable &_Copy)
Definition: ppl.h:4478
_Node *volatile * _M_buckets
Definition: ppl.h:4528

Member Data Documentation

template<typename _Ty >
_Node* volatile* Concurrency::combinable< _Ty >::_M_buckets
private
template<typename _Ty >
std::tr1::function<_Ty ()> Concurrency::combinable< _Ty >::_M_fnInitialize
private
template<typename _Ty >
size_t Concurrency::combinable< _Ty >::_M_size
private

The documentation for this class was generated from the following file: