31 #pragma pack(push,_CRT_PACKING)
32 #pragma push_macro("new")
37 #define _TRACE_LEVEL_INFORMATION 4
51 class structured_task_group;
83 template<
typename _Function>
102 m_pFunction = reinterpret_cast <
TaskProc> (&::Concurrency::details::_UnrealizedChore::_InvokeBridge<task_handle>);
163 template <
class _Function>
283 template<
class _Function>
321 template<
class _Function>
386 template<
class _Function>
425 template<
class _Function>
571 template<
typename _Function>
572 void run(
const _Function& _Func)
612 template<
typename _Function>
651 template<
typename _Function>
694 template<
typename _Function>
755 template<
class _Function>
794 template<
class _Function>
863 template<
typename _Function>
906 template <
typename _Function1,
typename _Function2>
912 _Task_group.
run(_Task_handle1);
943 template <
typename _Function1,
typename _Function2>
983 template <
typename _Function1,
typename _Function2,
typename _Function3>
984 void parallel_invoke(
const _Function1& _Func1,
const _Function2& _Func2,
const _Function3& _Func3)
991 _Task_group.
run(_Task_handle1);
994 _Task_group.
run(_Task_handle2);
1038 template <
typename _Function1,
typename _Function2,
typename _Function3,
typename _Function4>
1039 void parallel_invoke(
const _Function1& _Func1,
const _Function2& _Func2,
const _Function3& _Func3,
const _Function4& _Func4)
1046 _Task_group.
run(_Task_handle1);
1049 _Task_group.
run(_Task_handle2);
1052 _Task_group.
run(_Task_handle3);
1102 template <
typename _Function1,
typename _Function2,
typename _Function3,
typename _Function4,
typename _Function5>
1103 void parallel_invoke(
const _Function1& _Func1,
const _Function2& _Func2,
const _Function3& _Func3,
const _Function4& _Func4,
const _Function5& _Func5)
1110 _Task_group.
run(_Task_handle1);
1113 _Task_group.
run(_Task_handle2);
1116 _Task_group.
run(_Task_handle3);
1119 _Task_group.
run(_Task_handle4);
1175 template <
typename _Function1,
typename _Function2,
typename _Function3,
typename _Function4,
typename _Function5,
1176 typename _Function6>
1177 void parallel_invoke(
const _Function1& _Func1,
const _Function2& _Func2,
const _Function3& _Func3,
const _Function4& _Func4,
const _Function5& _Func5,
1178 const _Function6& _Func6)
1185 _Task_group.
run(_Task_handle1);
1188 _Task_group.
run(_Task_handle2);
1191 _Task_group.
run(_Task_handle3);
1194 _Task_group.
run(_Task_handle4);
1197 _Task_group.
run(_Task_handle5);
1259 template <
typename _Function1,
typename _Function2,
typename _Function3,
typename _Function4,
typename _Function5,
1260 typename _Function6,
typename _Function7>
1261 void parallel_invoke(
const _Function1& _Func1,
const _Function2& _Func2,
const _Function3& _Func3,
const _Function4& _Func4,
const _Function5& _Func5,
1262 const _Function6& _Func6,
const _Function7& _Func7)
1269 _Task_group.
run(_Task_handle1);
1272 _Task_group.
run(_Task_handle2);
1275 _Task_group.
run(_Task_handle3);
1278 _Task_group.
run(_Task_handle4);
1281 _Task_group.
run(_Task_handle5);
1284 _Task_group.
run(_Task_handle6);
1352 template <
typename _Function1,
typename _Function2,
typename _Function3,
typename _Function4,
typename _Function5,
1353 typename _Function6,
typename _Function7,
typename _Function8>
1354 void parallel_invoke(
const _Function1& _Func1,
const _Function2& _Func2,
const _Function3& _Func3,
const _Function4& _Func4,
const _Function5& _Func5,
1355 const _Function6& _Func6,
const _Function7& _Func7,
const _Function8& _Func8)
1362 _Task_group.
run(_Task_handle1);
1365 _Task_group.
run(_Task_handle2);
1368 _Task_group.
run(_Task_handle3);
1371 _Task_group.
run(_Task_handle4);
1374 _Task_group.
run(_Task_handle5);
1377 _Task_group.
run(_Task_handle6);
1380 _Task_group.
run(_Task_handle7);
1454 template <
typename _Function1,
typename _Function2,
typename _Function3,
typename _Function4,
typename _Function5,
1455 typename _Function6,
typename _Function7,
typename _Function8,
typename _Function9>
1456 void parallel_invoke(
const _Function1& _Func1,
const _Function2& _Func2,
const _Function3& _Func3,
const _Function4& _Func4,
const _Function5& _Func5,
1457 const _Function6& _Func6,
const _Function7& _Func7,
const _Function8& _Func8,
const _Function9& _Func9)
1464 _Task_group.
run(_Task_handle1);
1467 _Task_group.
run(_Task_handle2);
1470 _Task_group.
run(_Task_handle3);
1473 _Task_group.
run(_Task_handle4);
1476 _Task_group.
run(_Task_handle5);
1479 _Task_group.
run(_Task_handle6);
1482 _Task_group.
run(_Task_handle7);
1485 _Task_group.
run(_Task_handle8);
1565 template <
typename _Function1,
typename _Function2,
typename _Function3,
typename _Function4,
typename _Function5,
1566 typename _Function6,
typename _Function7,
typename _Function8,
typename _Function9,
typename _Function10>
1567 void parallel_invoke(
const _Function1& _Func1,
const _Function2& _Func2,
const _Function3& _Func3,
const _Function4& _Func4,
const _Function5& _Func5,
1568 const _Function6& _Func6,
const _Function7& _Func7,
const _Function8& _Func8,
const _Function9& _Func9,
const _Function10& _Func10)
1575 _Task_group.
run(_Task_handle1);
1578 _Task_group.
run(_Task_handle2);
1581 _Task_group.
run(_Task_handle3);
1584 _Task_group.
run(_Task_handle4);
1587 _Task_group.
run(_Task_handle5);
1590 _Task_group.
run(_Task_handle6);
1593 _Task_group.
run(_Task_handle7);
1596 _Task_group.
run(_Task_handle8);
1599 _Task_group.
run(_Task_handle9);
1628 template<
class _Type>
1657 template<
class _Type>
1684 if (_Chunk_size == 0)
1686 throw std::invalid_argument(
"_Chunk_size");
1696 template<
class _Type>
1699 static_assert(
sizeof(
_Type) <=
sizeof(_Size_type),
"Potential truncation of _Range_arg");
1700 _Size_type _Num_chunks = (
static_cast<_Size_type
>(_Range_arg) /
_M_chunk_size);
1702 if (_Num_chunks == 0)
1707 return static_cast<_Type>(_Num_chunks);
1748 template<
class _Type>
1768 _M_num_chunks = _Num_chunks;
1769 _M_pChunk_locations =
new location[_Num_chunks];
1777 #pragma warning(push)
1778 #pragma warning(disable: 4180)
1780 #pragma warning(disable: 6263)
1784 template <
typename _Random_iterator,
typename _Index_type,
typename _Function,
bool _Is_iterator>
1788 static void __cdecl
_Invoke(
const _Random_iterator& _First, _Index_type& _Index,
const _Function& _Func)
1790 _Func(_First[_Index]);
1796 template <
typename _Random_iterator,
typename _Index_type,
typename _Function>
1800 static void __cdecl
_Invoke(
const _Random_iterator& _First, _Index_type& _Index,
const _Function& _Func)
1802 _Func(static_cast<_Random_iterator>(_First + _Index));
1808 template<
typename _Index_type>
1814 _Range(_Index_type _Current_iteration, _Index_type _Last_iteration) :
1828 if (_Remaining_iterations > 1)
1831 _M_last_iteration = _M_current_iteration + _Remaining_iterations / 2;
1838 _Helper_range->_M_current_iteration = _M_last_iteration;
1847 _Index_type _Current_iter = _M_current_iteration;
1849 _Helper_range->_M_current_iteration = _Current_iter + 1;
1850 _Helper_range->_M_last_iteration = _M_last_iteration;
1852 _M_last_iteration = _Current_iter + 1;
1858 return (_M_last_iteration - _M_current_iteration);
1899 template<typename _Index_type>
1904 _M_pHelper_range(
NULL), _M_pParent_worker(_PParent_worker), _M_pWorker_range(
NULL), _M_completion_count(0), _M_stop_iterating(0)
1912 if (_M_completion_count != _Tree_Complete)
1915 _Propagate_cancel();
1926 if (_M_completion_count)
1937 _Index_type _Cached_first_iteration = _Helper_range->_M_current_iteration;
1945 _M_pHelper_range = _Helper_range;
1951 while ((_Helper_range->_M_current_iteration == _Cached_first_iteration) && !_M_completion_count)
1953 if ((_M_pWorker_range !=
NULL) && _M_context._IsSynchronouslyBlocked())
1971 if ((_Worker_range !=
NULL) && _M_context._IsSynchronouslyBlocked()
1972 && (_Helper_range->_M_current_iteration == _Cached_first_iteration) && !_M_completion_count)
1976 _M_pHelper_range =
NULL;
1979 _CONCRT_ASSERT(_Helper_range->_M_current_iteration != _Cached_first_iteration);
1998 if (_Helper_range->_M_current_iteration == _Cached_first_iteration)
2019 _InterlockedExchangePointer(reinterpret_cast<void * volatile *>(&_M_pHelper_range),
NULL);
2032 _M_pWorker_range = _Worker_range;
2038 _M_pWorker_range =
NULL;
2039 _Wait_on_intrusive_steal();
2044 return (_M_pHelper_range !=
NULL);
2049 return (_M_completion_count != 0);
2057 _InterlockedExchange(&_M_completion_count, 1);
2063 _M_completion_count = _Tree_Complete;
2068 return _M_beacon._Is_signaled();
2073 return _M_beacon._Confirm_cancel();
2082 if (_M_stop_iterating != 0)
2086 while (_M_stop_iterating != 0)
2100 if (_M_pParent_worker !=
NULL)
2102 _M_pParent_worker->_NotifyCancel();
2107 static const long _Tree_Complete = 2;
2125 _Worker_proxy
const & operator=(_Worker_proxy
const&);
2137 template <
typename _Random_iterator,
typename _Index_type,
typename _Function,
typename _Partitioner,
bool _Is_iterator>
2141 _Parallel_chunk_helper(_Index_type,
const _Random_iterator& _First, _Index_type _First_iteration, _Index_type _Last_iteration,
const _Index_type& _Step,
2143 _M_first(_First), _M_first_iteration(_First_iteration), _M_last_iteration(_Last_iteration), _M_step(_Step), _M_function(_Func),
2144 _M_parent_worker(_Parent_data)
2152 _M_first(_First), _M_first_iteration(_Worker_range._M_current_iteration), _M_last_iteration(_Worker_range._M_last_iteration), _M_step(_Step), _M_function(_Func),
2153 _M_parent_worker(_Parent_data)
2171 if (_M_parent_worker !=
NULL && !_M_parent_worker->_Receive_range(&_Worker_range))
2178 _Index_type _Current_iteration = _Worker_range._M_current_iteration;
2179 _Index_type _Scaled_index = _Current_iteration * _M_step;
2202 _Helper_group.
run(_Helper_task);
2211 for (_Index_type _I = _Current_iteration; _I < _Worker_range._M_last_iteration; (_I++, _Worker_range._M_current_iteration =_I, _Scaled_index += _M_step))
2241 _Helper_group.
run(*_Helper_subtask);
2259 _Helper_group.
wait();
2280 template <
typename _Random_iterator,
typename _Index_type,
typename _Function,
typename _Partitioner,
bool _Is_iterator>
2285 _Index_type _Last_iteration,
const _Index_type& _Step,
const _Function& _Func,
const _Partitioner&) :
2286 _M_first(_First), _M_first_iteration(_First_iteration), _M_last_iteration(_Last_iteration), _M_step(_Step), _M_function(_Func)
2294 _Index_type _Scaled_index = _M_first_iteration * _M_step;
2296 for (_Index_type _I = _M_first_iteration; _I < _M_last_iteration; (_I++, _Scaled_index += _M_step))
2314 template <
typename _Random_iterator,
typename _Index_type,
typename _Function,
bool _Is_iterator>
2320 _Parallel_localized_chunk_helper(_Index_type _Chunk_index,
const _Random_iterator& _First, _Index_type _First_iteration, _Index_type _Last_iteration,
const _Index_type& _Step,
2322 _M_fixed_helper(_Chunk_index, _First, _First_iteration, _Last_iteration, _Step, _Func,
static_partitioner()),
2323 _M_chunk_location(_Part._Get_chunk_location(static_cast<unsigned
int>(_Chunk_index)))
2332 if (_M_chunk_location._Is_system())
2346 #pragma warning(pop)
2348 template <
typename _Worker_
class,
typename _Index_type,
typename Partitioner>
2354 _Task_group.
run(_Chunk_helpers[_I]);
2357 template <
typename _Worker_
class,
typename _Index_type>
2369 template <
typename _Worker_
class,
typename _Random_iterator,
typename _Index_type,
typename _Function,
typename _Partitioner>
2370 void _Parallel_chunk_impl(
const _Random_iterator& _First, _Index_type _Range_arg,
const _Index_type& _Step,
const _Function& _Func, _Partitioner&& _Part)
2375 _Index_type _Num_iterations = (_Step == 1) ? _Range_arg : (((_Range_arg - 1) / _Step) + 1);
2378 _Index_type _Num_chunks = _Part._Get_num_chunks(_Num_iterations);
2387 _Index_type _Iterations_per_chunk = _Num_iterations / _Num_chunks;
2388 _Index_type _Remaining_iterations = _Num_iterations % _Num_chunks;
2392 if (_Iterations_per_chunk == 0)
2394 _Num_chunks = _Remaining_iterations;
2397 _Index_type _Work_size = 0;
2398 _Index_type _Start_iteration = 0;
2402 for (_I = 0; _I < _Num_chunks - 1; _I++)
2404 if (_Remaining_iterations > 0)
2407 _Work_size = _Iterations_per_chunk + 1;
2408 _Remaining_iterations--;
2412 _Work_size = _Iterations_per_chunk;
2416 new(&_Chunk_helpers[_I])
task_handle<_Worker_class>(_Worker_class(_I, _First, _Start_iteration, _Start_iteration + _Work_size, _Step, _Func, std::forward<_Partitioner>(_Part)));
2423 _Start_iteration += _Work_size;
2427 _CONCRT_ASSERT((_Remaining_iterations == 0) || ((_Iterations_per_chunk == 0) && (_Remaining_iterations == 1)));
2428 _Work_size = _Num_iterations - _Start_iteration;
2431 new(&_Chunk_helpers[_I])
task_handle<_Worker_class>(_Worker_class(_I, _First, _Start_iteration, _Start_iteration + _Work_size, _Step, _Func, std::forward<_Partitioner>(_Part)));
2437 template <
typename _Worker_
class,
typename _Random_iterator,
typename _Index_type,
typename _Function>
2438 void _Parallel_chunk_impl(
const _Random_iterator& _First, _Index_type _Range_arg,
const _Index_type& _Step,
const _Function& _Func)
2440 _Parallel_chunk_impl<_Worker_class>(_First, _Range_arg, _Step, _Func,
auto_partitioner());
2444 template <
typename _Index_type,
typename _Diff_type,
typename _Function>
2448 _Parallel_chunk_impl<_Worker_class>(_First, _Range_arg, _Step, _Func, _Part);
2452 template <
typename _Index_type,
typename _Diff_type,
typename _Function>
2456 _Parallel_chunk_impl<_Worker_class>(_First, _Range_arg, _Step, _Func, _Part);
2460 template <
typename _Index_type,
typename _Diff_type,
typename _Function>
2464 _Parallel_chunk_impl<_Worker_class>(_First, _Range_arg, _Step, _Func, _Part);
2469 template <
typename _Index_type,
typename _Diff_type,
typename _Function>
2473 _Parallel_chunk_impl<_Worker_class>(_First, _Range_arg, _Step, _Func, _Part);
2476 template <
typename _Index_type,
typename _Function,
typename _Partitioner>
2482 throw std::invalid_argument(
"_Step");
2486 if (_First >= _Last)
2492 typedef typename std::tr1::conditional<std::tr1::is_same<_Index_type, int>::value,
unsigned int,
2493 typename std::tr1::conditional<std::tr1::is_same<_Index_type, long>::value,
unsigned long,
2494 typename std::tr1::conditional<std::tr1::is_same<_Index_type, long long>::value,
unsigned long long, decltype(_Last - _First)
2499 _Diff_type _Range_size = _Diff_type(_Last) - _Diff_type(_First);
2500 _Diff_type _Diff_step = _Step;
2502 if (_Range_size <= _Diff_step)
2508 _Parallel_for_partitioned_impl<_Index_type, _Diff_type, _Function>(_First, _Range_size, _Step, _Func, std::forward<_Partitioner>(_Part));
2512 template <
typename _Index_type,
typename _Function>
2558 template <
typename _Index_type,
typename _Function,
typename _Partitioner>
2559 void parallel_for(_Index_type _First, _Index_type
_Last, _Index_type _Step,
const _Function& _Func, _Partitioner&& _Part)
2594 template <
typename _Index_type,
typename _Function>
2633 template <
typename _Index_type,
typename _Function>
2636 parallel_for(_First, _Last, _Index_type(1), _Func, _Part);
2672 template <
typename _Index_type,
typename _Function>
2675 parallel_for(_First, _Last, _Index_type(1), _Func, _Part);
2711 template <
typename _Index_type,
typename _Function>
2714 parallel_for(_First, _Last, _Index_type(1), _Func, _Part);
2750 template <
typename _Index_type,
typename _Function>
2753 parallel_for(_First, _Last, _Index_type(1), _Func, _Part);
2766 #pragma warning(push)
2767 #pragma warning(disable: 4180)
2769 template <
typename _Forward_iterator,
typename _Function,
unsigned int _Chunk_size>
2773 typedef typename std::iterator_traits<_Forward_iterator>::value_type
_Value_type;
2774 static const unsigned int _Size = _Chunk_size;
2777 _M_function(_Func), _M_len(0)
2779 static_assert(std::is_lvalue_reference<decltype(*_First)>::value,
"lvalue required for forward iterator operator *");
2781 for (
unsigned int _Index=0; (_Index <
_Size) && (_First != _Last); _Index++)
2783 _M_element[_M_len++] = &(*_First++);
2791 [
this] (
unsigned int _Index)
2793 _M_function(*(_M_element[_Index]));
2801 typename std::iterator_traits<_Forward_iterator>::pointer _M_element[
_Size];
2807 #pragma warning(pop)
2811 template <
typename _Forward_iterator,
typename _Function>
2817 const unsigned int _Chunk_size = 1024;
2824 _Task_group.
run(_Functor);
2827 template <
typename _Forward_iterator,
typename _Function>
2833 if (_First != _Last)
2836 [&_First, &_Last, &_Func, &_Task_group]
2844 template <
typename _Forward_iterator,
typename _Function>
2849 if (_First != _Last)
2859 template <
typename _Random_iterator,
typename _Index_type,
typename _Function>
2864 _Parallel_chunk_impl<_Worker_class>(_First, _Range_arg, _Step, _Func, _Part);
2867 template <
typename _Random_iterator,
typename _Index_type,
typename _Function>
2872 _Parallel_chunk_impl<_Worker_class>(_First, _Range_arg, _Step, _Func, _Part);
2875 template <
typename _Random_iterator,
typename _Index_type,
typename _Function>
2880 _Parallel_chunk_impl<_Worker_class>(_First, _Range_arg, _Step, _Func, _Part);
2883 template <
typename _Random_iterator,
typename _Index_type,
typename _Function>
2888 _Parallel_chunk_impl<_Worker_class>(_First, _Range_arg, _Step, _Func, _Part);
2891 template <
typename _Random_iterator,
typename _Function,
typename _Partitioner>
2892 void _Parallel_for_each_impl(
const _Random_iterator& _First,
const _Random_iterator& _Last,
const _Function& _Func, _Partitioner&& _Part, std::random_access_iterator_tag)
2894 typedef typename std::iterator_traits<_Random_iterator>::difference_type _Index_type;
2897 if (_First >= _Last)
2902 _Index_type _Range_size = _Last - _First;
2904 if (_Range_size == 1)
2910 _Index_type _Step = 1;
2944 template <
typename _Iterator,
typename _Function>
2987 template <
typename _Iterator,
typename _Function,
typename _Partitioner>
2988 void parallel_for_each(_Iterator _First, _Iterator _Last,
const _Function& _Func, _Partitioner&& _Part)
2997 #pragma warning(push)
2998 #pragma warning(disable: 4180)
3039 template<
typename _Forward_iterator>
3041 _Forward_iterator _Begin, _Forward_iterator _End,
const typename std::iterator_traits<_Forward_iterator>::value_type &
_Identity)
3043 return parallel_reduce(_Begin, _End, _Identity, std::plus<
typename std::iterator_traits<_Forward_iterator>::value_type>());
3093 template<
typename _Forward_iterator,
typename _Sym_reduce_fun>
3094 inline typename std::iterator_traits<_Forward_iterator>::value_type
parallel_reduce(_Forward_iterator _Begin, _Forward_iterator _End,
3095 const typename std::iterator_traits<_Forward_iterator>::value_type &
_Identity, _Sym_reduce_fun _Sym_fun)
3097 typedef typename std::remove_cv<typename std::iterator_traits<_Forward_iterator>::value_type>::type _Reduce_type;
3100 [_Sym_fun](_Forward_iterator _Begin, _Forward_iterator _End, _Reduce_type _Init)->_Reduce_type
3102 while (_Begin != _End)
3104 _Init = _Sym_fun(_Init, *_Begin++);
3112 template <
typename _Reduce_type,
typename _Sub_function,
typename _Combinable_type>
3115 template<
typename _Ty,
typename _Sym_fun>
3176 template<
typename _Reduce_type,
typename _Forward_iterator,
typename _Range_reduce_fun,
typename _Sym_reduce_fun>
3178 const _Range_reduce_fun &_Range_fun,
const _Sym_reduce_fun &_Sym_fun)
3180 typedef typename std::iterator_traits<_Forward_iterator>::value_type _Value_type;
3182 static_assert(!std::tr1::is_same<
typename std::iterator_traits<_Forward_iterator>::iterator_category, std::input_iterator_tag>::value
3183 && !std::tr1::is_same<
typename std::iterator_traits<_Forward_iterator>::iterator_category, std::output_iterator_tag>::value,
3184 "iterator can not be input_iterator or output_iterator.");
3189 typename std::iterator_traits<_Forward_iterator>::iterator_category());
3193 template<
typename _Ty,
typename _Sym_fun>
3194 class _Order_combinable
3212 _Item->
_Next = _Next;
3219 new(
reinterpret_cast<_Ty *
>(&
_Value)) _Ty(_Cur);
3233 return new(_Ret)
_Bucket(_Par);
3247 _M_root = _M_root->
_Next;
3248 reinterpret_cast<_Ty &
>(_Cur->
_Value).~_Ty();
3256 _Ty _Ret(reinterpret_cast<_Ty &>(_M_root->
_Value));
3258 _M_root = _M_root->
_Next;
3262 reinterpret_cast<_Ty &
>(_Cur->
_Value).~_Ty();
3265 _Ret = _M_fun(reinterpret_cast <_Ty &> (_Cur->
_Value), _Ret);
3266 _M_root = _M_root->
_Next;
3269 reinterpret_cast<_Ty &
>(_Cur->
_Value).~_Ty();
3283 template <
typename _Forward_iterator,
typename _Function>
3284 typename _Function::_Reduce_type
_Parallel_reduce_impl(_Forward_iterator _First,
const _Forward_iterator& _Last,
const _Function& _Func,
3285 std::forward_iterator_tag)
3289 if (_First != _Last)
3294 return _Func._Combinable._Serial_combine_release();
3298 return _Func._Identity_value;
3302 template<
typename _Forward_iterator,
typename _Functor>
3305 template <
typename _Worker,
typename _Random_iterator,
typename _Function>
3308 template <
typename _Random_iterator,
typename _Function>
3309 typename _Function::_Reduce_type
_Parallel_reduce_impl(_Random_iterator _First, _Random_iterator _Last,
const _Function& _Func,
3310 std::random_access_iterator_tag)
3315 if (_First >= _Last)
3317 return _Func._Identity_value;
3320 else if (_Last - _First <= 1)
3322 _Worker_class(_First, _Last, _Func)();
3323 return _Func._Combinable._Serial_combine_release();
3328 _Parallel_reduce_random_executor<_Worker_class>(_First,
_Last, _Func);
3329 return _Func._Combinable._Serial_combine_release();
3334 template <
typename _Reduce_type,
typename _Sub_function,
typename _Combinable_type>
3335 struct _Reduce_functor_helper
3346 _Sub_fun(_Sub_fun), _Combinable(comb), _Identity_value(_Identity)
3355 template<
typename _Forward_iterator,
typename _Functor>
3356 class _Parallel_reduce_fixed_worker
3361 _M_begin(_Begin), _M_end(_End), _M_fun(_Fun), _M_bucket(_M_fun._Combinable._Unsafe_push_back())
3365 void operator ()()
const
3367 _M_bucket->_Put(_M_fun._Sub_fun(_M_begin, _M_end, _M_fun._Identity_value));
3380 template <
typename _Worker,
typename _Random_iterator,
typename _Function>
3389 size_t _Begin_index = 0;
3390 size_t _Step =
_Size / _Cpu_num;
3391 size_t _NumRemaining =
_Size - _Step * _Cpu_num;
3393 for(
size_t _I = 0; _I < _Cpu_num - 1; _I++)
3395 size_t _Next = _Begin_index + _Step;
3409 _Tg.
run(_Tasks[_I]);
3410 _Begin_index = _Next;
3419 template <
typename _Forward_iterator,
typename _Function,
int _Default_worker_size,
int _Default_chunk_size>
3423 mutable std::auto_ptr<task_handle<_Worker_class>>
_Workers;
3430 while (_Worker_size < _Default_worker_size && _First != _Last)
3433 _Forward_iterator _Head = _First;
3436 for (
size_t _I = 0; _I < _Default_chunk_size && _First !=
_Last; ++_I, ++_First)
3447 _Workers(_Other._Workers), _Worker_size(_Other._Worker_size)
3451 void operator ()()
const
3454 for(
int _I = 0; _I < _Worker_size; _I++)
3456 _Tg.
run(_Workers.get()[_I]);
3465 for (
int _I = 0; _I < _Worker_size; _I++)
3467 _Workers.get()[_I].~task_handle<_Worker_class>();
3474 template <
typename _Forward_iterator,
typename _Function>
3477 const static int _Internal_worker_number = 1024, _Default_chunk_size = 512;
3486 while (_Index < _Internal_worker_number && _First != _Last)
3489 _Forward_iterator _Head = _First;
3492 for (
size_t _I = 0; _I < _Default_chunk_size && _First !=
_Last; ++_I, ++_First)
3500 _Worker_group.
run(_Workers[_Index]);
3505 while (_First != _Last)
3510 _Worker_group.
wait();
3513 #pragma warning(pop)
3518 #pragma warning(push)
3519 #pragma warning(disable: 4180)
3524 template<
typename _Any_input_traits,
typename _Any_output_traits>
3527 template<
typename _Input_iterator,
typename _Output_iterator,
typename _Unary_operator>
3539 template<
typename _Random_input_iterator,
typename _Random_output_iterator,
typename _Unary_operator,
typename _Partitioner>
3541 _Random_output_iterator& _Result,
const _Unary_operator& _Unary_op, _Partitioner&& _Part)
3546 [_Begin, &_Result, &_Unary_op](
size_t _Index)
3548 _Result[_Index] = _Unary_op(_Begin[_Index]);
3550 std::forward<_Partitioner>(_Part));
3551 _Result += _End - _Begin;
3556 template<
typename _Any_input_traits1,
typename _Any_input_traits2,
typename _Any_output_traits>
3560 template<
typename _Input_iterator1,
typename _Input_iterator2,
typename _Output_iterator,
typename _Binary_operator>
3562 _Output_iterator& _Result,
const _Binary_operator& _Binary_op,
const auto_partitioner&)
3573 template<
typename _Random_input_iterator1,
typename _Random_input_iterator2,
typename _Random_output_iterator,
typename _Binary_operator,
typename _Partitioner>
3575 _Random_input_iterator2 _Begin2, _Random_output_iterator& _Result,
const _Binary_operator& _Binary_op, _Partitioner&& _Part)
3577 if (_Begin1 < _End1)
3580 [_Begin1, _Begin2, &_Result, &_Binary_op](
size_t _Index)
3582 _Result[_Index] = _Binary_op(_Begin1[_Index], _Begin2[_Index]);
3584 std::forward<_Partitioner>(_Part));
3585 _Result += _End1 - _Begin1;
3593 template <
typename _Forward_iterator,
typename _Iterator_kind>
3598 typedef typename std::iterator_traits<_Forward_iterator>::value_type
value_type;
3602 static_assert(!std::is_same<_Iterator_kind, std::input_iterator_tag>::value
3603 && !std::is_same<_Iterator_kind, std::output_iterator_tag>::value,
3604 "iterator can not be input_iterator or output_iterator.");
3607 size_t _Populate(_Forward_iterator& _First, _Forward_iterator _Last)
3610 static_assert(std::is_lvalue_reference<decltype(*_First)>::value,
"lvalue required for forward iterator operator *");
3612 for (
size_t _Index=0; (_Index <
_Size) && (_First != _Last); _Index++)
3615 _M_element_array[_Length++] = &(*_First++);
3623 for (
size_t _Index=0; _Index < _Length; _Index++)
3625 _M_element_array[_Index] = &(*_First++);
3629 void _Store(
const value_type& _Elem,
size_t _Index)
const
3631 *(_M_element_array[_Index]) = _Elem;
3634 typename std::iterator_traits<_Forward_iterator>::reference
_Load(
size_t _Index)
const
3636 return *(_M_element_array[_Index]);
3640 typename std::iterator_traits<_Forward_iterator>::pointer _M_element_array[
_Size];
3643 template <
typename _Random_iterator>
3648 typedef typename std::iterator_traits<_Random_iterator>::value_type
value_type;
3654 size_t _Populate(_Random_iterator& _First, _Random_iterator _Last)
3656 typename std::iterator_traits<_Random_iterator>::difference_type _Range_size = _Last - _First;
3657 typename std::iterator_traits<_Random_iterator>::difference_type _Sized =
_Size;
3660 if (_Range_size > _Sized)
3667 _First += _Range_size;
3668 return static_cast<size_t>(_Range_size);
3678 void _Store(
const value_type& _Elem,
size_t _Index)
const
3680 _M_first[_Index] = _Elem;
3683 typename std::iterator_traits<_Random_iterator>::reference
_Load(
size_t _Index)
const
3686 return _M_first[_Index];
3693 template <
typename _Input_iterator1,
typename _Input_iterator2,
typename _Output_iterator,
typename _Binary_operator>
3698 _Output_iterator& _Result,
const _Binary_operator& _Binary_op) :
3699 _M_binary_op(_Binary_op), _M_len(0)
3701 _M_len = _M_input_helper1._Populate(_First1, _Last1);
3702 _M_input_helper2._Populate(_First2, _M_len);
3703 _M_output_helper._Populate(_Result, _M_len);
3710 [
this] (
size_t _Index)
3712 _M_output_helper._Store(_M_binary_op(_M_input_helper1._Load(_Index), _M_input_helper2._Load(_Index)), _Index);
3727 template <
typename _Input_iterator1,
typename _Input_iterator2,
typename _Output_iterator,
typename _Binary_operator>
3729 const _Binary_operator& _Binary_op,
task_group& _Tg)
3738 if (_First1 != _Last1)
3741 [=, &_Result, &_Binary_op, &_Tg]
3748 template <
typename _Input_iterator,
typename _Output_iterator,
typename _Unary_operator>
3753 _M_unary_op(_Unary_op), _M_len(0)
3755 _M_len = _M_input_helper._Populate(_First, _Last);
3756 _M_output_helper._Populate(_Result, _M_len);
3763 [
this] (
size_t _Index)
3765 _M_output_helper._Store(_M_unary_op(_M_input_helper._Load(_Index)), _Index);
3779 template <
typename _Input_iterator,
typename _Output_iterator,
typename _Unary_operator>
3781 const _Unary_operator& _Unary_op,
task_group& _Tg)
3790 if (_First != _Last)
3793 [=, &_Result, &_Unary_op, &_Tg]
3800 template <
typename _Input_iterator,
typename _Output_iterator,
typename _Unary_operator,
typename _Partitioner>
3801 _Output_iterator
_Parallel_transform_unary_impl(_Input_iterator _First, _Input_iterator _Last, _Output_iterator _Result,
const _Unary_operator& _Unary_op, _Partitioner&& _Part)
3803 typedef typename std::iterator_traits<_Input_iterator>::iterator_category _Input_iterator_type;
3804 typedef typename std::iterator_traits<_Output_iterator>::iterator_category _Output_iterator_type;
3806 if (_First != _Last)
3866 template <
typename _Input_iterator1,
typename _Output_iterator,
typename _Unary_operator>
3923 template <
typename _Input_iterator1,
typename _Output_iterator,
typename _Unary_operator>
3980 template <
typename _Input_iterator1,
typename _Output_iterator,
typename _Unary_operator>
4037 template <
typename _Input_iterator1,
typename _Output_iterator,
typename _Unary_operator>
4100 template <
typename _Input_iterator1,
typename _Input_iterator2,
typename _Output_iterator,
typename _Binary_operator,
typename _Partitioner>
4101 _Output_iterator
parallel_transform(_Input_iterator1 _First1, _Input_iterator1 _Last1, _Input_iterator2 _First2,
4102 _Output_iterator _Result,
const _Binary_operator& _Binary_op, _Partitioner&& _Part)
4104 typedef typename std::iterator_traits<_Input_iterator1>::iterator_category _Input_iterator_type1;
4105 typedef typename std::iterator_traits<_Input_iterator2>::iterator_category _Input_iterator_type2;
4106 typedef typename std::iterator_traits<_Output_iterator>::iterator_category _Output_iterator_type;
4108 if (_First1 != _Last1)
4165 template <
typename _Input_iterator1,
typename _Input_iterator2,
typename _Output_iterator,
typename _Binary_operator>
4166 _Output_iterator
parallel_transform(_Input_iterator1 _First1, _Input_iterator1 _Last1, _Input_iterator2 _First2,
4167 _Output_iterator _Result,
const _Binary_operator& _Binary_op)
4172 #pragma warning(pop)
4174 #pragma warning(push)
4176 #pragma warning(disable: 4316)
4192 template<
typename _Ty>
4199 #pragma warning(push)
4200 #pragma warning(disable: 4324)
4204 unsigned long _M_key;
4208 _Node(
unsigned long _Key, _Ty _InitialValue)
4209 : _M_key(_Key), _M_value(_InitialValue), _M_chain(
NULL)
4213 #pragma warning(pop)
4233 : _M_fnInitialize(_DefaultInit)
4256 template <
typename _Function>
4258 : _M_fnInitialize(_FnInitialize)
4278 : _M_size(_Copy._M_size), _M_fnInitialize(_Copy._M_fnInitialize)
4296 delete [] _M_buckets;
4311 delete [] _M_buckets;
4326 _Node* _ExistingNode = _FindLocalItem(_Key, &_Index);
4327 if (_ExistingNode ==
NULL)
4329 _ExistingNode = _AddLocalItem(_Key, _Index);
4333 return _ExistingNode->_M_value;
4353 _Node* _ExistingNode = _FindLocalItem(_Key, &_Index);
4354 if (_ExistingNode ==
NULL)
4357 _ExistingNode = _AddLocalItem(_Key, _Index);
4365 return _ExistingNode->_M_value;
4374 for (
size_t _Index = 0; _Index < _M_size; ++_Index)
4376 _Node* _CurrentNode = _M_buckets[_Index];
4377 while (_CurrentNode !=
NULL)
4379 _Node* _NextNode = _CurrentNode->_M_chain;
4380 delete _CurrentNode;
4381 _CurrentNode = _NextNode;
4384 memset((
void*)_M_buckets, 0, _M_size *
sizeof _M_buckets[0]);
4402 template<
typename _Function>
4405 _Node* _CurrentNode =
NULL;
4410 for (_Index = 0; _Index < _M_size; ++_Index)
4412 _CurrentNode = _M_buckets[_Index];
4413 if (_CurrentNode !=
NULL)
4420 if (_CurrentNode ==
NULL)
4422 return _M_fnInitialize();
4426 _Ty _Result = _CurrentNode->_M_value;
4427 for (_CurrentNode = _CurrentNode->_M_chain; _CurrentNode !=
NULL; _CurrentNode = _CurrentNode->_M_chain)
4429 _Result = _FnCombine(_Result, _CurrentNode->_M_value);
4434 for (++_Index; _Index < _M_size; ++_Index)
4436 for (_CurrentNode = _M_buckets[_Index]; _CurrentNode !=
NULL; _CurrentNode = _CurrentNode->_M_chain)
4438 _Result = _FnCombine(_Result, _CurrentNode->_M_value);
4458 template<
typename _Function>
4461 for (
size_t _Index = 0; _Index < _M_size; ++_Index)
4463 for (_Node* _CurrentNode = _M_buckets[_Index]; _CurrentNode !=
NULL; _CurrentNode = _CurrentNode->_M_chain)
4465 _FnCombine(_CurrentNode->_M_value);
4474 _M_buckets =
new _Node*[_M_size];
4475 memset((
void*)_M_buckets, 0, _M_size *
sizeof _M_buckets[0]);
4480 _M_buckets =
new _Node*[_M_size];
4481 for (
size_t _Index = 0; _Index < _M_size; ++_Index)
4483 _M_buckets[_Index] =
NULL;
4484 for (_Node* _CurrentNode = _Copy.
_M_buckets[_Index]; _CurrentNode !=
NULL; _CurrentNode = _CurrentNode->_M_chain)
4486 _Node* _NewNode =
new _Node(_CurrentNode->_M_key, _CurrentNode->_M_value);
4487 _NewNode->_M_chain = _M_buckets[_Index];
4488 _M_buckets[_Index] = _NewNode;
4497 *_PIndex = _Key % _M_size;
4500 _Node* _CurrentNode = _M_buckets[*_PIndex];
4501 while (_CurrentNode !=
NULL)
4503 if (_CurrentNode->_M_key == _Key)
4505 return _CurrentNode;
4508 _CurrentNode = _CurrentNode->_M_chain;
4516 _Node* _NewNode =
new _Node(_Key, _M_fnInitialize());
4520 _TopNode = _M_buckets[_Index];
4521 _NewNode->_M_chain = _TopNode;
4533 #pragma warning(pop) // C4316
4535 #pragma push_macro("_MAX_NUM_TASKS_PER_CORE")
4536 #pragma push_macro("_FINE_GRAIN_CHUNK_SIZE")
4537 #pragma push_macro("_SORT_MAX_RECURSION_DEPTH")
4554 #define _MAX_NUM_TASKS_PER_CORE 1024
4560 #define _FINE_GRAIN_CHUNK_SIZE 512
4563 #define _SORT_MAX_RECURSION_DEPTH 64
4565 template<
typename _Random_iterator,
typename _Function>
4566 inline size_t _Median_of_three(
const _Random_iterator &_Begin,
size_t _A,
size_t _B,
size_t _C,
const _Function &_Func,
bool &_Potentially_equal)
4568 _Potentially_equal =
false;
4569 if (_Func(_Begin[_A], _Begin[_B]))
4571 if (_Func(_Begin[_A], _Begin[_C]))
4573 return _Func(_Begin[_B], _Begin[_C]) ? _B :
_C;
4582 if (_Func(_Begin[_B], _Begin[_C]))
4584 return _Func(_Begin[_A], _Begin[_C]) ? _A :
_C;
4588 _Potentially_equal =
true;
4594 template<
typename _Random_iterator,
typename _Function>
4595 inline size_t _Median_of_nine(
const _Random_iterator &_Begin,
size_t _Size,
const _Function &_Func,
bool &_Potentially_equal)
4598 size_t _A =
_Median_of_three(_Begin, 0, _Offset, _Offset * 2, _Func, _Potentially_equal),
4599 _B =
_Median_of_three(_Begin, _Offset * 3, _Offset * 4, _Offset * 5, _Func, _Potentially_equal),
4600 _C =
_Median_of_three(_Begin, _Offset * 6, _Offset * 7, _Size - 1, _Func, _Potentially_equal);
4603 if (_Potentially_equal)
4605 _Potentially_equal = !_Func(_Begin[
_C], _Begin[_A]);
4612 template<
typename _Random_iterator,
typename _Function>
4613 inline size_t _Select_median_pivot(
const _Random_iterator &_Begin,
size_t _Size,
const _Function &_Func,
const size_t _Chunk_size,
bool &_Potentially_equal)
4616 if (_Chunk_size <
_FINE_GRAIN_CHUNK_SIZE && _Size <= std::max<size_t>(_Chunk_size * 4, static_cast<size_t>(15)))
4618 bool _Never_care_equal;
4619 return _Median_of_three(_Begin, 0, _Size / 2, _Size - 1, _Func, _Never_care_equal);
4629 template<
typename _Random_iterator,
typename _Random_buffer_iterator,
typename _Function>
4630 size_t _Search_mid_point(
const _Random_iterator &_Begin1,
size_t &_Len1,
const _Random_buffer_iterator &_Begin2,
size_t &_Len2,
const _Function &_Func)
4632 size_t _Len = (_Len1 + _Len2) / 2, _Index1 = 0, _Index2 = 0;
4634 while (_Index1 < _Len1 && _Index2 < _Len2)
4636 size_t _Mid1 = (_Index1 + _Len1) / 2, _Mid2 = (_Index2 + _Len2) / 2;
4637 if (_Func(_Begin1[_Mid1], _Begin2[_Mid2]))
4639 if (_Mid1 + _Mid2 < _Len)
4641 _Index1 = _Mid1 + 1;
4650 if (_Mid1 + _Mid2 < _Len)
4652 _Index2 = _Mid2 + 1;
4661 if (_Index1 == _Len1)
4663 _Len2 = _Len - _Len1;
4667 _Len1 = _Len - _Len2;
4674 template<
typename _Random_iterator,
typename _Random_buffer_iterator,
typename _Random_output_iterator,
typename _Function>
4675 void _Merge_chunks(_Random_iterator _Begin1,
const _Random_iterator &_End1, _Random_buffer_iterator _Begin2,
const _Random_buffer_iterator &_End2,
4676 _Random_output_iterator _Output,
const _Function &_Func)
4678 while (_Begin1 != _End1 && _Begin2 != _End2)
4680 if (_Func(*_Begin1, *_Begin2))
4690 if (_Begin1 != _End1)
4694 else if (_Begin2 != _End2)
4702 template<
typename _Random_iterator,
typename _Random_buffer_iterator,
typename _Random_output_iterator,
typename _Function>
4703 void _Parallel_merge(_Random_iterator _Begin1,
size_t _Len1, _Random_buffer_iterator _Begin2,
size_t _Len2, _Random_output_iterator _Output,
4704 const _Function &_Func,
size_t _Div_num)
4707 if (_Div_num <= 1 || (_Len1 <= 1 && _Len2 <= 1))
4709 _Merge_chunks(_Begin1, _Begin1 + _Len1, _Begin2, _Begin2 + _Len2, _Output, _Func);
4713 size_t _Mid_len1 = _Len1, _Mid_len2 = _Len2;
4719 _Parallel_merge(_Begin1, _Mid_len1, _Begin2, _Mid_len2, _Output, _Func, _Div_num / 2);
4723 _Parallel_merge(_Begin1 + _Mid_len1, _Len1 - _Mid_len1, _Begin2 + _Mid_len2, _Len2 - _Mid_len2, _Output + _Mid, _Func, _Div_num / 2);
4730 template<
typename _Ty,
typename _Function>
4733 return static_cast<size_t>(_Proj_func(_Val) >>
static_cast<int>(8 *
_Radix) & 255);
4737 template<
typename _Random_iterator,
typename _Random_buffer_iterator,
typename _Function>
4745 size_t _Pos[256] = {0};
4747 for (
size_t _I = 0; _I <
_Size; _I++)
4749 ++_Pos[
_Radix_key(_Begin[_I], _Radix, _Proj_func)];
4752 for (
size_t _I = 1; _I < 256; _I++)
4754 _Pos[_I] += _Pos[_I - 1];
4758 for (
size_t _I = _Size - 1; _I != 0; _I--)
4767 template<
typename _Random_iterator,
typename _Random_buffer_iterator,
typename _Function>
4769 size_t _Radix, _Function _Proj_func,
size_t _Deep = 0)
4771 size_t _Cur_radix = 0;
4777 while (_Cur_radix < _Radix)
4783 if (_Cur_radix == _Radix)
4789 if (_Deep + _Radix + 1 & 1)
4793 std::_Move(_Output, _Output + _Size, _Begin);
4804 template<
typename _Random_iterator,
typename _Random_buffer_iterator,
typename _Function>
4806 size_t _Radix, _Function _Proj_func,
const size_t _Chunk_size,
size_t _Deep = 0)
4809 if (_Size <= _Chunk_size || _Radix < 1)
4815 size_t _Buffer_size =
sizeof(
size_t) * 256 * _Threads_num;
4816 size_t _Step = _Size / _Threads_num;
4817 size_t _Remain = _Size % _Threads_num;
4822 memset(_Chunks, 0, _Buffer_size);
4869 size_t _Beg_index, _End_index;
4872 if (_Index < _Remain)
4874 _Beg_index = _Index * (_Step + 1);
4875 _End_index = _Beg_index + (_Step + 1);
4879 _Beg_index = _Remain * (_Step + 1) + (_Index - _Remain) * _Step;
4880 _End_index = _Beg_index + _Step;
4884 while (_Beg_index != _End_index)
4886 ++_Chunks[_Index][
_Radix_key(_Begin[_Beg_index++], _Radix, _Proj_func)];
4890 int _Index = -1,
_Count = 0;
4893 for (
int _I = 0; _I < 256; _I++)
4895 size_t _Last = _I ? _Chunks[_Threads_num - 1][_I - 1] : 0;
4896 _Chunks[0][_I] +=
_Last;
4898 for (
size_t _J = 1; _J < _Threads_num; _J++)
4900 _Chunks[_J][_I] += _Chunks[_J - 1][_I];
4905 if (_Chunks[_Threads_num - 1][_I] - _Last)
4918 size_t _Beg_index, _End_index;
4921 if (_Index < _Remain)
4923 _Beg_index = _Index * (_Step + 1);
4924 _End_index = _Beg_index + (_Step + 1);
4928 _Beg_index = _Remain * (_Step + 1) + (_Index - _Remain) * _Step;
4929 _End_index = _Beg_index + _Step;
4934 if (_Beg_index != _End_index--)
4936 while (_Beg_index != _End_index)
4938 _Output[--_Chunks[_Index][
_Radix_key(_Begin[_End_index], _Radix, _Proj_func)]] =
std::move(_Begin[_End_index]);
4941 _Output[--_Chunks[_Index][
_Radix_key(_Begin[_End_index], _Radix, _Proj_func)]] =
std::move(_Begin[_End_index]);
4948 if (_Index < 256 - 1)
4951 _Begin + _Chunks[0][_Index], _Radix - 1, _Proj_func, _Chunk_size, _Deep + 1);
4956 _Begin + _Chunks[0][_Index], _Radix - 1, _Proj_func, _Chunk_size, _Deep + 1);
4970 template<
typename _Random_iterator,
typename _Random_buffer_iterator,
typename _Function>
4972 _Function _Proj_func,
const size_t _Chunk_size)
4974 typedef typename std::iterator_traits<_Random_iterator>::value_type _Value_type;
4977 typedef typename std::remove_const<typename std::remove_reference<decltype(_Proj_func(*_Begin))>::type>::type _Integer_type;
4981 [=](_Random_iterator _Begin, _Random_iterator _End, _Integer_type _Init) -> _Integer_type
4983 while (_Begin != _End)
4985 _Integer_type _Ret = _Proj_func(*_Begin++);
4993 }, [](
const _Integer_type &a,
const _Integer_type &b) ->
const _Integer_type& {
return (a < b)? b : a;});
4997 while (_Max_val >>= 8)
5005 template<
typename _Random_iterator,
typename _Function>
5010 return std::sort(_Begin, _Begin + _Size, _Func);
5016 bool _Is_three_way_split =
false;
5017 size_t _Mid_index =
_Select_median_pivot(_Begin, _Size, _Func, _Chunk_size, _Is_three_way_split);
5024 size_t _I = 1, _J = _Size - 1;
5030 while (_Func(*_Begin, _Begin[_J]))
5035 while (_Func(_Begin[_I], *_Begin))
5045 if (_Func(_Begin[_K], *_Begin))
5054 while (_Func(*_Begin, _Begin[_K]))
5067 while (_Func(*_Begin, _Begin[_J]))
5073 while (_Func(_Begin[_I], *_Begin))
5094 volatile size_t _Next_div = _Div_num / 2;
5116 template<
typename _Random_iterator,
typename _Random_buffer_iterator,
typename _Function>
5118 int _Div_num,
const size_t _Chunk_size)
5120 static_assert(std::is_same<
typename std::iterator_traits<_Random_iterator>::value_type,
typename std::iterator_traits<_Random_buffer_iterator>::value_type>::value,
5121 "same value type expected");
5123 if (_Div_num <= 1 || _Size <= _Chunk_size)
5130 int _Left_div_turns = 0;
5131 while (_Div_num >>= 1)
5136 if (_Left_div_turns & 1)
5138 std::move(_Begin, _Begin + _Size, _Output);
5148 size_t _Mid = _Size / 2;
5151 auto _Handle =
make_task([&, _Chunk_size]
5161 if (_Is_buffer_swap)
5163 _Parallel_merge(_Output, _Mid, _Output + _Mid, _Size - _Mid, _Begin, _Func, _Div_num);
5167 _Parallel_merge(_Begin, _Mid, _Begin + _Mid, _Size - _Mid, _Output, _Func, _Div_num);
5170 return !_Is_buffer_swap;
5176 #pragma warning (push)
5177 #pragma warning (disable: 4127)
5180 template<
typename _Allocator>
5183 typename _Allocator::pointer _P = _Alloc.allocate(_N);
5187 if (!std::has_trivial_default_constructor<typename _Allocator::value_type>::value)
5189 for (
size_t _I = 0; _I <
_N; _I++)
5192 typename _Allocator::value_type
_T;
5193 _Alloc.construct(_P + _I, std::forward<typename _Allocator::value_type>(_T));
5201 template<
typename _Allocator>
5206 if (!std::has_trivial_destructor<typename _Allocator::value_type>::value)
5208 for (
size_t _I = 0; _I <
_N; _I++)
5210 _Alloc.destroy(_P + _I);
5214 _Alloc.deallocate(_P, _N);
5221 template<
typename _Allocator>
5248 #pragma warning (pop)
5272 template<
typename _Random_iterator>
5273 inline void parallel_sort(
const _Random_iterator &_Begin,
const _Random_iterator &_End)
5275 parallel_sort(_Begin, _End, std::less<
typename std::iterator_traits<_Random_iterator>::value_type>());
5311 template<
typename _Random_iterator,
typename _Function>
5312 inline void parallel_sort(
const _Random_iterator &_Begin,
const _Random_iterator &_End,
const _Function &_Func,
const size_t _Chunk_size = 2048)
5319 size_t _Size = _End - _Begin;
5322 if (_Size <= _Chunk_size || _Core_num < 2)
5356 template<
typename _Random_iterator>
5359 parallel_buffered_sort<std::allocator<typename std::iterator_traits<_Random_iterator>::value_type>>(_Begin, _End,
5360 std::less<typename std::iterator_traits<_Random_iterator>::value_type>());
5392 template<
typename _Allocator,
typename _Random_iterator>
5395 parallel_buffered_sort<_Allocator>(_Begin, _End,
5396 std::less<typename std::iterator_traits<_Random_iterator>::value_type>());
5431 template<
typename _Allocator,
typename _Random_iterator>
5434 parallel_buffered_sort<_Allocator>(_Alloc, _Begin, _End, std::less<typename std::iterator_traits<_Random_iterator>::value_type>());
5474 template<
typename _Random_iterator,
typename _Function>
5475 inline void parallel_buffered_sort(
const _Random_iterator &_Begin,
const _Random_iterator &_End,
const _Function &_Func,
const size_t _Chunk_size = 2048)
5477 parallel_buffered_sort<std::allocator<typename std::iterator_traits<_Random_iterator>::value_type>>(_Begin, _End, _Func, _Chunk_size);
5520 template<
typename _Allocator,
typename _Random_iterator,
typename _Function>
5521 inline void parallel_buffered_sort(
const _Random_iterator &_Begin,
const _Random_iterator &_End,
const _Function &_Func,
const size_t _Chunk_size = 2048)
5524 return parallel_buffered_sort<_Allocator, _Random_iterator, _Function>(_Alloc, _Begin, _End, _Func, _Chunk_size);
5570 template<
typename _Allocator,
typename _Random_iterator,
typename _Function>
5571 inline void parallel_buffered_sort(
const _Allocator& _Alloc,
const _Random_iterator &_Begin,
const _Random_iterator &_End,
const _Function &_Func,
const size_t _Chunk_size = 2048)
5578 size_t _Size = _End - _Begin;
5581 if (_Size <= _Chunk_size || _Core_num < 2)
5585 const static size_t CORE_NUM_MASK = 0x55555555;
5626 _Func, _Core_num & CORE_NUM_MASK | _Core_num << 1 & CORE_NUM_MASK, _Chunk_size);
5631 #pragma warning(push)
5632 #pragma warning (disable: 4127)
5637 template <
typename _DataType>
5648 static_assert(std::is_integral<_DataType>::value,
5649 "Type should be integral to use default radix function. For more information on integral types, please refer to http://msdn.microsoft.com/en-us/library/bb983099.aspx.");
5650 static_assert((
sizeof(_DataType) <=
sizeof(
size_t)),
"Passed Type is bigger than size_t.");
5652 if (std::is_unsigned<_DataType>::value)
5661 return (((
SIZE_MAX/2) + 1) + static_cast<size_t>(val));
5665 #pragma warning (pop)
5692 template<
typename _Random_iterator>
5695 typedef typename std::iterator_traits<_Random_iterator>::value_type _DataType;
5699 parallel_radixsort<std::allocator<_DataType>>(_Begin, _End, _Proj_func, 256 * 256);
5730 template<
typename _Allocator,
typename _Random_iterator>
5734 return parallel_radixsort<_Allocator, _Random_iterator>(_Alloc, _Begin, _End);
5768 template<
typename _Allocator,
typename _Random_iterator>
5769 inline void parallel_radixsort(
const _Allocator& _Alloc,
const _Random_iterator &_Begin,
const _Random_iterator &_End)
5771 typedef typename std::iterator_traits<_Random_iterator>::value_type _DataType;
5775 parallel_radixsort<_Allocator>(_Alloc, _Begin, _End, _Proj_func);
5812 template<
typename _Random_iterator,
typename _Function>
5813 inline void parallel_radixsort(
const _Random_iterator &_Begin,
const _Random_iterator &_End,
const _Function &_Proj_func,
const size_t _Chunk_size = 256 * 256)
5815 parallel_radixsort<std::allocator<typename std::iterator_traits<_Random_iterator>::value_type>>(
5816 _Begin, _End, _Proj_func, _Chunk_size);
5856 template<
typename _Allocator,
typename _Random_iterator,
typename _Function>
5857 inline void parallel_radixsort(
const _Random_iterator &_Begin,
const _Random_iterator &_End,
const _Function &_Proj_func,
const size_t _Chunk_size = 256 * 256)
5860 return parallel_radixsort<_Allocator, _Random_iterator, _Function>(_Alloc, _Begin, _End, _Proj_func, _Chunk_size);
5903 template<
typename _Allocator,
typename _Random_iterator,
typename _Function>
5904 inline void parallel_radixsort(
const _Allocator& _Alloc,
const _Random_iterator &_Begin,
const _Random_iterator &_End,
const _Function &_Proj_func,
const size_t _Chunk_size = 256 * 256)
5911 size_t _Size = _End - _Begin;
5927 #pragma pop_macro("_SORT_MAX_RECURSION_DEPTH")
5928 #pragma pop_macro("_MAX_NUM_TASKS_PER_CORE")
5929 #pragma pop_macro("_FINE_GRAIN_CHUNK_SIZE")
5934 #pragma pop_macro("new")
void _Parallel_for_impl(_Index_type _First, _Index_type _Last, _Index_type _Step, const _Function &_Func, _Partitioner &&_Part)
Definition: ppl.h:2477
_Type _Get_num_chunks(_Type)
Definition: ppl.h:1749
volatile long _M_completion_count
Definition: ppl.h:2119
_Check_return_opt_ _In_ long _Offset
Definition: io.h:334
A cancellation beacon is a flag which can be polled in an inlinable fashion using the is_signaled met...
Definition: concrt.h:5447
void _Wait_on_intrusive_steal()
Definition: ppl.h:2079
void _Parallel_for_each_chunk(_Forward_iterator &_First, const _Forward_iterator &_Last, const _Function &_Func, task_group &_Task_group)
Definition: ppl.h:2812
void _Parallel_quicksort_impl(const _Random_iterator &_Begin, size_t _Size, const _Function &_Func, size_t _Div_num, const size_t _Chunk_size, int _Depth)
Definition: ppl.h:5006
_Iterator_helper()
Definition: ppl.h:3650
size_t _Select_median_pivot(const _Random_iterator &_Begin, size_t _Size, const _Function &_Func, const size_t _Chunk_size, bool &_Potentially_equal)
Definition: ppl.h:4613
::Concurrency::details::_TaskCollection _M_task_collection
Definition: ppl.h:841
Definition: concrt.h:1123
_Ty & local()
Returns a reference to the thread-private sub-computation.
Definition: ppl.h:4322
void _Parallel_chunk_task_group_run(structured_task_group &_Task_group, task_handle< _Worker_class > *_Chunk_helpers, const Partitioner &, _Index_type _I)
Definition: ppl.h:2349
static void __cdecl _Invoke(const _Random_iterator &_First, _Index_type &_Index, const _Function &_Func)
Definition: ppl.h:1788
_CRTIMP _In_ int _Value
Definition: setjmp.h:190
An event type that marks the beginning of a start/end event pair.
Definition: concrt.h:5611
void _Parallel_integer_sort_asc(const _Random_iterator &_Begin, size_t _Size, const _Random_buffer_iterator &_Output, _Function _Proj_func, const size_t _Chunk_size)
Definition: ppl.h:4971
_CRTIMP void _Cancel()
Cancels work on the task collection.
const _Sub_function & _Sub_fun
Definition: ppl.h:3337
bool _Send_range(_Range< _Index_type > *_Worker_range)
Definition: ppl.h:2007
size_t _M_size
Definition: ppl.h:4529
_CRTIMP bool _IsCanceling()
Informs the caller whether or not the task collection is currently in the midst of cancellation...
_Parallel_fixed_chunk_helper< _Random_iterator, _Index_type, _Function, static_partitioner, _Is_iterator > _Base
Definition: ppl.h:2318
Concurrency::details::_TaskCollectionBase * _OwningCollection() const
Definition: concrt.h:4340
The combinable object is intended to provide thread-private copies of data, to perform lock-free t...
Definition: ppl.h:4193
Structured task collections represent groups of work which follow a strictly LIFO ordered paradigm qu...
Definition: concrt.h:4620
unchecked_array_iterator< _Iterator > make_unchecked_array_iterator(_Iterator _Ptr)
Definition: iterator:729
void _Initialize_locations(unsigned int _Num_chunks)
Definition: ppl.h:1766
volatile _Index_type _M_current
Definition: ppl.h:1893
~combinable()
Destroys a combinable object.
Definition: ppl.h:4308
size_t _M_number
Definition: ppl.h:3225
void _Populate(_Forward_iterator &_First, size_t _Length)
Definition: ppl.h:3621
unsigned int _M_len
Definition: ppl.h:2802
std::tr1::function< _Ty()> _M_fnInitialize
Definition: ppl.h:4530
_Bucket * _M_root
Definition: ppl.h:3226
#define _TRACE_LEVEL_INFORMATION
Definition: ppl.h:37
void _NotifyCancel()
Definition: ppl.h:2093
_Worker_proxy * _M_pParent_worker
Definition: ppl.h:2113
Implements busy wait with no backoff
Definition: concrt.h:604
TaskProc m_pFunction
Definition: concrt.h:4313
void run_with_cancellation_token(const _Function &_Func, cancellation_token _Ct)
Executes a function object immediately and synchronously in the context of a given cancellation token...
Definition: ppl.h:864
_CRTIMP _TaskCollectionStatus __stdcall _RunAndWait(_UnrealizedChore *_PChore=NULL)
A cancellation friendly wrapper with which to execute _PChore and then waits for all chores running i...
_CRTIMP bool _IsCanceling()
Informs the caller whether or not the task collection is currently in the midst of a cancellation...
#define _CONCRT_ASSERT(x)
Definition: concrt.h:137
location & _M_chunk_location
Definition: ppl.h:2341
_Parallel_chunk_helper(_Index_type, const _Random_iterator &_First, _Index_type _First_iteration, _Index_type _Last_iteration, const _Index_type &_Step, const _Function &_Func, const _Partitioner &, _Worker_proxy< _Index_type > *const _Parent_data=NULL)
Definition: ppl.h:2141
combinable(const combinable &_Copy)
Constructs a new combinable object.
Definition: ppl.h:4277
_Index_type _Number_of_iterations() const
Definition: ppl.h:1856
task_group_status run_and_wait(const _Function &_Func)
Schedules a task to be run inline on the calling context with the assistance of the structured_task_g...
Definition: ppl.h:426
static _CRTIMP location __cdecl current()
Returns a location object representing the most specific place the calling thread is executing...
location * _M_pChunk_locations
Definition: ppl.h:1764
~_Worker_proxy()
Definition: ppl.h:1909
void _Integer_radix_pass(const _Random_iterator &_Begin, size_t _Size, const _Random_buffer_iterator &_Output, size_t _Radix, _Function _Proj_func)
Definition: ppl.h:4738
task_handle< _Function > make_task(const _Function &_Func)
A factory method for creating a task_handle object.
Definition: ppl.h:164
_W64 unsigned int size_t
Definition: crtdefs.h:496
std::iterator_traits< _Forward_iterator >::value_type parallel_reduce(_Forward_iterator _Begin, _Forward_iterator _End, const typename std::iterator_traits< _Forward_iterator >::value_type &_Identity)
Computes the sum of all elements in a specified range by computing successive partial sums...
Definition: ppl.h:3040
static cancellation_token none()
Returns a cancellation token which can never be subject to cancellation.
Definition: pplcancellation_token.h:628
_Node * _FindLocalItem(unsigned long _Key, size_t *_PIndex)
Definition: ppl.h:4493
_OutIt _Move(_InIt _First, _InIt _Last, _OutIt _Dest, _Nonscalar_ptr_iterator_tag)
Definition: xutility:2416
std::iterator_traits< _Random_iterator >::reference _Load(size_t _Index) const
Definition: ppl.h:3683
void(__cdecl * TaskProc)(void *)
Concurrency::details contains definitions of support routines in the public namespaces and one or mor...
Definition: concrt.h:265
_Bucket * _Next
Definition: ppl.h:3202
void * align(size_t _Bound, size_t _Size, void *&_Ptr, size_t &_Space) _NOEXCEPT
Definition: memory:1951
void operator()() const
Definition: ppl.h:2329
_CRTIMP _In_opt_z_ const wchar_t _In_opt_z_ const wchar_t unsigned int
Definition: crtdefs.h:642
_N
Definition: wchar.h:1269
_CRTIMP2 bool __cdecl is_current_task_group_canceling()
Returns an indication of whether the task group which is currently executing inline on the current co...
_CRTIMP void _Schedule(_UnrealizedChore *_PChore, location *_PLocation)
Schedules a chore that can potentially run in parallel. The chore is pushed onto the associated works...
_Combinable_type & _Combinable
Definition: ppl.h:3340
void _Parallel_merge(_Random_iterator _Begin1, size_t _Len1, _Random_buffer_iterator _Begin2, size_t _Len2, _Random_output_iterator _Output, const _Function &_Func, size_t _Div_num)
Definition: ppl.h:4703
void combine_each(_Function _FnCombine) const
Computes a final value from the set of thread-local sub-computations by calling the supplied combine ...
Definition: ppl.h:4459
_Parallel_chunk_helper(const _Random_iterator &_First, const _Index_type &_Step, const _Function &_Func, const _Range< _Index_type > &_Worker_range, _Worker_proxy< _Index_type > *const _Parent_data=NULL)
Definition: ppl.h:2150
void _IncrementConstructedElemsCount()
Definition: concrt.h:1095
_OutIt move(_InIt _First, _InIt _Last, _OutIt _Dest)
Definition: xutility:2447
location & _Get_chunk_location(unsigned int _ChunkIndex)
Definition: ppl.h:1743
_Bucket(_Bucket *_N)
Definition: ppl.h:3204
void operator()() const
Definition: ppl.h:2291
__declspec(align(64)) struct _Node
Definition: ppl.h:4201
const _Function & _M_function
Definition: ppl.h:2270
_Output_iterator parallel_transform(_Input_iterator1 _First1, _Input_iterator1 _Last1, _Output_iterator _Result, const _Unary_operator&_Unary_op, const auto_partitioner &_Part=auto_partitioner())
Applies a specified function object to each element in a source range, or to a pair of elements from ...
Definition: ppl.h:3867
The Concurrency namespace provides classes and functions that provide access to the Concurrency Runti...
Definition: agents.h:42
void _Parallel_for_each_forward_impl(_Forward_iterator &_First, const _Forward_iterator &_Last, const _Function &_Func, task_group &_Task_group)
Definition: ppl.h:2828
void _Parallel_integer_radix_sort(const _Random_iterator &_Begin, size_t _Size, const _Random_buffer_iterator &_Output, size_t _Radix, _Function _Proj_func, const size_t _Chunk_size, size_t _Deep=0)
Definition: ppl.h:4805
std::iterator_traits< _Forward_iterator >::value_type _Value_type
Definition: ppl.h:2773
void _Integer_radix_sort(const _Random_iterator &_Begin, size_t _Size, const _Random_buffer_iterator &_Output, size_t _Radix, _Function _Proj_func, size_t _Deep=0)
Definition: ppl.h:4768
void _Disable_intrusive_steal()
Definition: ppl.h:2036
~task_handle()
Destroys the task_handle object.
Definition: ppl.h:109
_Random_iterator _M_first
Definition: ppl.h:3690
void interruption_point()
Creates an interruption point for cancellation. If a cancellation is in progress in the context where...
Definition: ppl.h:879
__declspec(property(get=_Get_current_iteration, put=_Set_current_iteration)) _Index_type _M_current_iteration
_ElemType * _InitOnRawMalloca(void *_MallocaRet)
Definition: concrt.h:1085
void clear()
Clears any intermediate computational results from a previous usage.
Definition: ppl.h:4372
_CRTIMP void __cdecl Free(_Pre_maybenull_ _Post_invalid_ void *_PAllocation)
Releases a block of memory previously allocated by the Alloc method to the Concurrency Runtime Cachin...
_CRTIMP2 size_t __cdecl _GetCombinableSize()
void _Construct(_Ty1 *_Ptr, _Ty2 &&_Val)
Definition: xmemory0:37
void parallel_invoke(const _Function1 &_Func1, const _Function2 &_Func2)
Executes the function objects supplied as parameters in parallel, and blocks until they have finished...
Definition: ppl.h:944
task_handle const & operator=(task_handle const &)
_Allocator _M_alloc
Definition: ppl.h:5243
#define NULL
Definition: crtdbg.h:30
_Parallel_reduce_fixed_worker(_Forward_iterator _Begin, _Forward_iterator _End, const _Functor &_Fun)
Definition: ppl.h:3360
std::auto_ptr< task_handle< _Worker_class > > _Workers
Definition: ppl.h:3423
task_group()
Constructs a new task_group object.
Definition: ppl.h:503
void operator()() const
Definition: ppl.h:2163
void _Set_last_iteration(const _Index_type _I)
Definition: ppl.h:1882
_TaskCollectionStatus _Wait()
Waits for all chores running in the _StructuredTaskCollection to finish (normally or abnormally)...
Definition: concrt.h:4727
The static_partitioner class represents a static partitioning of the range iterated over by parallel_...
Definition: ppl.h:1640
void _SetRuntimeOwnsLifetime(bool fValue)
Definition: concrt.h:4347
The simple_partitioner class represents a static partitioning of the range iterated over by parallel_...
Definition: ppl.h:1669
structured_task_group()
Constructs a new structured_task_group object.
Definition: ppl.h:218
size_t _M_size
Definition: ppl.h:5242
void _Set_tree_done()
Definition: ppl.h:2060
void _Set_current_iteration(const _Index_type _I)
Definition: ppl.h:1868
_CRTIMP _TaskCollectionStatus __stdcall _RunAndWait(_UnrealizedChore *_PChore=NULL)
A cancellation friendly wrapper with which to execute _PChore and then waits for all chores running i...
_CRTIMP void _Schedule(_UnrealizedChore *_PChore, location *_PLocation)
Schedules a chore that can potentially run in parallel. The chore is pushed onto the associated works...
_TaskCollectionStatus _Wait()
Waits for all chores running in the _TaskCollection to finish (normally or abnormally). This method encapsulates all the running tasks in an exception handling block, and will re-throw any exceptions that occur in any of it tasks (if those exceptions occur on another thread, they are marshaled from that thread to the thread where the _TaskCollection was created, and re-thrown). After this function returns, the _TaskCollection cannot be used for scheduling further work.
Definition: concrt.h:4930
size_t _Search_mid_point(const _Random_iterator &_Begin1, size_t &_Len1, const _Random_buffer_iterator &_Begin2, size_t &_Len2, const _Function &_Func)
Definition: ppl.h:4630
::Concurrency::details::_Cancellation_beacon _M_beacon
Definition: ppl.h:2116
bool _Parallel_buffered_sort_impl(const _Random_iterator &_Begin, size_t _Size, _Random_buffer_iterator _Output, const _Function &_Func, int _Div_num, const size_t _Chunk_size)
Definition: ppl.h:5117
volatile _Index_type _M_last
Definition: ppl.h:1894
_Bucket * _Unsafe_push_back()
Definition: ppl.h:3276
_Parallel_for_each_helper(_Forward_iterator &_First, const _Forward_iterator &_Last, const _Function &_Func)
Definition: ppl.h:2776
bool _SpinOnce()
Spins for one time quantum,until a maximum spin is reached.
Definition: concrt.h:652
~task_group()
Destroys a task_group object. You are expected to call the either the wait or run_and_wait method on ...
Definition: ppl.h:535
void _Parallel_for_partitioned_impl(_Index_type _First, _Diff_type _Range_arg, _Diff_type _Step, const _Function &_Func, const auto_partitioner &_Part)
Definition: ppl.h:2445
const _Index_type _M_first_iteration
Definition: ppl.h:2308
_Worker_proxy(_Worker_proxy *_PParent_worker=NULL)
Definition: ppl.h:1903
_Ty _Serial_combine_release()
Definition: ppl.h:3254
void _InitCopy(const combinable &_Copy)
Definition: ppl.h:4478
_Range(_Index_type _Current_iteration, _Index_type _Last_iteration)
Definition: ppl.h:1814
void run(const _Function &_Func)
Schedules a task on the task_group object. If a task_handle object is passed as a parameter to run...
Definition: ppl.h:572
~structured_task_group()
Destroys a structured_task_group object. You are expected to call either the wait or run_and_wait met...
Definition: ppl.h:251
void run(task_handle< _Function > &_Task_handle)
Schedules a task on the structured_task_group object. The caller manages the lifetime of the task_han...
Definition: ppl.h:284
#define _malloca(size)
Definition: malloc.h:228
void _Parallel_chunk_impl(const _Random_iterator &_First, _Index_type _Range_arg, const _Index_type &_Step, const _Function &_Func, _Partitioner &&_Part)
Definition: ppl.h:2370
task_group_status run_and_wait(task_handle< _Function > &_Task_handle)
Schedules a task to be run inline on the calling context with the assistance of the structured_task_g...
Definition: ppl.h:387
void _Put(const _Ty &_Cur)
Definition: ppl.h:3217
bool _Is_done()
Definition: ppl.h:2047
_Ty & local(bool &_Exists)
Returns a reference to the thread-private sub-computation.
Definition: ppl.h:4349
void run(task_handle< _Function > &_Task_handle, location &_Placement)
Schedules a task on the task_group object. If a task_handle object is passed as a parameter to run...
Definition: ppl.h:695
void parallel_sort(const _Random_iterator &_Begin, const _Random_iterator &_End)
Arranges the elements in a specified range into a nondescending order, or according to an ordering cr...
Definition: ppl.h:5273
std::iterator_traits< _Forward_iterator >::value_type value_type
Definition: ppl.h:3598
_Reduce_functor_helper(const _Reduce_type &_Identity, const _Sub_function &_Sub_fun, _Combinable_type &&comb)
Definition: ppl.h:3345
int _Worker_size
Definition: ppl.h:3424
_CRTIMP void __cdecl _Trace_ppl_function(const GUID &_Guid, unsigned char _Level, ConcRT_EventType _Type)
void _Parallel_reduce_random_executor(_Random_iterator _Begin, _Random_iterator _End, const _Function &_Fun)
Definition: ppl.h:3381
void _Parallel_for_each_partitioned_impl(const _Random_iterator &_First, _Index_type _Range_arg, _Index_type _Step, const _Function &_Func, const auto_partitioner &_Part)
Definition: ppl.h:2860
const _Random_iterator & _M_first
Definition: ppl.h:2304
~auto_partitioner()
Destroys a auto_partitioner object.
Definition: ppl.h:1626
const _Index_type & _M_step
Definition: ppl.h:2305
_Bucket * _Construct(_Bucket *_Par=0)
Definition: ppl.h:3230
size_t _GetAllocationSize() const
Definition: concrt.h:1127
The auto_partitioner class represents the default method parallel_for, parallel_for_each and parallel...
Definition: ppl.h:1613
iterator_traits< _Iter >::iterator_category _Iter_cat(const _Iter &)
Definition: xutility:404
affinity_partitioner()
Constructs an affinity_partitioner object.
Definition: ppl.h:1730
static _CRTIMP void __cdecl _Yield()
void parallel_for_each(const extent< _Rank > &_Compute_domain, const _Kernel_type &_Kernel)
Invokes a parallel computation of a kernel function over a compute domain on an accelerator_view. The accelerator_view is determined from the arrays and/or array_views captured by the kernel function, or if no accelerator_view can be derived, the default is chosen.
Definition: amp.h:6988
void parallel_for(_Index_type _First, _Index_type _Last, _Index_type _Step, const _Function &_Func, _Partitioner &&_Part)
parallel_for iterates over a range of indices and executes a user-supplied function at each iteration...
Definition: ppl.h:2559
~_AllocatedBufferHolder()
Definition: ppl.h:5231
void _Enable_intrusive_steal(_Range< _Index_type > *_Worker_range)
Definition: ppl.h:2030
auto_partitioner()
Constructs a auto_partitioner object.
Definition: ppl.h:1620
#define _FINE_GRAIN_CHUNK_SIZE
Definition: ppl.h:4560
void _Store(const value_type &_Elem, size_t _Index) const
Definition: ppl.h:3678
#define _SORT_MAX_RECURSION_DEPTH
Definition: ppl.h:4563
An event type that marks the beginning of a start/end event pair.
Definition: concrt.h:5606
void _Propagate_cancel()
Definition: ppl.h:2098
void _Parallel_for_each_impl(_Forward_iterator _First, const _Forward_iterator &_Last, const _Function &_Func, const auto_partitioner &, std::forward_iterator_tag)
Definition: ppl.h:2845
_Node *volatile * _M_buckets
Definition: ppl.h:4528
structured_task_group(cancellation_token _CancellationToken)
Constructs a new structured_task_group object.
Definition: ppl.h:235
_CRTIMP void *__cdecl Alloc(size_t _NumBytes)
Allocates a block of memory of the size specified from the Concurrency Runtime Caching Suballocator...
_In_ wchar_t _C
Definition: wchar.h:1295
task_group_status run_and_wait(const _Function &_Func)
Schedules a task to be run inline on the calling context with the assistance of the task_group object...
Definition: ppl.h:795
_Base _M_fixed_helper
Definition: ppl.h:2342
bool _GetRuntimeOwnsLifetime() const
Definition: concrt.h:4354
_Parallel_reduce_forward_executor_helper(const _Parallel_reduce_forward_executor_helper &_Other)
Definition: ppl.h:3446
_Allocator::pointer _M_buffer
Definition: ppl.h:5244
size_t _Median_of_nine(const _Random_iterator &_Begin, size_t _Size, const _Function &_Func, bool &_Potentially_equal)
Definition: ppl.h:4595
static _Ty _DefaultInit()
Definition: ppl.h:4215
void parallel_radixsort(const _Random_iterator &_Begin, const _Random_iterator &_End)
Arranges elements in a specified range into an non descending order using a radix sorting algorithm...
Definition: ppl.h:5693
#define false
Definition: stdbool.h:11
_Allocator::pointer _Construct_buffer(size_t _N, _Allocator &_Alloc)
Definition: ppl.h:5181
Definition: concrt.h:4319
const _Index_type _M_last_iteration
Definition: ppl.h:2273
unsigned long long _Size_type
Definition: ppl.h:1672
The structured_task_group class represents a highly structured collection of parallel work...
Definition: ppl.h:204
combinable & operator=(const combinable &_Copy)
Assigns to a combinable object from another combinable object.
Definition: ppl.h:4293
void * _InterlockedCompareExchangePointer(void *volatile *, void *, void *)
const _Functor & _M_fun
Definition: ppl.h:3371
combinable(_Function _FnInitialize)
Constructs a new combinable object.
Definition: ppl.h:4257
const _Reduce_type & _Identity_value
Definition: ppl.h:3338
task_group_status wait()
Waits until all work on the structured_task_group has completed or is canceled.
Definition: ppl.h:348
_CRTIMP void _CheckTaskCollection()
_Range< _Index_type > *volatile _M_pWorker_range
Definition: ppl.h:2122
void _Parallel_invoke_impl(const _Function1 &_Func1, const _Function2 &_Func2)
Definition: ppl.h:907
_Parallel_localized_chunk_helper(_Index_type _Chunk_index, const _Random_iterator &_First, _Index_type _First_iteration, _Index_type _Last_iteration, const _Index_type &_Step, const _Function &_Func, affinity_partitioner &_Part)
Definition: ppl.h:2320
Task collections represent groups of work which step outside the strict structuring of the _Structure...
Definition: concrt.h:4825
_Function _M_function
Definition: ppl.h:136
~simple_partitioner()
Destroys a simple_partitioner object.
Definition: ppl.h:1694
_Size_type _M_chunk_size
Definition: ppl.h:1712
size_t _Radix_key(const _Ty &_Val, size_t _Radix, _Function _Proj_func)
Definition: ppl.h:4731
The task_group class represents a collection of parallel work which can be waited on or canceled...
Definition: ppl.h:489
_In_ wctype_t _Type
Definition: ctype.h:205
An abstraction of a physical location on hardware.
Definition: concrt.h:1902
const _Forward_iterator _M_end
Definition: ppl.h:3372
void run(const _Function &_Func, location &_Placement)
Schedules a task on the task_group object. If a task_handle object is passed as a parameter to run...
Definition: ppl.h:613
void _Insert(_Bucket *_Item)
Definition: ppl.h:3209
task_group(cancellation_token _CancellationToken)
Constructs a new task_group object.
Definition: ppl.h:519
bool is_canceling()
Informs the caller whether or not the task group is currently in the midst of a cancellation. This does not necessarily indicate that the cancel method was called on the structured_task_group object (although such certainly qualifies this method to return true). It may be the case that the structured_task_group object is executing inline and a task group further up in the work tree was canceled. In cases such as these where the runtime can determine ahead of time that cancellation will flow through this structured_task_group object, true will be returned as well.
Definition: ppl.h:462
size_t _Populate(_Random_iterator &_First, _Random_iterator _Last)
Definition: ppl.h:3654
unsigned int _M_num_chunks
Definition: ppl.h:1761
void operator()() const
The function call operator that the runtime invokes to perform the work of the task handle...
Definition: ppl.h:125
void _Store(const value_type &_Elem, size_t _Index) const
Definition: ppl.h:3629
void _Send_range(_Range< _Index_type > *_Helper_range)
Definition: ppl.h:1822
_Type _Get_num_chunks(_Type) const
Definition: ppl.h:1629
std::iterator_traits< _Forward_iterator >::reference _Load(size_t _Index) const
Definition: ppl.h:3634
#define _MAX_NUM_TASKS_PER_CORE
Definition: ppl.h:4554
void cancel()
Makes a best effort attempt to cancel the sub-tree of work rooted at this task group. Every task scheduled on the task group will get canceled transitively if possible.
Definition: ppl.h:811
void swap(array< _Ty, _Size > &_Left, array< _Ty, _Size > &_Right) _NOEXCEPT_OP(_NOEXCEPT_OP(_Left.swap(_Right)))
Definition: array:429
_ElemType * _AddRawMallocaNode(void *_MallocaRet)
Definition: concrt.h:1147
void _Set_done()
Definition: ppl.h:2052
bool _Receive_range(_Range< _Index_type > *_Helper_range)
Definition: ppl.h:1923
bool _Verify_beacon_cancellation()
Definition: ppl.h:2071
~_Parallel_reduce_forward_executor_helper()
Definition: ppl.h:3461
#define _T(x)
Definition: tchar.h:2498
void _Steal_range(_Range< _Index_type > *_Helper_range)
Definition: ppl.h:1842
task_group_status
Describes the execution status of a task_group or structured_task_group object. A value of this type ...
Definition: pplinterface.h:114
void _Destroy_buffer(typename _Allocator::pointer _P, size_t _N, _Allocator &_Alloc)
Definition: ppl.h:5202
_Reduce_type _Reduce_type
Definition: ppl.h:3342
size_t _Median_of_three(const _Random_iterator &_Begin, size_t _A, size_t _B, size_t _C, const _Function &_Func, bool &_Potentially_equal)
Definition: ppl.h:4566
_Allocator::pointer _Get_buffer()
Definition: ppl.h:5236
_Parallel_reduce_forward_executor_helper(_Forward_iterator &_First, _Forward_iterator _Last, const _Function &_Func)
Definition: ppl.h:3426
#define _CRTIMP2
Definition: crtdefs.h:126
void run(task_handle< _Function > &_Task_handle)
Schedules a task on the task_group object. If a task_handle object is passed as a parameter to run...
Definition: ppl.h:652
void operator()() const
Definition: ppl.h:2787
task_group_status run_and_wait(task_handle< _Function > &_Task_handle)
Schedules a task to be run inline on the calling context with the assistance of the task_group object...
Definition: ppl.h:756
simple_partitioner(_Size_type _Chunk_size)
Constructs a simple_partitioner object.
Definition: ppl.h:1682
_Order_combinable(const _Sym_fun &_Fun)
Definition: ppl.h:3236
_Type _Get_num_chunks(_Type) const
Definition: ppl.h:1658
bool _Is_helper_registered()
Definition: ppl.h:2042
long __cdecl _InterlockedDecrement(long volatile *)
const _Sym_fun & _M_fun
Definition: ppl.h:3224
static_partitioner()
Constructs a static_partitioner object.
Definition: ppl.h:1647
_Diff _Count
Definition: algorithm:1941
const _Index_type _M_last_iteration
Definition: ppl.h:2309
_Worker_proxy< _Index_type > *const _M_parent_worker
Definition: ppl.h:2275
void _Merge_chunks(_Random_iterator _Begin1, const _Random_iterator &_End1, _Random_buffer_iterator _Begin2, const _Random_buffer_iterator &_End2, _Random_output_iterator _Output, const _Function &_Func)
Definition: ppl.h:4675
::Concurrency::details::_Context _M_context
Definition: ppl.h:2117
std::iterator_traits< _Random_iterator >::value_type value_type
Definition: ppl.h:3648
void _Populate(_Random_iterator &_First, size_t _Length)
Definition: ppl.h:3672
The affinity_partitioner class is similar to the static_partitioner class, but it improves cache affi...
Definition: ppl.h:1722
char _Value[(sizeof(_Ty)/sizeof(char))]
Definition: ppl.h:3201
_AllocatedBufferHolder(size_t _Size, const _Allocator &_Alloc)
Definition: ppl.h:5225
const _Index_type _M_first_iteration
Definition: ppl.h:2272
_Ty combine(_Function _FnCombine) const
Computes a final value from the set of thread-local sub-computations by calling the supplied combine ...
Definition: ppl.h:4403
void cancel()
Makes a best effort attempt to cancel the sub-tree of work rooted at this task group. Every task scheduled on the task group will get canceled transitively if possible.
Definition: ppl.h:443
size_t operator()(const _DataType &val) const
Definition: ppl.h:5640
~static_partitioner()
Destroys a static_partitioner object.
Definition: ppl.h:1655
static void __cdecl _Invoke(const _Random_iterator &_First, _Index_type &_Index, const _Function &_Func)
Definition: ppl.h:1800
_Type _Get_num_chunks(_Type _Range_arg) const
Definition: ppl.h:1697
Definition: concrt.h:1067
_Functor::Bucket_type *const _M_bucket
Definition: ppl.h:3373
void _InitNew()
Definition: ppl.h:4471
long __cdecl _InterlockedIncrement(long volatile *)
_Parallel_fixed_chunk_helper(_Index_type, const _Random_iterator &_First, _Index_type _First_iteration, _Index_type _Last_iteration, const _Index_type &_Step, const _Function &_Func, const _Partitioner &)
Definition: ppl.h:2284
void _Parallel_transform_binary_impl2(_Input_iterator1 _First1, _Input_iterator1 _Last1, _Input_iterator2 _First2, _Output_iterator &_Result, const _Binary_operator&_Binary_op, task_group &_Tg)
Definition: ppl.h:3728
bool _Is_beacon_signaled()
Definition: ppl.h:2066
size_t _Populate(_Forward_iterator &_First, _Forward_iterator _Last)
Definition: ppl.h:3607
_Iterator_helper()
Definition: ppl.h:3600
_Parallel_reduce_fixed_worker< _Forward_iterator, _Function > _Worker_class
Definition: ppl.h:3422
_FwdIt const _Ty _Val
Definition: algorithm:1938
const _Function & _M_function
Definition: ppl.h:2306
#define SIZE_MAX
Definition: limits.h:81
The task_handle class represents an individual parallel work item. It encapsulates the instructions a...
Definition: ppl.h:84
_Index_type _Get_current_iteration() const
Definition: ppl.h:1862
Definition: xtr1common:380
_Check_return_ _In_ long _Size
Definition: io.h:325
static _CRTIMP _Context __cdecl _CurrentContext()
const _Function & _M_function
Definition: ppl.h:2800
_CRTIMP _Pre_notnull_ _Post_z_ char _In_ int _Radix
Definition: stdlib.h:483
~affinity_partitioner()
Destroys an affinity_partitioner object.
Definition: ppl.h:1738
_FwdIt _Last
Definition: algorithm:1936
void run(task_handle< _Function > &_Task_handle, location &_Placement)
Schedules a task on the structured_task_group object. The caller manages the lifetime of the task_han...
Definition: ppl.h:322
combinable()
Constructs a new combinable object.
Definition: ppl.h:4232
_Function::_Reduce_type _Parallel_reduce_impl(_Forward_iterator _First, const _Forward_iterator &_Last, const _Function &_Func, std::forward_iterator_tag)
Definition: ppl.h:3284
_Combinable_type::_Bucket Bucket_type
Definition: ppl.h:3343
_Range< _Index_type > *volatile _M_pHelper_range
Definition: ppl.h:2110
_Index_type _Get_last_iteration() const
Definition: ppl.h:1876
const _Random_iterator & _M_first
Definition: ppl.h:2268
const _Index_type & _M_step
Definition: ppl.h:2269
void sort(_RanIt _First, _RanIt _Last, _Pr _Pred)
Definition: algorithm:3153
::Concurrency::details::_StructuredTaskCollection _M_task_collection
Definition: ppl.h:473
static _CRTIMP unsigned int __cdecl _GetNumberOfVirtualProcessors()
~_Order_combinable()
Definition: ppl.h:3242
void parallel_buffered_sort(const _Random_iterator &_Begin, const _Random_iterator &_End)
Arranges the elements in a specified range into a nondescending order, or according to an ordering cr...
Definition: ppl.h:5357
void _Parallel_transform_unary_impl2(_Input_iterator _First, _Input_iterator _Last, _Output_iterator &_Result, const _Unary_operator&_Unary_op, task_group &_Tg)
Definition: ppl.h:3780
_Node * _AddLocalItem(unsigned long _Key, size_t _Index)
Definition: ppl.h:4514
void _Parallel_reduce_forward_executor(_Forward_iterator _First, _Forward_iterator _Last, const _Function &_Func, task_group &_Task_group)
Definition: ppl.h:3475
volatile long _M_stop_iterating
Definition: ppl.h:2123
bool is_canceling()
Informs the caller whether or not the task group is currently in the midst of a cancellation. This does not necessarily indicate that the cancel method was called on the task_group object (although such certainly qualifies this method to return true). It may be the case that the task_group object is executing inline and a task group further up in the work tree was canceled. In cases such as these where the runtime can determine ahead of time that cancellation will flow through this task_group object, true will be returned as well.
Definition: ppl.h:830
_Output_iterator _Parallel_transform_unary_impl(_Input_iterator _First, _Input_iterator _Last, _Output_iterator _Result, const _Unary_operator&_Unary_op, _Partitioner &&_Part)
Definition: ppl.h:3801
The cancellation_token class represents the ability to determine whether some operation has been requ...
Definition: pplcancellation_token.h:616
_CRTIMP void _Cancel()
Cancels work on the task collection.
static _ChoreType * _InternalAlloc(const _Function &_Func)
Definition: concrt.h:4361
task_group_status wait()
Waits until all work on the task_group object has either completed or been canceled.
Definition: ppl.h:718
task_handle(const _Function &_Func)
Constructs a new task_handle object. The work of the task is performed by invoking the function speci...
Definition: ppl.h:100