40 #ifndef _GLIBCXX_PARALLEL_WORKSTEALING_H
41 #define _GLIBCXX_PARALLEL_WORKSTEALING_H 1
50 #define _GLIBCXX_JOB_VOLATILE volatile
53 template<
typename _DifferenceTp>
56 typedef _DifferenceTp _DifferenceType;
62 _GLIBCXX_JOB_VOLATILE _DifferenceType
_M_first;
67 _GLIBCXX_JOB_VOLATILE _DifferenceType
_M_last;
72 _GLIBCXX_JOB_VOLATILE _DifferenceType
_M_load;
93 template<
typename _RAIter,
100 _RAIter __end, _Op __op,
104 typename std::iterator_traits<_RAIter>::difference_type __bound)
108 typedef std::iterator_traits<_RAIter> _TraitsType;
109 typedef typename _TraitsType::difference_type _DifferenceType;
113 _DifferenceType __chunk_size =
114 static_cast<_DifferenceType
>(__s.workstealing_chunk_size);
117 _DifferenceType __length = (__bound < 0) ? (__end - __begin) : __bound;
128 omp_lock_t __output_lock;
129 omp_init_lock(&__output_lock);
135 _ThreadIndex __num_threads = __gnu_parallel::max<_ThreadIndex>
136 (1, __gnu_parallel::min<_DifferenceType>(__length,
137 __get_max_threads()));
139 # pragma omp parallel shared(__busy) num_threads(__num_threads)
143 __num_threads = omp_get_num_threads();
152 bool __iam_working =
false;
164 _Result __result = _Result();
167 _DifferenceType __steal;
177 __iam_working =
true;
180 __my_job.
_M_first =
static_cast<_DifferenceType
>
181 (__iam * (__length / __num_threads));
183 __my_job.
_M_last = (__iam == (__num_threads - 1)
185 : ((__iam + 1) * (__length / __num_threads) - 1));
192 _DifferenceType __my_first = __my_job.
_M_first;
193 __result = __f(__op, __begin + __my_first);
207 # pragma omp flush(__busy)
214 _DifferenceType __current_job =
215 __fetch_and_add<_DifferenceType>(&(__my_job.
_M_first),
221 for (_DifferenceType __job_counter = 0;
222 __job_counter < __chunk_size
223 && __current_job <= __my_job.
_M_last;
227 __current = __begin + __current_job;
231 __result = __r(__result, __f(__op, __current));
234 # pragma omp flush(__busy)
244 __iam_working =
false;
247 _DifferenceType __supposed_first, __supposed_last,
253 # pragma omp flush(__busy)
254 __victim = __rand_gen();
255 __supposed_first = __job[__victim * __stride].
_M_first;
256 __supposed_last = __job[__victim * __stride].
_M_last;
257 __supposed_load = __job[__victim * __stride].
_M_load;
260 && ((__supposed_load <= 0)
261 || ((__supposed_first + __supposed_load - 1)
262 != __supposed_last)));
267 if (__supposed_load > 0)
271 __steal = (__supposed_load < 2) ? 1 : __supposed_load / 2;
274 _DifferenceType __stolen_first =
275 __fetch_and_add<_DifferenceType>
276 (&(__job[__victim * __stride].
_M_first), __steal);
277 _DifferenceType __stolen_try = (__stolen_first + __steal
278 - _DifferenceType(1));
288 __iam_working =
true;
290 # pragma omp flush(__busy)
292 # pragma omp flush(__busy)
295 omp_set_lock(&__output_lock);
296 __output = __r(__output, __result);
297 omp_unset_lock(&__output_lock);
304 __f._M_finish_iterator = __begin + __length;
306 omp_destroy_lock(&__output_lock);
End-user include file. Provides advanced settings and tuning options. This file is a GNU parallel ext...
class _Settings Run-time settings for the parallel mode including all tunable parameters.
volatile _DifferenceType _M_load
Number of elements, i.e. _M_last-_M_first+1.
volatile _DifferenceType _M_last
Last element.
uint16_t _ThreadIndex
Unsigned integer to index a thread number. The maximum thread number (for each processor) must fit in...
_Siter_base< _Iterator >::iterator_type __base(_Iterator __it)
_Op __for_each_template_random_access_workstealing(_RAIter __begin, _RAIter __end, _Op __op, _Fu &__f, _Red __r, _Result __base, _Result &__output, typename std::iterator_traits< _RAIter >::difference_type __bound)
Work stealing algorithm for random access iterators.
unsigned int cache_line_size
Overestimation of cache line size. Used to avoid false sharing, i.e. elements of different threads ar...
const _Tp & min(const _Tp &__a, const _Tp &__b)
Equivalent to std::min.
One __job for a certain thread.
GNU parallel code for public use.
Random number generator, based on the Mersenne twister.
static const _Settings & get()
Get the global settings.
Compatibility layer, mostly concerned with atomic operations.
#define _GLIBCXX_CALL(__n)
Macro to produce log message when entering a function.
void __yield()
Yield control to another thread, without waiting for the end of the time slice.
Random number generator based on the Mersenne twister. This file is a GNU parallel extension to the S...
volatile _DifferenceType _M_first
First element.