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);
Random number generator, based on the Mersenne twister.
static const _Settings & get()
Get the global settings.
volatile _DifferenceType _M_last
Last element.
One __job for a certain thread.
unsigned int cache_line_size
Overestimation of cache line size. Used to avoid false sharing, i.e. elements of different threads ar...
GNU parallel code for public use.
Random number generator based on the Mersenne twister. This file is a GNU parallel extension to the S...
const _Tp & min(const _Tp &__a, const _Tp &__b)
Equivalent to std::min.
End-user include file. Provides advanced settings and tuning options. This file is a GNU parallel ext...
Compatibility layer, mostly concerned with atomic operations.
void __yield()
Yield control to another thread, without waiting for the end of the time slice.
uint16_t _ThreadIndex
Unsigned integer to index a thread number. The maximum thread number (for each processor) must fit in...
class _Settings Run-time settings for the parallel mode including all tunable parameters.
#define _GLIBCXX_CALL(__n)
Macro to produce log message when entering a function.
_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.
volatile _DifferenceType _M_first
First element.
volatile _DifferenceType _M_load
Number of elements, i.e. _M_last-_M_first+1.