33 #ifndef _GLIBCXX_PARALLEL_FIND_H 34 #define _GLIBCXX_PARALLEL_FIND_H 1 55 template<
typename _RAIter1,
61 _RAIter2 __begin2, _Pred __pred, _Selector __selector)
68 case CONSTANT_SIZE_BLOCKS:
75 _GLIBCXX_PARALLEL_ASSERT(
false);
80 #if _GLIBCXX_FIND_EQUAL_SPLIT 92 template<
typename _RAIter1,
98 _RAIter2 __begin2, _Pred __pred,
103 typedef std::iterator_traits<_RAIter1> _TraitsType;
104 typedef typename _TraitsType::difference_type _DifferenceType;
105 typedef typename _TraitsType::value_type _ValueType;
107 _DifferenceType __length = __end1 - __begin1;
108 _DifferenceType __result = __length;
109 _DifferenceType* __borders;
111 omp_lock_t __result_lock;
112 omp_init_lock(&__result_lock);
115 # pragma omp parallel num_threads(__num_threads) 119 __num_threads = omp_get_num_threads();
120 __borders =
new _DifferenceType[__num_threads + 1];
125 _DifferenceType __start = __borders[__iam],
126 __stop = __borders[__iam + 1];
128 _RAIter1 __i1 = __begin1 + __start;
129 _RAIter2 __i2 = __begin2 + __start;
130 for (_DifferenceType __pos = __start; __pos < __stop; ++__pos)
132 # pragma omp flush(__result) 134 if (__result < __pos)
137 if (__selector(__i1, __i2, __pred))
139 omp_set_lock(&__result_lock);
140 if (__pos < __result)
142 omp_unset_lock(&__result_lock);
150 omp_destroy_lock(&__result_lock);
154 __begin2 + __result);
159 #if _GLIBCXX_FIND_GROWING_BLOCKS 180 template<
typename _RAIter1,
186 _RAIter2 __begin2, _Pred __pred, _Selector __selector,
191 typedef std::iterator_traits<_RAIter1> _TraitsType;
192 typedef typename _TraitsType::difference_type _DifferenceType;
193 typedef typename _TraitsType::value_type _ValueType;
197 _DifferenceType __length = __end1 - __begin1;
200 __sequential_search_size = std::min<_DifferenceType>
205 __find_seq_result = __selector._M_sequential_algorithm
206 (__begin1, __begin1 + __sequential_search_size,
209 if (__find_seq_result.first != (__begin1 + __sequential_search_size))
210 return __find_seq_result;
213 _DifferenceType __next_block_start = __sequential_search_size;
214 _DifferenceType __result = __length;
216 omp_lock_t __result_lock;
217 omp_init_lock(&__result_lock);
222 # pragma omp parallel shared(__result) num_threads(__num_threads) 225 __num_threads = omp_get_num_threads();
230 _DifferenceType __block_size =
231 std::max<_DifferenceType>(1, __scale_factor * __next_block_start);
232 _DifferenceType __start = __fetch_and_add<_DifferenceType>
233 (&__next_block_start, __block_size);
236 _DifferenceType __stop =
237 std::min<_DifferenceType>(__length, __start + __block_size);
241 while (__start < __length)
243 # pragma omp flush(__result) 245 if (__result < __start)
251 __local_result = __selector._M_sequential_algorithm
252 (__begin1 + __start, __begin1 + __stop,
253 __begin2 + __start, __pred);
255 if (__local_result.first != (__begin1 + __stop))
257 omp_set_lock(&__result_lock);
258 if ((__local_result.first - __begin1) < __result)
260 __result = __local_result.first - __begin1;
263 __fetch_and_add<_DifferenceType>(&__next_block_start,
266 omp_unset_lock(&__result_lock);
269 _DifferenceType __block_size =
270 std::max<_DifferenceType>(1, __scale_factor * __next_block_start);
273 __start = __fetch_and_add<_DifferenceType>(&__next_block_start,
276 std::min<_DifferenceType>(__length, __start + __block_size);
280 omp_destroy_lock(&__result_lock);
285 __begin2 + __result);
290 #if _GLIBCXX_FIND_CONSTANT_SIZE_BLOCKS 310 template<
typename _RAIter1,
316 _RAIter2 __begin2, _Pred __pred, _Selector __selector,
320 typedef std::iterator_traits<_RAIter1> _TraitsType;
321 typedef typename _TraitsType::difference_type _DifferenceType;
322 typedef typename _TraitsType::value_type _ValueType;
326 _DifferenceType __length = __end1 - __begin1;
328 _DifferenceType __sequential_search_size = std::min<_DifferenceType>
333 __find_seq_result = __selector._M_sequential_algorithm
334 (__begin1, __begin1 + __sequential_search_size, __begin2, __pred);
336 if (__find_seq_result.first != (__begin1 + __sequential_search_size))
337 return __find_seq_result;
339 _DifferenceType __result = __length;
340 omp_lock_t __result_lock;
341 omp_init_lock(&__result_lock);
346 # pragma omp parallel shared(__result) num_threads(__num_threads) 349 __num_threads = omp_get_num_threads();
355 _DifferenceType __iteration_start = __sequential_search_size;
358 _DifferenceType __start = __iteration_start + __iam * __block_size;
359 _DifferenceType __stop = std::min<_DifferenceType>(__length,
365 while (__start < __length)
368 # pragma omp flush(__result) 370 if (__result < __start)
373 __local_result = __selector._M_sequential_algorithm
374 (__begin1 + __start, __begin1 + __stop,
375 __begin2 + __start, __pred);
377 if (__local_result.first != (__begin1 + __stop))
379 omp_set_lock(&__result_lock);
380 if ((__local_result.first - __begin1) < __result)
381 __result = __local_result.first - __begin1;
382 omp_unset_lock(&__result_lock);
387 __iteration_start += __num_threads * __block_size;
390 __start = __iteration_start + __iam * __block_size;
391 __stop = std::min<_DifferenceType>(__length,
392 __start + __block_size);
396 omp_destroy_lock(&__result_lock);
400 __begin2 + __result);
uint16_t _ThreadIndex
Unsigned integer to index a thread number. The maximum thread number (for each processor) must fit in...
constexpr pair< typename __decay_and_strip< _T1 >::__type, typename __decay_and_strip< _T2 >::__type > make_pair(_T1 &&__x, _T2 &&__y)
A convenience wrapper for creating a pair from two objects.
Compatibility layer, mostly concerned with atomic operations.
Selects the constant block size variant for std::find().
GNU parallel code for public use.
float find_scale_factor
Block size scale-down factor with respect to current position.
Defines on whether to include algorithm variants.
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.
static const _Settings & get()
Get the global settings.
_OutputIterator __equally_split(_DifferenceType __n, _ThreadIndex __num_threads, _OutputIterator __s)
function to split a sequence into parts of almost equal size.
#define _GLIBCXX_CALL(__n)
Macro to produce log message when entering a function.
_SequenceIndex find_sequential_search_size
Start with looking for this many elements sequentially, for find.
Selects the growing block size variant for std::find().
std::pair< _RAIter1, _RAIter2 > __find_template(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _Pred __pred, _Selector __selector)
Parallel std::find, switch for different algorithms.
Selects the equal splitting variant for std::find().
_SequenceIndex find_initial_block_size
Initial block size for find.
Struct holding two objects of arbitrary type.