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,
99 _Selector __selector, equal_split_tag)
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;
195 const _Settings& __s = _Settings::get();
197 _DifferenceType __length = __end1 - __begin1;
200 __sequential_search_size = std::
min<_DifferenceType>
201 (__length, __s.find_sequential_search_size);
204 std::pair<_RAIter1, _RAIter2>
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);
219 const
float __scale_factor = __s.find_scale_factor;
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,
317 constant_size_blocks_tag)
320 typedef std::iterator_traits<_RAIter1> _TraitsType;
321 typedef typename _TraitsType::difference_type _DifferenceType;
322 typedef typename _TraitsType::value_type _ValueType;
324 const _Settings& __s = _Settings::get();
326 _DifferenceType __length = __end1 - __begin1;
328 _DifferenceType __sequential_search_size = std::
min<_DifferenceType>
329 (__length, __s.find_sequential_search_size);
332 std::pair<_RAIter1, _RAIter2>
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();
352 _DifferenceType __block_size = __s.find_initial_block_size;
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);