Commit 77d16198 by Paolo Carlini Committed by Paolo Carlini

multiway_merge.h: Simple formatting and uglification fixes.

2009-11-06  Paolo Carlini  <paolo.carlini@oracle.com>

	* include/parallel/multiway_merge.h: Simple formatting and
	uglification fixes.
	* include/parallel/find_selectors.h: Likewise.
	* include/parallel/losertree.h: Likewise.
	* include/parallel/list_partition.h: Likewise.
	* include/parallel/for_each.h: Likewise.
	* include/parallel/multiseq_selection.h: Likewise.
	* include/parallel/workstealing.h: Likewise.
	* include/parallel/par_loop.h: Likewise.
	* include/parallel/numeric: Likewise.
	* include/parallel/quicksort.h: Likewise.
	* include/parallel/equally_split.h: Likewise.
	* include/parallel/omp_loop_static.h: Likewise.
	* include/parallel/random_shuffle.h: Likewise.
	* include/parallel/balanced_quicksort.h: Likewise.
	* include/parallel/tags.h: Likewise.
	* include/parallel/set_operations.h: Likewise.
	* include/parallel/merge.h: Likewise.
	* include/parallel/unique_copy.h: Likewise.
	* include/parallel/multiway_mergesort.h: Likewise.
	* include/parallel/search.h: Likewise.
	* include/parallel/partition.h: Likewise.
	* include/parallel/partial_sum.h: Likewise.
	* include/parallel/find.h: Likewise.
	* include/parallel/queue.h: Likewise.
	* include/parallel/omp_loop.h: Likewise.
	* include/parallel/checkers.h: Likewise.
	* include/parallel/sort.h: Likewise.

From-SVN: r153966
parent b169fe9d
2009-11-06 Paolo Carlini <paolo.carlini@oracle.com>
* include/parallel/multiway_merge.h: Simple formatting and
uglification fixes.
* include/parallel/find_selectors.h: Likewise.
* include/parallel/losertree.h: Likewise.
* include/parallel/list_partition.h: Likewise.
* include/parallel/for_each.h: Likewise.
* include/parallel/multiseq_selection.h: Likewise.
* include/parallel/workstealing.h: Likewise.
* include/parallel/par_loop.h: Likewise.
* include/parallel/numeric: Likewise.
* include/parallel/quicksort.h: Likewise.
* include/parallel/equally_split.h: Likewise.
* include/parallel/omp_loop_static.h: Likewise.
* include/parallel/random_shuffle.h: Likewise.
* include/parallel/balanced_quicksort.h: Likewise.
* include/parallel/tags.h: Likewise.
* include/parallel/set_operations.h: Likewise.
* include/parallel/merge.h: Likewise.
* include/parallel/unique_copy.h: Likewise.
* include/parallel/multiway_mergesort.h: Likewise.
* include/parallel/search.h: Likewise.
* include/parallel/partition.h: Likewise.
* include/parallel/partial_sum.h: Likewise.
* include/parallel/find.h: Likewise.
* include/parallel/queue.h: Likewise.
* include/parallel/omp_loop.h: Likewise.
* include/parallel/checkers.h: Likewise.
* include/parallel/sort.h: Likewise.
2009-11-06 Jonathan Wakely <jwakely.gcc@gmail.com> 2009-11-06 Jonathan Wakely <jwakely.gcc@gmail.com>
PR libstdc++/41949 PR libstdc++/41949
......
...@@ -68,5 +68,6 @@ namespace __gnu_parallel ...@@ -68,5 +68,6 @@ namespace __gnu_parallel
return true; return true;
} }
}
#endif /* _GLIBCXX_PARALLEL_CHECKERS_H */ #endif /* _GLIBCXX_PARALLEL_CHECKERS_H */
// -*- C++ -*- // -*- C++ -*-
// Copyright (C) 2007, 2009 Free Software Foundation, Inc. // Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
// //
// This file is part of the GNU ISO C++ Library. This library is free // This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the terms // software; you can redistribute it and/or modify it under the terms
...@@ -33,57 +33,56 @@ ...@@ -33,57 +33,56 @@
namespace __gnu_parallel namespace __gnu_parallel
{ {
/** @brief function to split a sequence into parts of almost equal size. /** @brief function to split a sequence into parts of almost equal size.
* *
* The resulting sequence __s of length __num_threads+1 contains the splitting * The resulting sequence __s of length __num_threads+1 contains the
* positions when splitting the range [0,__n) into parts of almost * splitting positions when splitting the range [0,__n) into parts of
* equal size (plus minus 1). The first entry is 0, the last one * almost equal size (plus minus 1). The first entry is 0, the last
* n. There may result empty parts. * one n. There may result empty parts.
* @param __n Number of elements * @param __n Number of elements
* @param __num_threads Number of parts * @param __num_threads Number of parts
* @param __s Splitters * @param __s Splitters
* @returns End of __splitter sequence, i.e. @__c __s+__num_threads+1 */ * @returns End of __splitter sequence, i.e. @__c __s+__num_threads+1 */
template<typename _DifferenceType, typename _OutputIterator> template<typename _DifferenceType, typename _OutputIterator>
_OutputIterator _OutputIterator
equally_split(_DifferenceType __n, _ThreadIndex __num_threads, equally_split(_DifferenceType __n, _ThreadIndex __num_threads,
_OutputIterator __s) _OutputIterator __s)
{ {
_DifferenceType __chunk_length = __n / __num_threads; _DifferenceType __chunk_length = __n / __num_threads;
_DifferenceType __num_longer_chunks = __n % __num_threads; _DifferenceType __num_longer_chunks = __n % __num_threads;
_DifferenceType __pos = 0; _DifferenceType __pos = 0;
for (_ThreadIndex __i = 0; __i < __num_threads; ++__i) for (_ThreadIndex __i = 0; __i < __num_threads; ++__i)
{ {
*__s++ = __pos; *__s++ = __pos;
__pos += (__i < __num_longer_chunks) ? __pos += ((__i < __num_longer_chunks)
(__chunk_length + 1) : __chunk_length; ? (__chunk_length + 1) : __chunk_length);
} }
*__s++ = __n; *__s++ = __n;
return __s; return __s;
} }
/** @brief function to split a sequence into parts of almost equal size.
/** @brief function to split a sequence into parts of almost equal size. *
* * Returns the position of the splitting point between
* Returns the position of the splitting point between * thread number __thread_no (included) and
* thread number __thread_no (included) and * thread number __thread_no+1 (excluded).
* thread number __thread_no+1 (excluded). * @param __n Number of elements
* @param __n Number of elements * @param __num_threads Number of parts
* @param __num_threads Number of parts * @returns splitting point */
* @returns splitting point */ template<typename _DifferenceType>
template<typename _DifferenceType> _DifferenceType
_DifferenceType equally_split_point(_DifferenceType __n,
equally_split_point(_DifferenceType __n, _ThreadIndex __num_threads,
_ThreadIndex __num_threads, _ThreadIndex __thread_no)
_ThreadIndex __thread_no) {
{ _DifferenceType __chunk_length = __n / __num_threads;
_DifferenceType __chunk_length = __n / __num_threads; _DifferenceType __num_longer_chunks = __n % __num_threads;
_DifferenceType __num_longer_chunks = __n % __num_threads; if (__thread_no < __num_longer_chunks)
if (__thread_no < __num_longer_chunks) return __thread_no * (__chunk_length + 1);
return __thread_no * (__chunk_length + 1); else
else return __num_longer_chunks * (__chunk_length + 1)
return __num_longer_chunks * (__chunk_length + 1)
+ (__thread_no - __num_longer_chunks) * __chunk_length; + (__thread_no - __num_longer_chunks) * __chunk_length;
} }
} }
#endif /* _GLIBCXX_PARALLEL_EQUALLY_SPLIT_H */ #endif /* _GLIBCXX_PARALLEL_EQUALLY_SPLIT_H */
...@@ -103,12 +103,12 @@ namespace __gnu_parallel ...@@ -103,12 +103,12 @@ namespace __gnu_parallel
typename _Pred> typename _Pred>
std::pair<_RAIter1, _RAIter2> std::pair<_RAIter1, _RAIter2>
_M_sequential_algorithm(_RAIter1 __begin1, _M_sequential_algorithm(_RAIter1 __begin1,
_RAIter1 __end1, _RAIter1 __end1,
_RAIter2 __begin2, _Pred __pred) _RAIter2 __begin2, _Pred __pred)
{ {
// Passed end iterator is one short. // Passed end iterator is one short.
_RAIter1 __spot = adjacent_find(__begin1, __end1 + 1, _RAIter1 __spot = adjacent_find(__begin1, __end1 + 1,
__pred, sequential_tag()); __pred, sequential_tag());
if (__spot == (__end1 + 1)) if (__spot == (__end1 + 1))
__spot = __end1; __spot = __end1;
return std::make_pair(__spot, __begin2); return std::make_pair(__spot, __begin2);
...@@ -141,56 +141,57 @@ namespace __gnu_parallel ...@@ -141,56 +141,57 @@ namespace __gnu_parallel
typename _Pred> typename _Pred>
std::pair<_RAIter1, _RAIter2> std::pair<_RAIter1, _RAIter2>
_M_sequential_algorithm(_RAIter1 __begin1, _M_sequential_algorithm(_RAIter1 __begin1,
_RAIter1 __end1, _RAIter1 __end1,
_RAIter2 __begin2, _Pred __pred) _RAIter2 __begin2, _Pred __pred)
{ return mismatch(__begin1, __end1, __begin2, __pred, sequential_tag()); { return mismatch(__begin1, __end1, __begin2,
} __pred, sequential_tag()); }
}; };
/** @brief Test predicate on several elements. */ /** @brief Test predicate on several elements. */
template<typename _FIterator> template<typename _FIterator>
struct __find_first_of_selector : public __generic_find_selector struct __find_first_of_selector : public __generic_find_selector
{ {
_FIterator _M_begin; _FIterator _M_begin;
_FIterator _M_end; _FIterator _M_end;
explicit __find_first_of_selector(_FIterator __begin, _FIterator __end) explicit __find_first_of_selector(_FIterator __begin,
: _M_begin(__begin), _M_end(__end) { } _FIterator __end)
: _M_begin(__begin), _M_end(__end) { }
/** @brief Test on one position.
* @param __i1 _Iterator on first sequence. /** @brief Test on one position.
* @param __i2 _Iterator on second sequence (unused). * @param __i1 _Iterator on first sequence.
* @param __pred Find predicate. */ * @param __i2 _Iterator on second sequence (unused).
template<typename _RAIter1, typename _RAIter2, * @param __pred Find predicate. */
typename _Pred> template<typename _RAIter1, typename _RAIter2,
bool typename _Pred>
operator()(_RAIter1 __i1, _RAIter2 __i2, _Pred __pred) bool
{ operator()(_RAIter1 __i1, _RAIter2 __i2, _Pred __pred)
for (_FIterator __pos_in_candidates = _M_begin; {
__pos_in_candidates != _M_end; ++__pos_in_candidates) for (_FIterator __pos_in_candidates = _M_begin;
if (__pred(*__i1, *__pos_in_candidates)) __pos_in_candidates != _M_end; ++__pos_in_candidates)
return true; if (__pred(*__i1, *__pos_in_candidates))
return false; return true;
} return false;
}
/** @brief Corresponding sequential algorithm on a sequence.
* @param __begin1 Begin iterator of first sequence. /** @brief Corresponding sequential algorithm on a sequence.
* @param __end1 End iterator of first sequence. * @param __begin1 Begin iterator of first sequence.
* @param __begin2 Begin iterator of second sequence. * @param __end1 End iterator of first sequence.
* @param __pred Find predicate. */ * @param __begin2 Begin iterator of second sequence.
template<typename _RAIter1, typename _RAIter2, * @param __pred Find predicate. */
typename _Pred> template<typename _RAIter1, typename _RAIter2,
std::pair<_RAIter1, _RAIter2> typename _Pred>
_M_sequential_algorithm(_RAIter1 __begin1, std::pair<_RAIter1, _RAIter2>
_RAIter1 __end1, _M_sequential_algorithm(_RAIter1 __begin1,
_RAIter2 __begin2, _Pred __pred) _RAIter1 __end1,
{ _RAIter2 __begin2, _Pred __pred)
return std::make_pair( {
find_first_of(__begin1, __end1, _M_begin, _M_end, __pred, return std::make_pair(find_first_of(__begin1, __end1,
sequential_tag()), __begin2); _M_begin, _M_end, __pred,
} sequential_tag()), __begin2);
}; }
};
} }
#endif /* _GLIBCXX_PARALLEL_FIND_SELECTORS_H */ #endif /* _GLIBCXX_PARALLEL_FIND_SELECTORS_H */
...@@ -69,31 +69,21 @@ namespace __gnu_parallel ...@@ -69,31 +69,21 @@ namespace __gnu_parallel
_Parallelism __parallelism_tag) _Parallelism __parallelism_tag)
{ {
if (__parallelism_tag == parallel_unbalanced) if (__parallelism_tag == parallel_unbalanced)
return __for_each_template_random_access_ed(__begin, __end, __user_op, return __for_each_template_random_access_ed
__functionality, __reduction, (__begin, __end, __user_op, __functionality, __reduction,
__reduction_start, __reduction_start, __output, __bound);
__output, __bound);
else if (__parallelism_tag == parallel_omp_loop) else if (__parallelism_tag == parallel_omp_loop)
return __for_each_template_random_access_omp_loop( return __for_each_template_random_access_omp_loop
__begin, __end, __user_op, (__begin, __end, __user_op, __functionality, __reduction,
__functionality, __reduction_start, __output, __bound);
__reduction,
__reduction_start,
__output, __bound);
else if (__parallelism_tag == parallel_omp_loop_static) else if (__parallelism_tag == parallel_omp_loop_static)
return __for_each_template_random_access_omp_loop( return __for_each_template_random_access_omp_loop
__begin, __end, __user_op, (__begin, __end, __user_op, __functionality, __reduction,
__functionality, __reduction_start, __output, __bound);
__reduction,
__reduction_start,
__output, __bound);
else //e. g. parallel_balanced else //e. g. parallel_balanced
return __for_each_template_random_access_workstealing(__begin, __end, return __for_each_template_random_access_workstealing
__user_op, (__begin, __end, __user_op, __functionality, __reduction,
__functionality, __reduction_start, __output, __bound);
__reduction,
__reduction_start,
__output, __bound);
} }
} }
......
...@@ -48,11 +48,11 @@ namespace __gnu_parallel ...@@ -48,11 +48,11 @@ namespace __gnu_parallel
template<typename _IIter> template<typename _IIter>
void void
__shrink_and_double(std::vector<_IIter>& __os_starts, __shrink_and_double(std::vector<_IIter>& __os_starts,
size_t& __count_to_two, size_t& __range_length, size_t& __count_to_two, size_t& __range_length,
const bool __make_twice) const bool __make_twice)
{ {
++__count_to_two; ++__count_to_two;
if (not __make_twice or __count_to_two < 2) if (!__make_twice || __count_to_two < 2)
__shrink(__os_starts, __count_to_two, __range_length); __shrink(__os_starts, __count_to_two, __range_length);
else else
{ {
...@@ -68,7 +68,7 @@ namespace __gnu_parallel ...@@ -68,7 +68,7 @@ namespace __gnu_parallel
template<typename _IIter> template<typename _IIter>
void void
__shrink(std::vector<_IIter>& __os_starts, size_t& __count_to_two, __shrink(std::vector<_IIter>& __os_starts, size_t& __count_to_two,
size_t& __range_length) size_t& __range_length)
{ {
for (typename std::vector<_IIter>::size_type __i = 0; for (typename std::vector<_IIter>::size_type __i = 0;
__i <= (__os_starts.size() / 2); ++__i) __i <= (__os_starts.size() / 2); ++__i)
...@@ -112,8 +112,8 @@ namespace __gnu_parallel ...@@ -112,8 +112,8 @@ namespace __gnu_parallel
std::vector<_IIter> __os_starts(2 * __oversampling * __num_parts + 1); std::vector<_IIter> __os_starts(2 * __oversampling * __num_parts + 1);
__os_starts[0]= __begin; __os_starts[0] = __begin;
_IIter __prev = __begin, __it = __begin; _IIter __prev = __begin, __it = __begin;
size_t __dist_limit = 0, __dist = 0; size_t __dist_limit = 0, __dist = 0;
size_t __cur = 1, __next = 1; size_t __cur = 1, __next = 1;
size_t __range_length = 1; size_t __range_length = 1;
......
...@@ -54,11 +54,10 @@ namespace __gnu_parallel ...@@ -54,11 +54,10 @@ namespace __gnu_parallel
typename _OutputIterator, typename _DifferenceTp, typename _OutputIterator, typename _DifferenceTp,
typename _Compare> typename _Compare>
_OutputIterator _OutputIterator
__merge_advance_usual(_RAIter1& __begin1, __merge_advance_usual(_RAIter1& __begin1, _RAIter1 __end1,
_RAIter1 __end1, _RAIter2& __begin2, _RAIter2 __end2,
_RAIter2& __begin2, _OutputIterator __target,
_RAIter2 __end2, _OutputIterator __target, _DifferenceTp __max_length, _Compare __comp)
_DifferenceTp __max_length, _Compare __comp)
{ {
typedef _DifferenceTp _DifferenceType; typedef _DifferenceTp _DifferenceType;
while (__begin1 != __end1 && __begin2 != __end2 && __max_length > 0) while (__begin1 != __end1 && __begin2 != __end2 && __max_length > 0)
...@@ -103,12 +102,10 @@ namespace __gnu_parallel ...@@ -103,12 +102,10 @@ namespace __gnu_parallel
typename _OutputIterator, typename _DifferenceTp, typename _OutputIterator, typename _DifferenceTp,
typename _Compare> typename _Compare>
_OutputIterator _OutputIterator
__merge_advance_movc(_RAIter1& __begin1, __merge_advance_movc(_RAIter1& __begin1, _RAIter1 __end1,
_RAIter1 __end1, _RAIter2& __begin2, _RAIter2 __end2,
_RAIter2& __begin2, _OutputIterator __target,
_RAIter2 __end2, _DifferenceTp __max_length, _Compare __comp)
_OutputIterator __target,
_DifferenceTp __max_length, _Compare __comp)
{ {
typedef _DifferenceTp _DifferenceType; typedef _DifferenceTp _DifferenceType;
typedef typename std::iterator_traits<_RAIter1>::value_type typedef typename std::iterator_traits<_RAIter1>::value_type
...@@ -172,14 +169,14 @@ namespace __gnu_parallel ...@@ -172,14 +169,14 @@ namespace __gnu_parallel
typename _Compare> typename _Compare>
inline _OutputIterator inline _OutputIterator
__merge_advance(_RAIter1& __begin1, _RAIter1 __end1, __merge_advance(_RAIter1& __begin1, _RAIter1 __end1,
_RAIter2& __begin2, _RAIter2 __end2, _RAIter2& __begin2, _RAIter2 __end2,
_OutputIterator __target, _DifferenceTp __max_length, _OutputIterator __target, _DifferenceTp __max_length,
_Compare __comp) _Compare __comp)
{ {
_GLIBCXX_CALL(__max_length) _GLIBCXX_CALL(__max_length)
return __merge_advance_movc(__begin1, __end1, __begin2, __end2, __target, return __merge_advance_movc(__begin1, __end1, __begin2, __end2,
__max_length, __comp); __target, __max_length, __comp);
} }
/** @brief Merge routine fallback to sequential in case the /** @brief Merge routine fallback to sequential in case the
...@@ -195,17 +192,15 @@ namespace __gnu_parallel ...@@ -195,17 +192,15 @@ namespace __gnu_parallel
template<typename _RAIter1, typename _RAIter2, template<typename _RAIter1, typename _RAIter2,
typename _RAIter3, typename _Compare> typename _RAIter3, typename _Compare>
inline _RAIter3 inline _RAIter3
__parallel_merge_advance(_RAIter1& __begin1, __parallel_merge_advance(_RAIter1& __begin1, _RAIter1 __end1,
_RAIter1 __end1, _RAIter2& __begin2,
_RAIter2& __begin2, // different iterators, parallel implementation
// different iterators, parallel implementation // not available
// not available _RAIter2 __end2, _RAIter3 __target, typename
_RAIter2 __end2, std::iterator_traits<_RAIter1>::
_RAIter3 __target, typename difference_type __max_length, _Compare __comp)
std::iterator_traits<_RAIter1>::
difference_type __max_length, _Compare __comp)
{ return __merge_advance(__begin1, __end1, __begin2, __end2, __target, { return __merge_advance(__begin1, __end1, __begin2, __end2, __target,
__max_length, __comp); } __max_length, __comp); }
/** @brief Parallel merge routine being able to merge only the @__c /** @brief Parallel merge routine being able to merge only the @__c
* __max_length smallest elements. * __max_length smallest elements.
...@@ -225,13 +220,11 @@ namespace __gnu_parallel ...@@ -225,13 +220,11 @@ namespace __gnu_parallel
template<typename _RAIter1, typename _RAIter3, template<typename _RAIter1, typename _RAIter3,
typename _Compare> typename _Compare>
inline _RAIter3 inline _RAIter3
__parallel_merge_advance(_RAIter1& __begin1, __parallel_merge_advance(_RAIter1& __begin1, _RAIter1 __end1,
_RAIter1 __end1, _RAIter1& __begin2, _RAIter1 __end2,
_RAIter1& __begin2, _RAIter3 __target, typename
_RAIter1 __end2, std::iterator_traits<_RAIter1>::
_RAIter3 __target, typename difference_type __max_length, _Compare __comp)
std::iterator_traits<_RAIter1>::
difference_type __max_length, _Compare __comp)
{ {
typedef typename typedef typename
std::iterator_traits<_RAIter1>::value_type _ValueType; std::iterator_traits<_RAIter1>::value_type _ValueType;
...@@ -242,17 +235,14 @@ namespace __gnu_parallel ...@@ -242,17 +235,14 @@ namespace __gnu_parallel
typedef typename std::pair<_RAIter1, _RAIter1> typedef typename std::pair<_RAIter1, _RAIter1>
_IteratorPair; _IteratorPair;
_IteratorPair _IteratorPair __seqs[2] = { std::make_pair(__begin1, __end1),
seqs[2] = { std::make_pair(__begin1, __end1), std::make_pair(__begin2, __end2) };
std::make_pair(__begin2, __end2) }; _RAIter3 __target_end = parallel_multiway_merge
_RAIter3 < /* __stable = */ true, /* __sentinels = */ false>
__target_end = parallel_multiway_merge (__seqs, __seqs + 2, __target, multiway_merge_exact_splitting
< /* __stable = */ true, /* __sentinels = */ false>( < /* __stable = */ true, _IteratorPair*,
seqs, seqs + 2, __target, _Compare, _DifferenceType1>, __max_length, __comp,
multiway_merge_exact_splitting omp_get_max_threads());
< /* __stable = */ true, _IteratorPair*,
_Compare, _DifferenceType1>,
__max_length, __comp, omp_get_max_threads());
return __target_end; return __target_end;
} }
......
...@@ -53,8 +53,8 @@ namespace __gnu_parallel ...@@ -53,8 +53,8 @@ namespace __gnu_parallel
/** @brief Compare __a pair of types lexicographically, ascending. */ /** @brief Compare __a pair of types lexicographically, ascending. */
template<typename _T1, typename _T2, typename _Compare> template<typename _T1, typename _T2, typename _Compare>
class _Lexicographic class _Lexicographic
: public std::binary_function< : public std::binary_function<std::pair<_T1, _T2>,
std::pair<_T1, _T2>, std::pair<_T1, _T2>, bool> std::pair<_T1, _T2>, bool>
{ {
private: private:
_Compare& _M_comp; _Compare& _M_comp;
...@@ -142,19 +142,19 @@ namespace __gnu_parallel ...@@ -142,19 +142,19 @@ namespace __gnu_parallel
// Number of sequences, number of elements in total (possibly // Number of sequences, number of elements in total (possibly
// including padding). // including padding).
_DifferenceType __m = std::distance(__begin_seqs, __end_seqs), __N = 0, _DifferenceType __m = std::distance(__begin_seqs, __end_seqs), __nn = 0,
__nmax, __n, __r; __nmax, __n, __r;
for (int __i = 0; __i < __m; __i++) for (int __i = 0; __i < __m; __i++)
{ {
__N += std::distance(__begin_seqs[__i].first, __nn += std::distance(__begin_seqs[__i].first,
__begin_seqs[__i].second); __begin_seqs[__i].second);
_GLIBCXX_PARALLEL_ASSERT( _GLIBCXX_PARALLEL_ASSERT(
std::distance(__begin_seqs[__i].first, std::distance(__begin_seqs[__i].first,
__begin_seqs[__i].second) > 0); __begin_seqs[__i].second) > 0);
} }
if (__rank == __N) if (__rank == __nn)
{ {
for (int __i = 0; __i < __m; __i++) for (int __i = 0; __i < __m; __i++)
__begin_offsets[__i] = __begin_seqs[__i].second; // Very end. __begin_offsets[__i] = __begin_seqs[__i].second; // Very end.
...@@ -163,9 +163,9 @@ namespace __gnu_parallel ...@@ -163,9 +163,9 @@ namespace __gnu_parallel
} }
_GLIBCXX_PARALLEL_ASSERT(__m != 0); _GLIBCXX_PARALLEL_ASSERT(__m != 0);
_GLIBCXX_PARALLEL_ASSERT(__N != 0); _GLIBCXX_PARALLEL_ASSERT(__nn != 0);
_GLIBCXX_PARALLEL_ASSERT(__rank >= 0); _GLIBCXX_PARALLEL_ASSERT(__rank >= 0);
_GLIBCXX_PARALLEL_ASSERT(__rank < __N); _GLIBCXX_PARALLEL_ASSERT(__rank < __nn);
_DifferenceType* __ns = new _DifferenceType[__m]; _DifferenceType* __ns = new _DifferenceType[__m];
_DifferenceType* __a = new _DifferenceType[__m]; _DifferenceType* __a = new _DifferenceType[__m];
...@@ -401,14 +401,14 @@ namespace __gnu_parallel ...@@ -401,14 +401,14 @@ namespace __gnu_parallel
// Number of sequences, number of elements in total (possibly // Number of sequences, number of elements in total (possibly
// including padding). // including padding).
_DifferenceType __m = std::distance(__begin_seqs, __end_seqs); _DifferenceType __m = std::distance(__begin_seqs, __end_seqs);
_DifferenceType __N = 0; _DifferenceType __nn = 0;
_DifferenceType __nmax, __n, __r; _DifferenceType __nmax, __n, __r;
for (int __i = 0; __i < __m; __i++) for (int __i = 0; __i < __m; __i++)
__N += std::distance(__begin_seqs[__i].first, __nn += std::distance(__begin_seqs[__i].first,
__begin_seqs[__i].second); __begin_seqs[__i].second);
if (__m == 0 || __N == 0 || __rank < 0 || __rank >= __N) if (__m == 0 || __nn == 0 || __rank < 0 || __rank >= __nn)
{ {
// result undefined if there is no data or __rank is outside bounds // result undefined if there is no data or __rank is outside bounds
throw std::exception(); throw std::exception();
...@@ -433,7 +433,7 @@ namespace __gnu_parallel ...@@ -433,7 +433,7 @@ namespace __gnu_parallel
// Pad all lists to this length, at least as long as any ns[__i], // Pad all lists to this length, at least as long as any ns[__i],
// equality iff __nmax = 2^__k - 1 // equality iff __nmax = 2^__k - 1
__l = pow2(__r) - 1; __l = __round_up_to_pow2(__r) - 1;
for (int __i = 0; __i < __m; ++__i) for (int __i = 0; __i < __m; ++__i)
{ {
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -125,8 +125,7 @@ namespace __gnu_parallel ...@@ -125,8 +125,7 @@ namespace __gnu_parallel
/** @brief Split by exact splitting. */ /** @brief Split by exact splitting. */
template<typename _RAIter, typename _Compare, template<typename _RAIter, typename _Compare,
typename _SortingPlacesIterator> typename _SortingPlacesIterator>
struct _SplitConsistently<true, _RAIter, struct _SplitConsistently<true, _RAIter, _Compare, _SortingPlacesIterator>
_Compare, _SortingPlacesIterator>
{ {
void void
operator()(const _ThreadIndex __iam, operator()(const _ThreadIndex __iam,
...@@ -140,19 +139,19 @@ namespace __gnu_parallel ...@@ -140,19 +139,19 @@ namespace __gnu_parallel
std::vector<std::pair<_SortingPlacesIterator, std::vector<std::pair<_SortingPlacesIterator,
_SortingPlacesIterator> > _SortingPlacesIterator> >
seqs(__sd->_M_num_threads); __seqs(__sd->_M_num_threads);
for (_ThreadIndex __s = 0; __s < __sd->_M_num_threads; __s++) for (_ThreadIndex __s = 0; __s < __sd->_M_num_threads; __s++)
seqs[__s] = std::make_pair(__sd->_M_temporary[__s], __seqs[__s] = std::make_pair(__sd->_M_temporary[__s],
__sd->_M_temporary[__s] __sd->_M_temporary[__s]
+ (__sd->_M_starts[__s + 1] + (__sd->_M_starts[__s + 1]
- __sd->_M_starts[__s])); - __sd->_M_starts[__s]));
std::vector<_SortingPlacesIterator> _M_offsets(__sd->_M_num_threads); std::vector<_SortingPlacesIterator> __offsets(__sd->_M_num_threads);
// if not last thread // if not last thread
if (__iam < __sd->_M_num_threads - 1) if (__iam < __sd->_M_num_threads - 1)
multiseq_partition(seqs.begin(), seqs.end(), multiseq_partition(__seqs.begin(), __seqs.end(),
__sd->_M_starts[__iam + 1], _M_offsets.begin(), __sd->_M_starts[__iam + 1], __offsets.begin(),
__comp); __comp);
for (int __seq = 0; __seq < __sd->_M_num_threads; __seq++) for (int __seq = 0; __seq < __sd->_M_num_threads; __seq++)
...@@ -160,7 +159,7 @@ namespace __gnu_parallel ...@@ -160,7 +159,7 @@ namespace __gnu_parallel
// for each sequence // for each sequence
if (__iam < (__sd->_M_num_threads - 1)) if (__iam < (__sd->_M_num_threads - 1))
__sd->_M_pieces[__iam][__seq]._M_end __sd->_M_pieces[__iam][__seq]._M_end
= _M_offsets[__seq] - seqs[__seq].first; = __offsets[__seq] - __seqs[__seq].first;
else else
// very end of this sequence // very end of this sequence
__sd->_M_pieces[__iam][__seq]._M_end = __sd->_M_pieces[__iam][__seq]._M_end =
...@@ -185,8 +184,7 @@ namespace __gnu_parallel ...@@ -185,8 +184,7 @@ namespace __gnu_parallel
/** @brief Split by sampling. */ /** @brief Split by sampling. */
template<typename _RAIter, typename _Compare, template<typename _RAIter, typename _Compare,
typename _SortingPlacesIterator> typename _SortingPlacesIterator>
struct _SplitConsistently<false, _RAIter, _Compare, struct _SplitConsistently<false, _RAIter, _Compare, _SortingPlacesIterator>
_SortingPlacesIterator>
{ {
void void
operator()(const _ThreadIndex __iam, operator()(const _ThreadIndex __iam,
...@@ -282,10 +280,8 @@ namespace __gnu_parallel ...@@ -282,10 +280,8 @@ namespace __gnu_parallel
const _RAIter& __target, const _RAIter& __target,
_Compare& __comp, _Compare& __comp,
_DiffType __length_am) const _DiffType __length_am) const
{ { stable_multiway_merge(__seqs_begin, __seqs_end, __target,
stable_multiway_merge(__seqs_begin, __seqs_end, __target, __length_am, __length_am, __comp, sequential_tag()); }
__comp, sequential_tag());
}
}; };
template<typename Seq_RAIter, typename _RAIter, template<typename Seq_RAIter, typename _RAIter,
...@@ -298,10 +294,8 @@ namespace __gnu_parallel ...@@ -298,10 +294,8 @@ namespace __gnu_parallel
const _RAIter& __target, const _RAIter& __target,
_Compare& __comp, _Compare& __comp,
_DiffType __length_am) const _DiffType __length_am) const
{ { multiway_merge(__seqs_begin, __seqs_end, __target, __length_am,
multiway_merge(__seqs_begin, __seqs_end, __target, __length_am, __comp, __comp, sequential_tag()); }
sequential_tag());
}
}; };
/** @brief PMWMS code executed by each thread. /** @brief PMWMS code executed by each thread.
...@@ -321,8 +315,8 @@ namespace __gnu_parallel ...@@ -321,8 +315,8 @@ namespace __gnu_parallel
_ThreadIndex __iam = omp_get_thread_num(); _ThreadIndex __iam = omp_get_thread_num();
// Length of this thread's chunk, before merging. // Length of this thread's chunk, before merging.
_DifferenceType __length_local _DifferenceType __length_local =
= __sd->_M_starts[__iam + 1] - __sd->_M_starts[__iam]; __sd->_M_starts[__iam + 1] - __sd->_M_starts[__iam];
// Sort in temporary storage, leave space for sentinel. // Sort in temporary storage, leave space for sentinel.
...@@ -350,8 +344,7 @@ namespace __gnu_parallel ...@@ -350,8 +344,7 @@ namespace __gnu_parallel
_DifferenceType __num_samples = _DifferenceType __num_samples =
_Settings::get().sort_mwms_oversampling * __sd->_M_num_threads - 1; _Settings::get().sort_mwms_oversampling * __sd->_M_num_threads - 1;
_SplitConsistently _SplitConsistently<__exact, _RAIter, _Compare, _SortingPlacesIterator>()
<__exact, _RAIter, _Compare, _SortingPlacesIterator>()
(__iam, __sd, __comp, __num_samples); (__iam, __sd, __comp, __num_samples);
// Offset from __target __begin, __length after merging. // Offset from __target __begin, __length after merging.
...@@ -364,26 +357,24 @@ namespace __gnu_parallel ...@@ -364,26 +357,24 @@ namespace __gnu_parallel
} }
typedef std::vector< typedef std::vector<
std::pair<_SortingPlacesIterator, _SortingPlacesIterator> > std::pair<_SortingPlacesIterator, _SortingPlacesIterator> >
_SeqVector; _SeqVector;
_SeqVector seqs(__sd->_M_num_threads); _SeqVector __seqs(__sd->_M_num_threads);
for (int __s = 0; __s < __sd->_M_num_threads; ++__s) for (int __s = 0; __s < __sd->_M_num_threads; ++__s)
{ {
seqs[__s] = __seqs[__s] =
std::make_pair std::make_pair(__sd->_M_temporary[__s]
(__sd->_M_temporary[__s] + __sd->_M_pieces[__iam][__s]._M_begin, + __sd->_M_pieces[__iam][__s]._M_begin,
__sd->_M_temporary[__s] + __sd->_M_pieces[__iam][__s]._M_end); __sd->_M_temporary[__s]
+ __sd->_M_pieces[__iam][__s]._M_end);
} }
__possibly_stable_multiway_merge< __possibly_stable_multiway_merge<
__stable, __stable, typename _SeqVector::iterator,
typename _SeqVector::iterator, _RAIter, _Compare, _DifferenceType>()(__seqs.begin(), __seqs.end(),
_RAIter, __sd->_M_source + __offset, __comp,
_Compare, _DifferenceType>() __length_am);
(seqs.begin(), seqs.end(),
__sd->_M_source + __offset, __comp,
__length_am);
# pragma omp barrier # pragma omp barrier
...@@ -421,7 +412,7 @@ namespace __gnu_parallel ...@@ -421,7 +412,7 @@ namespace __gnu_parallel
// shared variables // shared variables
_PMWMSSortingData<_RAIter> __sd; _PMWMSSortingData<_RAIter> __sd;
_DifferenceType* _M_starts; _DifferenceType* __starts;
# pragma omp parallel num_threads(__num_threads) # pragma omp parallel num_threads(__num_threads)
{ {
...@@ -450,30 +441,29 @@ namespace __gnu_parallel ...@@ -450,30 +441,29 @@ namespace __gnu_parallel
= new std::vector<_Piece<_DifferenceType> >[__num_threads]; = new std::vector<_Piece<_DifferenceType> >[__num_threads];
for (int __s = 0; __s < __num_threads; ++__s) for (int __s = 0; __s < __num_threads; ++__s)
__sd._M_pieces[__s].resize(__num_threads); __sd._M_pieces[__s].resize(__num_threads);
_M_starts = __sd._M_starts __starts = __sd._M_starts = new _DifferenceType[__num_threads + 1];
= new _DifferenceType[__num_threads + 1];
_DifferenceType __chunk_length = __n / __num_threads; _DifferenceType __chunk_length = __n / __num_threads;
_DifferenceType __split = __n % __num_threads; _DifferenceType __split = __n % __num_threads;
_DifferenceType __pos = 0; _DifferenceType __pos = 0;
for (int __i = 0; __i < __num_threads; ++__i) for (int __i = 0; __i < __num_threads; ++__i)
{ {
_M_starts[__i] = __pos; __starts[__i] = __pos;
__pos += (__i < __split) __pos += ((__i < __split)
? (__chunk_length + 1) : __chunk_length; ? (__chunk_length + 1) : __chunk_length);
} }
_M_starts[__num_threads] = __pos; __starts[__num_threads] = __pos;
} //single } //single
// Now sort in parallel. // Now sort in parallel.
parallel_sort_mwms_pu<__stable, __exact>(&__sd, __comp); parallel_sort_mwms_pu<__stable, __exact>(&__sd, __comp);
} //parallel } //parallel
delete[] _M_starts; delete[] __starts;
delete[] __sd._M_temporary; delete[] __sd._M_temporary;
if (!__exact) if (!__exact)
::operator delete(__sd._M_samples); ::operator delete(__sd._M_samples);
delete[] __sd._M_offsets; delete[] __sd._M_offsets;
delete[] __sd._M_pieces; delete[] __sd._M_pieces;
......
...@@ -69,7 +69,7 @@ namespace __parallel ...@@ -69,7 +69,7 @@ namespace __parallel
__accumulate_switch(_IIter __begin, _IIter __end, __accumulate_switch(_IIter __begin, _IIter __end,
_Tp __init, _IteratorTag) _Tp __init, _IteratorTag)
{ return accumulate(__begin, __end, __init, { return accumulate(__begin, __end, __init,
__gnu_parallel::sequential_tag()); } __gnu_parallel::sequential_tag()); }
template<typename _IIter, typename _Tp, typename _BinaryOperation, template<typename _IIter, typename _Tp, typename _BinaryOperation,
typename _IteratorTag> typename _IteratorTag>
......
...@@ -74,8 +74,8 @@ namespace __gnu_parallel ...@@ -74,8 +74,8 @@ namespace __gnu_parallel
_DifferenceType; _DifferenceType;
_DifferenceType __length = __end - __begin; _DifferenceType __length = __end - __begin;
_ThreadIndex __num_threads = _ThreadIndex __num_threads = __gnu_parallel::min<_DifferenceType>
__gnu_parallel::min<_DifferenceType>(__get_max_threads(), __length); (__get_max_threads(), __length);
_Result *__thread_results; _Result *__thread_results;
...@@ -94,8 +94,8 @@ namespace __gnu_parallel ...@@ -94,8 +94,8 @@ namespace __gnu_parallel
#pragma omp for schedule(dynamic, _Settings::get().workstealing_chunk_size) #pragma omp for schedule(dynamic, _Settings::get().workstealing_chunk_size)
for (_DifferenceType __pos = 0; __pos < __length; ++__pos) for (_DifferenceType __pos = 0; __pos < __length; ++__pos)
__thread_results[__iam] = __thread_results[__iam] = __r(__thread_results[__iam],
__r(__thread_results[__iam], __f(__o, __begin+__pos)); __f(__o, __begin+__pos));
} //parallel } //parallel
for (_ThreadIndex __i = 0; __i < __num_threads; ++__i) for (_ThreadIndex __i = 0; __i < __num_threads; ++__i)
......
...@@ -74,8 +74,8 @@ namespace __gnu_parallel ...@@ -74,8 +74,8 @@ namespace __gnu_parallel
_DifferenceType; _DifferenceType;
_DifferenceType __length = __end - __begin; _DifferenceType __length = __end - __begin;
_ThreadIndex __num_threads = _ThreadIndex __num_threads = std::min<_DifferenceType>
std::min<_DifferenceType>(__get_max_threads(), __length); (__get_max_threads(), __length);
_Result *__thread_results; _Result *__thread_results;
......
...@@ -75,25 +75,24 @@ namespace __gnu_parallel ...@@ -75,25 +75,24 @@ namespace __gnu_parallel
_Result *__thread_results; _Result *__thread_results;
bool* __constructed; bool* __constructed;
_ThreadIndex __num_threads = _ThreadIndex __num_threads = __gnu_parallel::min<_DifferenceType>
__gnu_parallel::min<_DifferenceType>(__get_max_threads(), __length); (__get_max_threads(), __length);
# pragma omp parallel num_threads(__num_threads) # pragma omp parallel num_threads(__num_threads)
{ {
# pragma omp single # pragma omp single
{ {
__num_threads = omp_get_num_threads(); __num_threads = omp_get_num_threads();
__thread_results = __thread_results = static_cast<_Result*>
static_cast<_Result*>(::operator new(__num_threads (::operator new(__num_threads * sizeof(_Result)));
* sizeof(_Result)));
__constructed = new bool[__num_threads]; __constructed = new bool[__num_threads];
} }
_ThreadIndex __iam = omp_get_thread_num(); _ThreadIndex __iam = omp_get_thread_num();
// Neutral element. // Neutral element.
_Result* __reduct = _Result* __reduct = static_cast<_Result*>
static_cast<_Result*>(::operator new(sizeof(_Result))); (::operator new(sizeof(_Result)));
_DifferenceType _DifferenceType
__start = equally_split_point(__length, __num_threads, __iam), __start = equally_split_point(__length, __num_threads, __iam),
......
...@@ -149,9 +149,10 @@ namespace __gnu_parallel ...@@ -149,9 +149,10 @@ namespace __gnu_parallel
if (__iam == 0) if (__iam == 0)
{ {
*__result = *__begin; *__result = *__begin;
__parallel_partial_sum_basecase( __parallel_partial_sum_basecase(__begin + 1,
__begin + 1, __begin + __borders[1], __result + 1, __begin + __borders[1],
__bin_op, *__begin); __result + 1,
__bin_op, *__begin);
::new(&(__sums[__iam])) _ValueType(*(__result + __borders[1] - 1)); ::new(&(__sums[__iam])) _ValueType(*(__result + __borders[1] - 1));
} }
else else
...@@ -168,7 +169,7 @@ namespace __gnu_parallel ...@@ -168,7 +169,7 @@ namespace __gnu_parallel
# pragma omp single # pragma omp single
__parallel_partial_sum_basecase(__sums + 1, __sums + __num_threads, __parallel_partial_sum_basecase(__sums + 1, __sums + __num_threads,
__sums + 1, __bin_op, __sums[0]); __sums + 1, __bin_op, __sums[0]);
# pragma omp barrier # pragma omp barrier
......
...@@ -65,10 +65,10 @@ namespace __gnu_parallel ...@@ -65,10 +65,10 @@ namespace __gnu_parallel
public: public:
/** @brief Constructor. Not to be called concurrent, of course. /** @brief Constructor. Not to be called concurrent, of course.
* @param _M_max_size Maximal number of elements to be contained. */ * @param _M_max_size Maximal number of elements to be contained. */
_RestrictedBoundedConcurrentQueue(_SequenceIndex _M_max_size) _RestrictedBoundedConcurrentQueue(_SequenceIndex __max_size)
{ {
this->_M_max_size = _M_max_size; _M_max_size = __max_size;
_M_base = new _Tp[_M_max_size]; _M_base = new _Tp[__max_size];
_M_borders = __encode2(0, 0); _M_borders = __encode2(0, 0);
#pragma omp flush #pragma omp flush
} }
...@@ -105,12 +105,12 @@ namespace __gnu_parallel ...@@ -105,12 +105,12 @@ namespace __gnu_parallel
while (__former_front > __former_back) while (__former_front > __former_back)
{ {
// Chance. // Chance.
_CASable _CASable __former_borders = __encode2(__former_front,
__former_borders = __encode2(__former_front, __former_back); __former_back);
_CASable _CASable __new_borders = __encode2(__former_front - 1,
__new_borders = __encode2(__former_front - 1, __former_back); __former_back);
if (__compare_and_swap( if (__compare_and_swap(&_M_borders, __former_borders,
&_M_borders, __former_borders, __new_borders)) __new_borders))
{ {
__t = *(_M_base + (__former_front - 1) % _M_max_size); __t = *(_M_base + (__former_front - 1) % _M_max_size);
return true; return true;
...@@ -132,12 +132,12 @@ namespace __gnu_parallel ...@@ -132,12 +132,12 @@ namespace __gnu_parallel
while (__former_front > __former_back) while (__former_front > __former_back)
{ {
// Chance. // Chance.
_CASable _CASable __former_borders = __encode2(__former_front,
__former_borders = __encode2(__former_front, __former_back); __former_back);
_CASable _CASable __new_borders = __encode2(__former_front,
__new_borders = __encode2(__former_front, __former_back + 1); __former_back + 1);
if (__compare_and_swap( if (__compare_and_swap(&_M_borders, __former_borders,
&_M_borders, __former_borders, __new_borders)) __new_borders))
{ {
__t = *(_M_base + __former_back % _M_max_size); __t = *(_M_base + __former_back % _M_max_size);
return true; return true;
......
...@@ -48,13 +48,12 @@ namespace __gnu_parallel ...@@ -48,13 +48,12 @@ namespace __gnu_parallel
*/ */
template<typename _RAIter, typename _Compare> template<typename _RAIter, typename _Compare>
typename std::iterator_traits<_RAIter>::difference_type typename std::iterator_traits<_RAIter>::difference_type
__parallel_sort_qs_divide(_RAIter __begin, __parallel_sort_qs_divide(_RAIter __begin, _RAIter __end,
_RAIter __end, _Compare __comp, typename std::iterator_traits
_Compare __comp, typename std::iterator_traits <_RAIter>::difference_type __pivot_rank,
<_RAIter>::difference_type __pivot_rank, typename std::iterator_traits
typename std::iterator_traits <_RAIter>::difference_type
<_RAIter>::difference_type __num_samples, _ThreadIndex __num_threads)
__num_samples, _ThreadIndex __num_threads)
{ {
typedef std::iterator_traits<_RAIter> _TraitsType; typedef std::iterator_traits<_RAIter> _TraitsType;
typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::value_type _ValueType;
...@@ -64,25 +63,24 @@ namespace __gnu_parallel ...@@ -64,25 +63,24 @@ namespace __gnu_parallel
__num_samples = std::min(__num_samples, __n); __num_samples = std::min(__num_samples, __n);
// Allocate uninitialized, to avoid default constructor. // Allocate uninitialized, to avoid default constructor.
_ValueType* __samples = _ValueType* __samples = static_cast<_ValueType*>
static_cast<_ValueType*>(::operator new(__num_samples (::operator new(__num_samples * sizeof(_ValueType)));
* sizeof(_ValueType)));
for (_DifferenceType __s = 0; __s < __num_samples; ++__s) for (_DifferenceType __s = 0; __s < __num_samples; ++__s)
{ {
const unsigned long long __index const unsigned long long __index = static_cast<unsigned long long>
= static_cast<unsigned long long>(__s) * __n / __num_samples; (__s) * __n / __num_samples;
::new(&(__samples[__s])) _ValueType(__begin[__index]); ::new(&(__samples[__s])) _ValueType(__begin[__index]);
} }
__gnu_sequential::sort(__samples, __samples + __num_samples, __comp); __gnu_sequential::sort(__samples, __samples + __num_samples, __comp);
_ValueType& pivot = __samples[__pivot_rank * __num_samples / __n]; _ValueType& __pivot = __samples[__pivot_rank * __num_samples / __n];
__gnu_parallel::binder2nd<_Compare, _ValueType, _ValueType, bool> __gnu_parallel::binder2nd<_Compare, _ValueType, _ValueType, bool>
__pred(__comp, pivot); __pred(__comp, __pivot);
_DifferenceType __split = _DifferenceType __split = __parallel_partition(__begin, __end,
__parallel_partition(__begin, __end, __pred, __num_threads); __pred, __num_threads);
::operator delete(__samples); ::operator delete(__samples);
...@@ -98,10 +96,9 @@ namespace __gnu_parallel ...@@ -98,10 +96,9 @@ namespace __gnu_parallel
*/ */
template<typename _RAIter, typename _Compare> template<typename _RAIter, typename _Compare>
void void
__parallel_sort_qs_conquer(_RAIter __begin, __parallel_sort_qs_conquer(_RAIter __begin, _RAIter __end,
_RAIter __end, _Compare __comp,
_Compare __comp, _ThreadIndex __num_threads)
_ThreadIndex __num_threads)
{ {
typedef std::iterator_traits<_RAIter> _TraitsType; typedef std::iterator_traits<_RAIter> _TraitsType;
typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::value_type _ValueType;
...@@ -127,24 +124,22 @@ namespace __gnu_parallel ...@@ -127,24 +124,22 @@ namespace __gnu_parallel
__pivot_rank = __n * __num_threads_left / __num_threads; __pivot_rank = __n * __num_threads_left / __num_threads;
_DifferenceType __split = _DifferenceType __split = __parallel_sort_qs_divide
__parallel_sort_qs_divide(__begin, __end, __comp, __pivot_rank, (__begin, __end, __comp, __pivot_rank,
_Settings::get().sort_qs_num_samples_preset, _Settings::get().sort_qs_num_samples_preset, __num_threads);
__num_threads);
#pragma omp parallel sections num_threads(2) #pragma omp parallel sections num_threads(2)
{ {
#pragma omp section #pragma omp section
__parallel_sort_qs_conquer(__begin, __begin + __split, __parallel_sort_qs_conquer(__begin, __begin + __split,
__comp, __num_threads_left); __comp, __num_threads_left);
#pragma omp section #pragma omp section
__parallel_sort_qs_conquer(__begin + __split, __end, __parallel_sort_qs_conquer(__begin + __split, __end,
__comp, __num_threads - __num_threads_left); __comp, __num_threads - __num_threads_left);
} }
} }
/** @brief Unbalanced quicksort main call. /** @brief Unbalanced quicksort main call.
* @param __begin Begin iterator of input sequence. * @param __begin Begin iterator of input sequence.
* @param __end End iterator input sequence, ignored. * @param __end End iterator input sequence, ignored.
...@@ -154,10 +149,9 @@ namespace __gnu_parallel ...@@ -154,10 +149,9 @@ namespace __gnu_parallel
*/ */
template<typename _RAIter, typename _Compare> template<typename _RAIter, typename _Compare>
void void
__parallel_sort_qs(_RAIter __begin, __parallel_sort_qs(_RAIter __begin, _RAIter __end,
_RAIter __end, _Compare __comp,
_Compare __comp, _ThreadIndex __num_threads)
_ThreadIndex __num_threads)
{ {
_GLIBCXX_CALL(__n) _GLIBCXX_CALL(__n)
......
...@@ -38,7 +38,6 @@ ...@@ -38,7 +38,6 @@
#include <parallel/parallel.h> #include <parallel/parallel.h>
#include <parallel/equally_split.h> #include <parallel/equally_split.h>
namespace __gnu_parallel namespace __gnu_parallel
{ {
/** /**
...@@ -47,24 +46,24 @@ namespace __gnu_parallel ...@@ -47,24 +46,24 @@ namespace __gnu_parallel
* @param __length Length of sequence to search for. * @param __length Length of sequence to search for.
* @param __advances Returned __offsets. * @param __advances Returned __offsets.
*/ */
template<typename _RAIter, typename _DifferenceTp> template<typename _RAIter, typename _DifferenceTp>
void void
__calc_borders(_RAIter __elements, _DifferenceTp __length, __calc_borders(_RAIter __elements, _DifferenceTp __length,
_DifferenceTp* __off) _DifferenceTp* __off)
{ {
typedef _DifferenceTp _DifferenceType; typedef _DifferenceTp _DifferenceType;
__off[0] = -1; __off[0] = -1;
if (__length > 1) if (__length > 1)
__off[1] = 0; __off[1] = 0;
_DifferenceType __k = 0; _DifferenceType __k = 0;
for (_DifferenceType __j = 2; __j <= __length; __j++) for (_DifferenceType __j = 2; __j <= __length; __j++)
{ {
while ((__k >= 0) && !(__elements[__k] == __elements[__j-1])) while ((__k >= 0) && !(__elements[__k] == __elements[__j-1]))
__k = __off[__k]; __k = __off[__k];
__off[__j] = ++__k; __off[__j] = ++__k;
} }
} }
// Generic parallel find algorithm (requires random access iterator). // Generic parallel find algorithm (requires random access iterator).
...@@ -75,100 +74,99 @@ template<typename _RAIter, typename _DifferenceTp> ...@@ -75,100 +74,99 @@ template<typename _RAIter, typename _DifferenceTp>
* @param __end2 End iterator of second sequence. * @param __end2 End iterator of second sequence.
* @param __pred Find predicate. * @param __pred Find predicate.
* @return Place of finding in first sequences. */ * @return Place of finding in first sequences. */
template<typename __RAIter1, template<typename __RAIter1,
typename __RAIter2, typename __RAIter2,
typename _Pred> typename _Pred>
__RAIter1 __RAIter1
__search_template(__RAIter1 __begin1, __RAIter1 __end1, __search_template(__RAIter1 __begin1, __RAIter1 __end1,
__RAIter2 __begin2, __RAIter2 __end2, __RAIter2 __begin2, __RAIter2 __end2,
_Pred __pred) _Pred __pred)
{ {
typedef std::iterator_traits<__RAIter1> _TraitsType; typedef std::iterator_traits<__RAIter1> _TraitsType;
typedef typename _TraitsType::difference_type _DifferenceType; typedef typename _TraitsType::difference_type _DifferenceType;
_GLIBCXX_CALL((__end1 - __begin1) + (__end2 - __begin2)); _GLIBCXX_CALL((__end1 - __begin1) + (__end2 - __begin2));
_DifferenceType __pattern_length = __end2 - __begin2; _DifferenceType __pattern_length = __end2 - __begin2;
// Pattern too short. // Pattern too short.
if(__pattern_length <= 0) if(__pattern_length <= 0)
return __end1; return __end1;
// Last point to start search. // Last point to start search.
_DifferenceType __input_length = (__end1 - __begin1) - __pattern_length; _DifferenceType __input_length = (__end1 - __begin1) - __pattern_length;
// Where is first occurrence of pattern? defaults to end. // Where is first occurrence of pattern? defaults to end.
_DifferenceType __result = (__end1 - __begin1); _DifferenceType __result = (__end1 - __begin1);
_DifferenceType *__splitters; _DifferenceType *__splitters;
// Pattern too long. // Pattern too long.
if (__input_length < 0) if (__input_length < 0)
return __end1; return __end1;
omp_lock_t __result_lock; omp_lock_t __result_lock;
omp_init_lock(&__result_lock); omp_init_lock(&__result_lock);
_ThreadIndex __num_threads = _ThreadIndex __num_threads = std::max<_DifferenceType>
std::max<_DifferenceType>(1, (1, std::min<_DifferenceType>(__input_length,
std::min<_DifferenceType>(__input_length, __get_max_threads())); __get_max_threads()));
_DifferenceType __advances[__pattern_length]; _DifferenceType __advances[__pattern_length];
__calc_borders(__begin2, __pattern_length, __advances); __calc_borders(__begin2, __pattern_length, __advances);
# pragma omp parallel num_threads(__num_threads) # pragma omp parallel num_threads(__num_threads)
{ {
# pragma omp single # pragma omp single
{ {
__num_threads = omp_get_num_threads(); __num_threads = omp_get_num_threads();
__splitters = new _DifferenceType[__num_threads + 1]; __splitters = new _DifferenceType[__num_threads + 1];
equally_split(__input_length, __num_threads, __splitters); equally_split(__input_length, __num_threads, __splitters);
} }
_ThreadIndex __iam = omp_get_thread_num(); _ThreadIndex __iam = omp_get_thread_num();
_DifferenceType __start = __splitters[__iam], _DifferenceType __start = __splitters[__iam],
__stop = __splitters[__iam + 1]; __stop = __splitters[__iam + 1];
_DifferenceType __pos_in_pattern = 0; _DifferenceType __pos_in_pattern = 0;
bool __found_pattern = false; bool __found_pattern = false;
while (__start <= __stop && !__found_pattern) while (__start <= __stop && !__found_pattern)
{ {
// Get new value of result. // Get new value of result.
#pragma omp flush(__result) #pragma omp flush(__result)
// No chance for this thread to find first occurrence. // No chance for this thread to find first occurrence.
if (__result < __start) if (__result < __start)
break; break;
while (__pred(__begin1[__start + __pos_in_pattern], while (__pred(__begin1[__start + __pos_in_pattern],
__begin2[__pos_in_pattern])) __begin2[__pos_in_pattern]))
{ {
++__pos_in_pattern; ++__pos_in_pattern;
if (__pos_in_pattern == __pattern_length) if (__pos_in_pattern == __pattern_length)
{ {
// Found new candidate for result. // Found new candidate for result.
omp_set_lock(&__result_lock); omp_set_lock(&__result_lock);
__result = std::min(__result, __start); __result = std::min(__result, __start);
omp_unset_lock(&__result_lock); omp_unset_lock(&__result_lock);
__found_pattern = true; __found_pattern = true;
break; break;
} }
} }
// Make safe jump. // Make safe jump.
__start += (__pos_in_pattern - __advances[__pos_in_pattern]); __start += (__pos_in_pattern - __advances[__pos_in_pattern]);
__pos_in_pattern = __pos_in_pattern = (__advances[__pos_in_pattern] < 0
(__advances[__pos_in_pattern] < 0) ? ? 0 : __advances[__pos_in_pattern]);
0 : __advances[__pos_in_pattern]; }
}
} //parallel } //parallel
omp_destroy_lock(&__result_lock); omp_destroy_lock(&__result_lock);
delete[] __splitters;
// Return iterator on found element. delete[] __splitters;
return (__begin1 + __result);
} // Return iterator on found element.
return (__begin1 + __result);
}
} // end namespace } // end namespace
#endif /* _GLIBCXX_PARALLEL_SEARCH_H */ #endif /* _GLIBCXX_PARALLEL_SEARCH_H */
...@@ -54,12 +54,12 @@ ...@@ -54,12 +54,12 @@
namespace __gnu_parallel namespace __gnu_parallel
{ {
//prototype //prototype
template<bool __stable, typename _RAIter, template<bool __stable, typename _RAIter,
typename _Compare, typename _Parallelism> typename _Compare, typename _Parallelism>
void void
__parallel_sort(_RAIter __begin, _RAIter __end, __parallel_sort(_RAIter __begin, _RAIter __end,
_Compare __comp, _Parallelism __parallelism); _Compare __comp, _Parallelism __parallelism);
/** /**
* @brief Choose multiway mergesort, splitting variant at run-time, * @brief Choose multiway mergesort, splitting variant at run-time,
...@@ -70,19 +70,19 @@ namespace __gnu_parallel ...@@ -70,19 +70,19 @@ namespace __gnu_parallel
* @callgraph * @callgraph
*/ */
template<bool __stable, typename _RAIter, typename _Compare> template<bool __stable, typename _RAIter, typename _Compare>
inline void inline void
__parallel_sort(_RAIter __begin, _RAIter __end, __parallel_sort(_RAIter __begin, _RAIter __end,
_Compare __comp, multiway_mergesort_tag __parallelism) _Compare __comp, multiway_mergesort_tag __parallelism)
{ {
_GLIBCXX_CALL(__end - __begin) _GLIBCXX_CALL(__end - __begin)
if(_Settings::get().sort_splitting == EXACT) if(_Settings::get().sort_splitting == EXACT)
parallel_sort_mwms<__stable, true> parallel_sort_mwms<__stable, true>
(__begin, __end, __comp, __parallelism.__get_num_threads()); (__begin, __end, __comp, __parallelism.__get_num_threads());
else else
parallel_sort_mwms<__stable, false> parallel_sort_mwms<__stable, false>
(__begin, __end, __comp, __parallelism.__get_num_threads()); (__begin, __end, __comp, __parallelism.__get_num_threads());
} }
/** /**
* @brief Choose multiway mergesort with exact splitting, * @brief Choose multiway mergesort with exact splitting,
...@@ -93,15 +93,16 @@ namespace __gnu_parallel ...@@ -93,15 +93,16 @@ namespace __gnu_parallel
* @callgraph * @callgraph
*/ */
template<bool __stable, typename _RAIter, typename _Compare> template<bool __stable, typename _RAIter, typename _Compare>
inline void inline void
__parallel_sort(_RAIter __begin, _RAIter __end, __parallel_sort(_RAIter __begin, _RAIter __end,
_Compare __comp, multiway_mergesort_exact_tag __parallelism) _Compare __comp,
{ multiway_mergesort_exact_tag __parallelism)
_GLIBCXX_CALL(__end - __begin) {
_GLIBCXX_CALL(__end - __begin)
parallel_sort_mwms<__stable, true> parallel_sort_mwms<__stable, true>
(__begin, __end, __comp, __parallelism.__get_num_threads()); (__begin, __end, __comp, __parallelism.__get_num_threads());
} }
/** /**
* @brief Choose multiway mergesort with splitting by sampling, * @brief Choose multiway mergesort with splitting by sampling,
...@@ -112,15 +113,16 @@ namespace __gnu_parallel ...@@ -112,15 +113,16 @@ namespace __gnu_parallel
* @callgraph * @callgraph
*/ */
template<bool __stable, typename _RAIter, typename _Compare> template<bool __stable, typename _RAIter, typename _Compare>
inline void inline void
__parallel_sort(_RAIter __begin, _RAIter __end, __parallel_sort(_RAIter __begin, _RAIter __end,
_Compare __comp, multiway_mergesort_sampling_tag __parallelism) _Compare __comp,
{ multiway_mergesort_sampling_tag __parallelism)
_GLIBCXX_CALL(__end - __begin) {
_GLIBCXX_CALL(__end - __begin)
parallel_sort_mwms<__stable, false> parallel_sort_mwms<__stable, false>
(__begin, __end, __comp, __parallelism.__get_num_threads()); (__begin, __end, __comp, __parallelism.__get_num_threads());
} }
/** /**
* @brief Choose quicksort for parallel sorting. * @brief Choose quicksort for parallel sorting.
...@@ -130,17 +132,17 @@ namespace __gnu_parallel ...@@ -130,17 +132,17 @@ namespace __gnu_parallel
* @callgraph * @callgraph
*/ */
template<bool __stable, typename _RAIter, typename _Compare> template<bool __stable, typename _RAIter, typename _Compare>
inline void inline void
__parallel_sort(_RAIter __begin, _RAIter __end, __parallel_sort(_RAIter __begin, _RAIter __end,
_Compare __comp, quicksort_tag __parallelism) _Compare __comp, quicksort_tag __parallelism)
{ {
_GLIBCXX_CALL(__end - __begin) _GLIBCXX_CALL(__end - __begin)
_GLIBCXX_PARALLEL_ASSERT(__stable == false); _GLIBCXX_PARALLEL_ASSERT(__stable == false);
__parallel_sort_qs(__begin, __end, __comp, __parallel_sort_qs(__begin, __end, __comp,
__parallelism.__get_num_threads()); __parallelism.__get_num_threads());
} }
/** /**
* @brief Choose balanced quicksort for parallel sorting. * @brief Choose balanced quicksort for parallel sorting.
...@@ -150,19 +152,18 @@ namespace __gnu_parallel ...@@ -150,19 +152,18 @@ namespace __gnu_parallel
* @param __stable Sort __stable. * @param __stable Sort __stable.
* @callgraph * @callgraph
*/ */
template<bool __stable, typename _RAIter, typename _Compare> template<bool __stable, typename _RAIter, typename _Compare>
inline void inline void
__parallel_sort(_RAIter __begin, _RAIter __end, __parallel_sort(_RAIter __begin, _RAIter __end,
_Compare __comp, balanced_quicksort_tag __parallelism) _Compare __comp, balanced_quicksort_tag __parallelism)
{ {
_GLIBCXX_CALL(__end - __begin) _GLIBCXX_CALL(__end - __begin)
_GLIBCXX_PARALLEL_ASSERT(__stable == false);
__parallel_sort_qsb(__begin, __end, __comp, _GLIBCXX_PARALLEL_ASSERT(__stable == false);
__parallelism.__get_num_threads());
}
__parallel_sort_qsb(__begin, __end, __comp,
__parallelism.__get_num_threads());
}
/** /**
* @brief Choose multiway mergesort with exact splitting, * @brief Choose multiway mergesort with exact splitting,
...@@ -173,17 +174,16 @@ namespace __gnu_parallel ...@@ -173,17 +174,16 @@ namespace __gnu_parallel
* @callgraph * @callgraph
*/ */
template<bool __stable, typename _RAIter, typename _Compare> template<bool __stable, typename _RAIter, typename _Compare>
inline void inline void
__parallel_sort(_RAIter __begin, _RAIter __end, __parallel_sort(_RAIter __begin, _RAIter __end,
_Compare __comp, default_parallel_tag __parallelism) _Compare __comp, default_parallel_tag __parallelism)
{ {
_GLIBCXX_CALL(__end - __begin) _GLIBCXX_CALL(__end - __begin)
__parallel_sort<__stable>
(__begin, __end, __comp,
multiway_mergesort_exact_tag(__parallelism.__get_num_threads()));
}
__parallel_sort<__stable>
(__begin, __end, __comp,
multiway_mergesort_exact_tag(__parallelism.__get_num_threads()));
}
/** /**
* @brief Choose a parallel sorting algorithm. * @brief Choose a parallel sorting algorithm.
...@@ -196,7 +196,7 @@ namespace __gnu_parallel ...@@ -196,7 +196,7 @@ namespace __gnu_parallel
template<bool __stable, typename _RAIter, typename _Compare> template<bool __stable, typename _RAIter, typename _Compare>
inline void inline void
__parallel_sort(_RAIter __begin, _RAIter __end, __parallel_sort(_RAIter __begin, _RAIter __end,
_Compare __comp, parallel_tag __parallelism) _Compare __comp, parallel_tag __parallelism)
{ {
_GLIBCXX_CALL(__end - __begin) _GLIBCXX_CALL(__end - __begin)
typedef std::iterator_traits<_RAIter> _TraitsType; typedef std::iterator_traits<_RAIter> _TraitsType;
......
...@@ -51,20 +51,16 @@ namespace __gnu_parallel ...@@ -51,20 +51,16 @@ namespace __gnu_parallel
public: public:
/** @brief Default constructor. Use default number of threads. */ /** @brief Default constructor. Use default number of threads. */
parallel_tag() parallel_tag()
{ { _M_num_threads = 0; }
this->_M_num_threads = 0;
}
/** @brief Default constructor. Recommend number of threads to use. /** @brief Default constructor. Recommend number of threads to use.
* @param __num_threads Desired number of threads. */ * @param __num_threads Desired number of threads. */
parallel_tag(_ThreadIndex __num_threads) parallel_tag(_ThreadIndex __num_threads)
{ { _M_num_threads = __num_threads; }
this->_M_num_threads = __num_threads;
}
/** @brief Find out desired number of threads. /** @brief Find out desired number of threads.
* @return Desired number of threads. */ * @return Desired number of threads. */
inline _ThreadIndex __get_num_threads() _ThreadIndex __get_num_threads()
{ {
if(_M_num_threads == 0) if(_M_num_threads == 0)
return omp_get_max_threads(); return omp_get_max_threads();
...@@ -74,19 +70,17 @@ namespace __gnu_parallel ...@@ -74,19 +70,17 @@ namespace __gnu_parallel
/** @brief Set the desired number of threads. /** @brief Set the desired number of threads.
* @param __num_threads Desired number of threads. */ * @param __num_threads Desired number of threads. */
inline void set_num_threads(_ThreadIndex __num_threads) void set_num_threads(_ThreadIndex __num_threads)
{ { _M_num_threads = __num_threads; }
this->_M_num_threads = __num_threads;
}
}; };
/** @brief Recommends parallel execution using the /** @brief Recommends parallel execution using the
default parallel algorithm. */ default parallel algorithm. */
struct default_parallel_tag : public parallel_tag struct default_parallel_tag : public parallel_tag
{ {
default_parallel_tag() { } default_parallel_tag() { }
default_parallel_tag(_ThreadIndex __num_threads) default_parallel_tag(_ThreadIndex __num_threads)
: parallel_tag(__num_threads) { } : parallel_tag(__num_threads) { }
}; };
/** @brief Recommends parallel execution using dynamic /** @brief Recommends parallel execution using dynamic
...@@ -114,18 +108,18 @@ namespace __gnu_parallel ...@@ -114,18 +108,18 @@ namespace __gnu_parallel
* with exact splitting, at compile time. */ * with exact splitting, at compile time. */
struct exact_tag : public parallel_tag struct exact_tag : public parallel_tag
{ {
exact_tag() { } exact_tag() { }
exact_tag(_ThreadIndex __num_threads) exact_tag(_ThreadIndex __num_threads)
: parallel_tag(__num_threads) { } : parallel_tag(__num_threads) { }
}; };
/** @brief Forces parallel merging /** @brief Forces parallel merging
* with exact splitting, at compile time. */ * with exact splitting, at compile time. */
struct sampling_tag : public parallel_tag struct sampling_tag : public parallel_tag
{ {
sampling_tag() { } sampling_tag() { }
sampling_tag(_ThreadIndex __num_threads) sampling_tag(_ThreadIndex __num_threads)
: parallel_tag(__num_threads) { } : parallel_tag(__num_threads) { }
}; };
...@@ -133,45 +127,45 @@ namespace __gnu_parallel ...@@ -133,45 +127,45 @@ namespace __gnu_parallel
* at compile time. */ * at compile time. */
struct multiway_mergesort_tag : public parallel_tag struct multiway_mergesort_tag : public parallel_tag
{ {
multiway_mergesort_tag() { } multiway_mergesort_tag() { }
multiway_mergesort_tag(_ThreadIndex __num_threads) multiway_mergesort_tag(_ThreadIndex __num_threads)
: parallel_tag(__num_threads) { } : parallel_tag(__num_threads) { }
}; };
/** @brief Forces parallel sorting using multiway mergesort /** @brief Forces parallel sorting using multiway mergesort
* with exact splitting at compile time. */ * with exact splitting at compile time. */
struct multiway_mergesort_exact_tag : public parallel_tag struct multiway_mergesort_exact_tag : public parallel_tag
{ {
multiway_mergesort_exact_tag() { } multiway_mergesort_exact_tag() { }
multiway_mergesort_exact_tag(_ThreadIndex __num_threads) multiway_mergesort_exact_tag(_ThreadIndex __num_threads)
: parallel_tag(__num_threads) { } : parallel_tag(__num_threads) { }
}; };
/** @brief Forces parallel sorting using multiway mergesort /** @brief Forces parallel sorting using multiway mergesort
* with splitting by sampling at compile time. */ * with splitting by sampling at compile time. */
struct multiway_mergesort_sampling_tag : public parallel_tag struct multiway_mergesort_sampling_tag : public parallel_tag
{ {
multiway_mergesort_sampling_tag() { } multiway_mergesort_sampling_tag() { }
multiway_mergesort_sampling_tag(_ThreadIndex __num_threads) multiway_mergesort_sampling_tag(_ThreadIndex __num_threads)
: parallel_tag(__num_threads) { } : parallel_tag(__num_threads) { }
}; };
/** @brief Forces parallel sorting using unbalanced quicksort /** @brief Forces parallel sorting using unbalanced quicksort
* at compile time. */ * at compile time. */
struct quicksort_tag : public parallel_tag struct quicksort_tag : public parallel_tag
{ {
quicksort_tag() { } quicksort_tag() { }
quicksort_tag(_ThreadIndex __num_threads) quicksort_tag(_ThreadIndex __num_threads)
: parallel_tag(__num_threads) { } : parallel_tag(__num_threads) { }
}; };
/** @brief Forces parallel sorting using balanced quicksort /** @brief Forces parallel sorting using balanced quicksort
* at compile time. */ * at compile time. */
struct balanced_quicksort_tag : public parallel_tag struct balanced_quicksort_tag : public parallel_tag
{ {
balanced_quicksort_tag() { } balanced_quicksort_tag() { }
balanced_quicksort_tag(_ThreadIndex __num_threads) balanced_quicksort_tag(_ThreadIndex __num_threads)
: parallel_tag(__num_threads) { } : parallel_tag(__num_threads) { }
}; };
......
...@@ -37,155 +37,160 @@ ...@@ -37,155 +37,160 @@
namespace __gnu_parallel namespace __gnu_parallel
{ {
/** @brief Parallel std::unique_copy(), w/__o explicit equality predicate.
/** @brief Parallel std::unique_copy(), w/__o explicit equality predicate. * @param __first Begin iterator of input sequence.
* @param __first Begin iterator of input sequence. * @param __last End iterator of input sequence.
* @param __last End iterator of input sequence. * @param __result Begin iterator of result __sequence.
* @param __result Begin iterator of result __sequence. * @param __binary_pred Equality predicate.
* @param __binary_pred Equality predicate. * @return End iterator of result __sequence. */
* @return End iterator of result __sequence. */ template<typename _IIter,
template<typename _IIter, class _OutputIterator,
class _OutputIterator, class _BinaryPredicate>
class _BinaryPredicate> _OutputIterator
_OutputIterator __parallel_unique_copy(_IIter __first, _IIter __last,
__parallel_unique_copy(_IIter __first, _IIter __last, _OutputIterator __result,
_OutputIterator __result, _BinaryPredicate __binary_pred) _BinaryPredicate __binary_pred)
{ {
_GLIBCXX_CALL(__last - __first) _GLIBCXX_CALL(__last - __first)
typedef std::iterator_traits<_IIter> _TraitsType; typedef std::iterator_traits<_IIter> _TraitsType;
typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::value_type _ValueType;
typedef typename _TraitsType::difference_type _DifferenceType; typedef typename _TraitsType::difference_type _DifferenceType;
_DifferenceType size = __last - __first; _DifferenceType __size = __last - __first;
if (size == 0) if (__size == 0)
return __result; return __result;
// Let the first thread process two parts. // Let the first thread process two parts.
_DifferenceType *__counter; _DifferenceType *__counter;
_DifferenceType *__borders; _DifferenceType *__borders;
_ThreadIndex __num_threads = __get_max_threads(); _ThreadIndex __num_threads = __get_max_threads();
// First part contains at least one element. // First part contains at least one element.
# pragma omp parallel num_threads(__num_threads) # pragma omp parallel num_threads(__num_threads)
{ {
# pragma omp single # pragma omp single
{
__num_threads = omp_get_num_threads();
__borders = new _DifferenceType[__num_threads + 2];
equally_split(__size, __num_threads + 1, __borders);
__counter = new _DifferenceType[__num_threads + 1];
}
_ThreadIndex __iam = omp_get_thread_num();
_DifferenceType __begin, __end;
// Check for length without duplicates
// Needed for position in output
_DifferenceType __i = 0;
_OutputIterator __out = __result;
if (__iam == 0)
{ {
__num_threads = omp_get_num_threads(); __begin = __borders[0] + 1; // == 1
__borders = new _DifferenceType[__num_threads + 2]; __end = __borders[__iam + 1];
equally_split(size, __num_threads + 1, __borders);
__counter = new _DifferenceType[__num_threads + 1]; ++__i;
*__out++ = *__first;
for (_IIter __iter = __first + __begin; __iter < __first + __end;
++__iter)
{
if (!__binary_pred(*__iter, *(__iter - 1)))
{
++__i;
*__out++ = *__iter;
}
}
} }
else
{
__begin = __borders[__iam]; //one part
__end = __borders[__iam + 1];
_ThreadIndex __iam = omp_get_thread_num(); for (_IIter __iter = __first + __begin; __iter < __first + __end;
++__iter)
{
if (!__binary_pred(*__iter, *(__iter - 1)))
++__i;
}
}
__counter[__iam] = __i;
_DifferenceType __begin, __end; // Last part still untouched.
_DifferenceType __begin_output;
// Check for length without duplicates # pragma omp barrier
// Needed for position in output
_DifferenceType __i = 0;
_OutputIterator __out = __result;
if (__iam == 0) // Store result in output on calculated positions.
{ __begin_output = 0;
__begin = __borders[0] + 1; // == 1
__end = __borders[__iam + 1];
++__i; if (__iam == 0)
*__out++ = *__first; {
for (int __t = 0; __t < __num_threads; ++__t)
__begin_output += __counter[__t];
for (_IIter iter = __first + __begin; iter < __first + __end; ++iter) __i = 0;
{
if (!__binary_pred(*iter, *(iter-1))) _OutputIterator __iter_out = __result + __begin_output;
{
++__i; __begin = __borders[__num_threads];
*__out++ = *iter; __end = __size;
}
} for (_IIter __iter = __first + __begin; __iter < __first + __end;
} ++__iter)
else {
{ if (__iter == __first
__begin = __borders[__iam]; //one part || !__binary_pred(*__iter, *(__iter - 1)))
__end = __borders[__iam + 1]; {
++__i;
for (_IIter iter = __first + __begin; iter < __first + __end; ++iter) *__iter_out++ = *__iter;
{ }
if (!__binary_pred(*iter, *(iter - 1))) }
++__i;
} __counter[__num_threads] = __i;
} }
__counter[__iam] = __i; else
{
// Last part still untouched. for (int __t = 0; __t < __iam; __t++)
_DifferenceType __begin_output; __begin_output += __counter[__t];
# pragma omp barrier _OutputIterator __iter_out = __result + __begin_output;
for (_IIter __iter = __first + __begin; __iter < __first + __end;
// Store result in output on calculated positions. ++__iter)
__begin_output = 0; {
if (!__binary_pred(*__iter, *(__iter - 1)))
if (__iam == 0) *__iter_out++ = *__iter;
{ }
for (int __t = 0; __t < __num_threads; ++__t) }
__begin_output += __counter[__t]; }
__i = 0; _DifferenceType __end_output = 0;
for (int __t = 0; __t < __num_threads + 1; __t++)
_OutputIterator __iter_out = __result + __begin_output; __end_output += __counter[__t];
__begin = __borders[__num_threads]; delete[] __borders;
__end = size;
return __result + __end_output;
for (_IIter iter = __first + __begin; iter < __first + __end; ++iter)
{
if (iter == __first || !__binary_pred(*iter, *(iter - 1)))
{
++__i;
*__iter_out++ = *iter;
}
}
__counter[__num_threads] = __i;
}
else
{
for (int __t = 0; __t < __iam; __t++)
__begin_output += __counter[__t];
_OutputIterator __iter_out = __result + __begin_output;
for (_IIter iter = __first + __begin; iter < __first + __end; ++iter)
{
if (!__binary_pred(*iter, *(iter-1)))
*__iter_out++ = *iter;
}
}
} }
_DifferenceType __end_output = 0; /** @brief Parallel std::unique_copy(), without explicit equality predicate
for (int __t = 0; __t < __num_threads + 1; __t++) * @param __first Begin iterator of input sequence.
__end_output += __counter[__t]; * @param __last End iterator of input sequence.
* @param __result Begin iterator of result __sequence.
delete[] __borders; * @return End iterator of result __sequence. */
template<typename _IIter, class _OutputIterator>
return __result + __end_output; inline _OutputIterator
} __parallel_unique_copy(_IIter __first, _IIter __last,
_OutputIterator __result)
/** @brief Parallel std::unique_copy(), without explicit equality predicate {
* @param __first Begin iterator of input sequence. typedef typename std::iterator_traits<_IIter>::value_type
* @param __last End iterator of input sequence. _ValueType;
* @param __result Begin iterator of result __sequence. return __parallel_unique_copy(__first, __last, __result,
* @return End iterator of result __sequence. */ std::equal_to<_ValueType>());
template<typename _IIter, class _OutputIterator> }
inline _OutputIterator
__parallel_unique_copy(_IIter __first, _IIter __last,
_OutputIterator __result)
{
typedef typename std::iterator_traits<_IIter>::value_type
_ValueType;
return __parallel_unique_copy(__first, __last, __result,
std::equal_to<_ValueType>());
}
}//namespace __gnu_parallel }//namespace __gnu_parallel
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment