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);
float find_scale_factor
Block size scale-down factor with respect to current position.
_SequenceIndex find_initial_block_size
Initial block size for find.
GNU parallel code for public use.
#define _GLIBCXX_CALL(__n)
Macro to produce log message when entering a function.
class _Settings Run-time settings for the parallel mode including all tunable parameters.
uint16_t _ThreadIndex
Unsigned integer to index a thread number. The maximum thread number (for each processor) must fit in...
Selects the constant block size variant for std::find().
_SequenceIndex find_sequential_search_size
Start with looking for this many elements sequentially, for find.
Defines on whether to include algorithm variants.
Compatibility layer, mostly concerned with atomic operations.
Selects the growing block size variant for std::find().
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.
End-user include file. Provides advanced settings and tuning options. This file is a GNU parallel ext...
Selects the equal splitting variant for std::find().
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.
std::pair< _RAIter1, _RAIter2 > __find_template(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _Pred __pred, _Selector __selector)
Parallel std::find, switch for different algorithms.
Struct holding two objects of arbitrary type.