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