Commit d7066497 by Johannes Singler Committed by Johannes Singler

quicksort.h: Reformat,

2008-04-23  Johannes Singler  <singler@ira.uka.de>

        * include/parallel/quicksort.h: Reformat,
        (parallel_sort_qs): Do not pass number of elements.
        * include/parallel/balanced_quicksort.h: Reformat,
        (parallel_sort_qsb): Do not pass number of elements.
        * include/parallel/tags.h:
        Introduce new tags for compile-time choice.
        * include/parallel/merge.h:
        (parallel_merge_advance):Beautified.
        * include/parallel/algo.h: Reformatting (spaces for tabs)
        New sort and stable_sort variants, corresponding to the tags.
        * include/parallel/sort.h:
        New sort and stable_sort variants, corresponding to the tags.
        Changed determining the desired number of threads.

From-SVN: r134582
parent 214ece29
2008-04-23 Johannes Singler <singler@ira.uka.de> 2008-04-23 Johannes Singler <singler@ira.uka.de>
* include/parallel/quicksort.h: Reformat,
(parallel_sort_qs): Do not pass number of elements.
* include/parallel/balanced_quicksort.h: Reformat,
(parallel_sort_qsb): Do not pass number of elements.
* include/parallel/tags.h:
Introduce new tags for compile-time choice.
* include/parallel/merge.h:
(parallel_merge_advance):Beautified.
* include/parallel/algo.h: Reformatting (spaces for tabs)
New sort and stable_sort variants, corresponding to the tags.
* include/parallel/sort.h:
New sort and stable_sort variants, corresponding to the tags.
Changed determining the desired number of threads.
2008-04-23 Johannes Singler <singler@ira.uka.de>
* include/parallel/multiway_merge.h * include/parallel/multiway_merge.h
(multiway_merge_loser_tree): (multiway_merge_loser_tree):
Leave checks to callers, add precondition instead. Leave checks to callers, add precondition instead.
......
...@@ -75,6 +75,7 @@ namespace __parallel ...@@ -75,6 +75,7 @@ namespace __parallel
__gnu_parallel::sequential_tag) __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_P::for_each(begin, end, f); } { return _GLIBCXX_STD_P::for_each(begin, end, f); }
// Sequential fallback for input iterator case // Sequential fallback for input iterator case
template<typename InputIterator, typename Function, typename IteratorTag> template<typename InputIterator, typename Function, typename IteratorTag>
inline Function inline Function
...@@ -1309,7 +1310,8 @@ namespace __parallel ...@@ -1309,7 +1310,8 @@ namespace __parallel
= __gnu_parallel::parallel_balanced) = __gnu_parallel::parallel_balanced)
{ {
if (_GLIBCXX_PARALLEL_CONDITION( if (_GLIBCXX_PARALLEL_CONDITION(
(end1 - begin1) >= __gnu_parallel::_Settings::get().transform_minimal_n (end1 - begin1) >=
__gnu_parallel::_Settings::get().transform_minimal_n
&& __gnu_parallel::is_parallel(parallelism_tag))) && __gnu_parallel::is_parallel(parallelism_tag)))
{ {
bool dummy = true; bool dummy = true;
...@@ -1711,6 +1713,8 @@ namespace __parallel ...@@ -1711,6 +1713,8 @@ namespace __parallel
return partition_switch(begin, end, pred, iterator_category()); return partition_switch(begin, end, pred, iterator_category());
} }
// sort interface
// Sequential fallback // Sequential fallback
template<typename RandomAccessIterator> template<typename RandomAccessIterator>
inline void inline void
...@@ -1726,6 +1730,27 @@ namespace __parallel ...@@ -1726,6 +1730,27 @@ namespace __parallel
{ _GLIBCXX_STD_P::sort<RandomAccessIterator, Comparator>(begin, end, { _GLIBCXX_STD_P::sort<RandomAccessIterator, Comparator>(begin, end,
comp); } comp); }
// Public interface
template<typename RandomAccessIterator, typename Comparator,
typename Parallelism>
void
sort(RandomAccessIterator begin, RandomAccessIterator end, Comparator comp,
Parallelism parallelism)
{
typedef iterator_traits<RandomAccessIterator> traits_type;
typedef typename traits_type::value_type value_type;
if (begin != end)
{
if (_GLIBCXX_PARALLEL_CONDITION(
static_cast<__gnu_parallel::sequence_index_t>(end - begin) >=
__gnu_parallel::_Settings::get().sort_minimal_n))
__gnu_parallel::parallel_sort<false>(begin, end, comp, parallelism);
else
sort(begin, end, comp, __gnu_parallel::sequential_tag());
}
}
// Public interface, insert default comparator // Public interface, insert default comparator
template<typename RandomAccessIterator> template<typename RandomAccessIterator>
inline void inline void
...@@ -1733,67 +1758,256 @@ namespace __parallel ...@@ -1733,67 +1758,256 @@ namespace __parallel
{ {
typedef iterator_traits<RandomAccessIterator> traits_type; typedef iterator_traits<RandomAccessIterator> traits_type;
typedef typename traits_type::value_type value_type; typedef typename traits_type::value_type value_type;
sort(begin, end, std::less<value_type>()); sort(begin, end, std::less<value_type>(),
__gnu_parallel::default_parallel_tag());
} }
// Public interface, insert default comparator
template<typename RandomAccessIterator>
inline void
sort(RandomAccessIterator begin, RandomAccessIterator end,
__gnu_parallel::default_parallel_tag parallelism)
{
typedef iterator_traits<RandomAccessIterator> traits_type;
typedef typename traits_type::value_type value_type;
sort(begin, end, std::less<value_type>(), parallelism);
}
// Public interface, insert default comparator
template<typename RandomAccessIterator>
inline void
sort(RandomAccessIterator begin, RandomAccessIterator end,
__gnu_parallel::parallel_tag parallelism)
{
typedef iterator_traits<RandomAccessIterator> traits_type;
typedef typename traits_type::value_type value_type;
sort(begin, end, std::less<value_type>(), parallelism);
}
// Public interface, insert default comparator
template<typename RandomAccessIterator>
inline void
sort(RandomAccessIterator begin, RandomAccessIterator end,
__gnu_parallel::multiway_mergesort_tag parallelism)
{
typedef iterator_traits<RandomAccessIterator> traits_type;
typedef typename traits_type::value_type value_type;
sort(begin, end, std::less<value_type>(), parallelism);
}
// Public interface, insert default comparator
template<typename RandomAccessIterator>
inline void
sort(RandomAccessIterator begin, RandomAccessIterator end,
__gnu_parallel::multiway_mergesort_sampling_tag parallelism)
{
typedef iterator_traits<RandomAccessIterator> traits_type;
typedef typename traits_type::value_type value_type;
sort(begin, end, std::less<value_type>(), parallelism);
}
// Public interface, insert default comparator
template<typename RandomAccessIterator>
inline void
sort(RandomAccessIterator begin, RandomAccessIterator end,
__gnu_parallel::multiway_mergesort_exact_tag parallelism)
{
typedef iterator_traits<RandomAccessIterator> traits_type;
typedef typename traits_type::value_type value_type;
sort(begin, end, std::less<value_type>(), parallelism);
}
// Public interface, insert default comparator
template<typename RandomAccessIterator>
inline void
sort(RandomAccessIterator begin, RandomAccessIterator end,
__gnu_parallel::quicksort_tag parallelism)
{
typedef iterator_traits<RandomAccessIterator> traits_type;
typedef typename traits_type::value_type value_type;
sort(begin, end, std::less<value_type>(), parallelism);
}
// Public interface, insert default comparator
template<typename RandomAccessIterator>
inline void
sort(RandomAccessIterator begin, RandomAccessIterator end,
__gnu_parallel::balanced_quicksort_tag parallelism)
{
typedef iterator_traits<RandomAccessIterator> traits_type;
typedef typename traits_type::value_type value_type;
sort(begin, end, std::less<value_type>(), parallelism);
}
// Public interface
template<typename RandomAccessIterator, typename Comparator> template<typename RandomAccessIterator, typename Comparator>
void void
sort(RandomAccessIterator begin, RandomAccessIterator end, Comparator comp) sort(RandomAccessIterator begin, RandomAccessIterator end, Comparator comp)
{ {
typedef iterator_traits<RandomAccessIterator> traits_type; typedef iterator_traits<RandomAccessIterator> traits_type;
typedef typename traits_type::value_type value_type; typedef typename traits_type::value_type value_type;
sort(begin, end, comp, __gnu_parallel::default_parallel_tag());
}
// stable_sort interface
// Sequential fallback
template<typename RandomAccessIterator>
inline void
stable_sort(RandomAccessIterator begin, RandomAccessIterator end,
__gnu_parallel::sequential_tag)
{ _GLIBCXX_STD_P::stable_sort(begin, end); }
// Sequential fallback
template<typename RandomAccessIterator, typename Comparator>
inline void
stable_sort(RandomAccessIterator begin, RandomAccessIterator end,
Comparator comp, __gnu_parallel::sequential_tag)
{ _GLIBCXX_STD_P::stable_sort<RandomAccessIterator, Comparator>(
begin, end, comp); }
// Public interface
template<typename RandomAccessIterator, typename Comparator,
typename Parallelism>
void
stable_sort(RandomAccessIterator begin, RandomAccessIterator end,
Comparator comp, Parallelism parallelism)
{
typedef iterator_traits<RandomAccessIterator> traits_type;
typedef typename traits_type::value_type value_type;
if (begin != end) if (begin != end)
{ {
if (_GLIBCXX_PARALLEL_CONDITION( if (_GLIBCXX_PARALLEL_CONDITION(
static_cast<__gnu_parallel::sequence_index_t>(end - begin) static_cast<__gnu_parallel::sequence_index_t>(end - begin) >=
>= __gnu_parallel::_Settings::get().sort_minimal_n)) __gnu_parallel::_Settings::get().sort_minimal_n))
__gnu_parallel::parallel_sort(begin, end, comp, false); __gnu_parallel::parallel_sort<true>(begin, end, comp, parallelism);
else else
sort(begin, end, comp, __gnu_parallel::sequential_tag()); stable_sort(begin, end, comp, __gnu_parallel::sequential_tag());
} }
} }
// Sequential fallback. // Public interface, insert default comparator
template<typename RandomAccessIterator>
inline void
stable_sort(RandomAccessIterator begin, RandomAccessIterator end)
{
typedef iterator_traits<RandomAccessIterator> traits_type;
typedef typename traits_type::value_type value_type;
stable_sort(begin, end, std::less<value_type>(),
__gnu_parallel::default_parallel_tag());
}
// Public interface, insert default comparator
template<typename RandomAccessIterator> template<typename RandomAccessIterator>
inline void inline void
stable_sort(RandomAccessIterator begin, RandomAccessIterator end, stable_sort(RandomAccessIterator begin, RandomAccessIterator end,
__gnu_parallel::sequential_tag) __gnu_parallel::default_parallel_tag parallelism)
{ return _GLIBCXX_STD_P::stable_sort(begin, end); } {
typedef iterator_traits<RandomAccessIterator> traits_type;
typedef typename traits_type::value_type value_type;
stable_sort(begin, end, std::less<value_type>(), parallelism);
}
// Sequential fallback. // Public interface, insert default comparator
template<typename RandomAccessIterator, typename Comparator> template<typename RandomAccessIterator>
inline void inline void
stable_sort(RandomAccessIterator begin, RandomAccessIterator end, stable_sort(RandomAccessIterator begin, RandomAccessIterator end,
Comparator comp, __gnu_parallel::sequential_tag) __gnu_parallel::parallel_tag parallelism)
{ return _GLIBCXX_STD_P::stable_sort(begin, end, comp); } {
typedef iterator_traits<RandomAccessIterator> traits_type;
typedef typename traits_type::value_type value_type;
stable_sort(begin, end, std::less<value_type>(), parallelism);
}
// Public interface, insert default comparator
template<typename RandomAccessIterator> template<typename RandomAccessIterator>
inline void inline void
stable_sort(RandomAccessIterator begin, RandomAccessIterator end) stable_sort(RandomAccessIterator begin, RandomAccessIterator end,
__gnu_parallel::multiway_mergesort_tag parallelism)
{ {
typedef iterator_traits<RandomAccessIterator> traits_type; typedef iterator_traits<RandomAccessIterator> traits_type;
typedef typename traits_type::value_type value_type; typedef typename traits_type::value_type value_type;
stable_sort(begin, end, std::less<value_type>()); stable_sort(begin, end, std::less<value_type>(), parallelism);
} }
// Parallel algorithm for random access iterators // Public interface, insert default comparator
template<typename RandomAccessIterator>
inline void
stable_sort(RandomAccessIterator begin, RandomAccessIterator end,
__gnu_parallel::quicksort_tag parallelism)
{
typedef iterator_traits<RandomAccessIterator> traits_type;
typedef typename traits_type::value_type value_type;
stable_sort(begin, end, std::less<value_type>(), parallelism);
}
// Public interface, insert default comparator
template<typename RandomAccessIterator>
inline void
stable_sort(RandomAccessIterator begin, RandomAccessIterator end,
__gnu_parallel::balanced_quicksort_tag parallelism)
{
typedef iterator_traits<RandomAccessIterator> traits_type;
typedef typename traits_type::value_type value_type;
stable_sort(begin, end, std::less<value_type>(), parallelism);
}
// Public interface
template<typename RandomAccessIterator, typename Comparator> template<typename RandomAccessIterator, typename Comparator>
void void
stable_sort(RandomAccessIterator begin, RandomAccessIterator end, stable_sort(RandomAccessIterator begin, RandomAccessIterator end,
Comparator comp) Comparator comp)
{ {
if (begin != end) typedef iterator_traits<RandomAccessIterator> traits_type;
{ typedef typename traits_type::value_type value_type;
if (_GLIBCXX_PARALLEL_CONDITION( stable_sort(begin, end, comp, __gnu_parallel::default_parallel_tag());
static_cast<__gnu_parallel::sequence_index_t>(end - begin)
>= __gnu_parallel::_Settings::get().sort_minimal_n))
__gnu_parallel::parallel_sort(begin, end, comp, true);
else
stable_sort(begin, end, comp, __gnu_parallel::sequential_tag());
}
} }
// // Sequential fallback
// template<typename RandomAccessIterator>
// inline void
// stable_sort(RandomAccessIterator begin, RandomAccessIterator end,
// __gnu_parallel::sequential_tag)
// { return _GLIBCXX_STD_P::stable_sort(begin, end); }
//
// // Sequential fallback
// template<typename RandomAccessIterator, typename Comparator>
// inline void
// stable_sort(RandomAccessIterator begin, RandomAccessIterator end,
// Comparator comp, __gnu_parallel::sequential_tag)
// { return _GLIBCXX_STD_P::stable_sort(begin, end, comp); }
//
// template<typename RandomAccessIterator>
// void
// stable_sort(RandomAccessIterator begin, RandomAccessIterator end)
// {
// typedef iterator_traits<RandomAccessIterator> traits_type;
// typedef typename traits_type::value_type value_type;
// stable_sort(begin, end, std::less<value_type>());
// }
//
// // Parallel algorithm for random access iterators
// template<typename RandomAccessIterator, typename Comparator>
// void
// stable_sort(RandomAccessIterator begin, RandomAccessIterator end,
// Comparator comp)
// {
// if (begin != end)
// {
// if (_GLIBCXX_PARALLEL_CONDITION(
// static_cast<__gnu_parallel::sequence_index_t>(end - begin) >=
// __gnu_parallel::_Settings::get().sort_minimal_n))
// __gnu_parallel::parallel_sort(begin, end, comp,
// __gnu_parallel::parallel_tag());
// else
// stable_sort(begin, end, comp, __gnu_parallel::sequential_tag());
// }
// }
// Sequential fallback // Sequential fallback
template<typename InputIterator1, typename InputIterator2, template<typename InputIterator1, typename InputIterator2,
typename OutputIterator> typename OutputIterator>
......
...@@ -252,7 +252,8 @@ template<typename RandomAccessIterator, typename Comparator> ...@@ -252,7 +252,8 @@ template<typename RandomAccessIterator, typename Comparator>
QSBThreadLocal<RandomAccessIterator>& tl = *tls[iam]; QSBThreadLocal<RandomAccessIterator>& tl = *tls[iam];
difference_type base_case_n = _Settings::get().sort_qsb_base_case_maximal_n; difference_type base_case_n =
_Settings::get().sort_qsb_base_case_maximal_n;
if (base_case_n < 2) if (base_case_n < 2)
base_case_n = 2; base_case_n = 2;
thread_index_t num_threads = tl.num_threads; thread_index_t num_threads = tl.num_threads;
...@@ -415,7 +416,6 @@ template<typename RandomAccessIterator, typename Comparator> ...@@ -415,7 +416,6 @@ template<typename RandomAccessIterator, typename Comparator>
* @param begin Begin iterator of sequence. * @param begin Begin iterator of sequence.
* @param end End iterator of sequence. * @param end End iterator of sequence.
* @param comp Comparator. * @param comp Comparator.
* @param n Length of the sequence to sort.
* @param num_threads Number of threads that are allowed to work on * @param num_threads Number of threads that are allowed to work on
* this part. * this part.
*/ */
...@@ -423,8 +423,6 @@ template<typename RandomAccessIterator, typename Comparator> ...@@ -423,8 +423,6 @@ template<typename RandomAccessIterator, typename Comparator>
void void
parallel_sort_qsb(RandomAccessIterator begin, RandomAccessIterator end, parallel_sort_qsb(RandomAccessIterator begin, RandomAccessIterator end,
Comparator comp, Comparator comp,
typename std::iterator_traits<RandomAccessIterator>
::difference_type n,
thread_index_t num_threads) thread_index_t num_threads)
{ {
_GLIBCXX_CALL(end - begin) _GLIBCXX_CALL(end - begin)
...@@ -436,6 +434,8 @@ template<typename RandomAccessIterator, typename Comparator> ...@@ -436,6 +434,8 @@ template<typename RandomAccessIterator, typename Comparator>
typedef QSBThreadLocal<RandomAccessIterator> tls_type; typedef QSBThreadLocal<RandomAccessIterator> tls_type;
difference_type n = end - begin;
if (n <= 1) if (n <= 1)
return; return;
......
...@@ -248,7 +248,7 @@ namespace __gnu_parallel ...@@ -248,7 +248,7 @@ namespace __gnu_parallel
typedef typename std::pair<RandomAccessIterator1, RandomAccessIterator1> typedef typename std::pair<RandomAccessIterator1, RandomAccessIterator1>
iterator_pair; iterator_pair;
std::pair<RandomAccessIterator1, RandomAccessIterator1> iterator_pair
seqs[2] = { std::make_pair(begin1, end1), seqs[2] = { std::make_pair(begin1, end1),
std::make_pair(begin2, end2) }; std::make_pair(begin2, end2) };
RandomAccessIterator3 RandomAccessIterator3
......
...@@ -87,7 +87,8 @@ namespace __gnu_parallel ...@@ -87,7 +87,8 @@ namespace __gnu_parallel
__gnu_parallel::binder2nd<Comparator, value_type, value_type, bool> __gnu_parallel::binder2nd<Comparator, value_type, value_type, bool>
pred(comp, pivot); pred(comp, pivot);
difference_type split = parallel_partition(begin, end, pred, num_threads); difference_type split =
parallel_partition(begin, end, pred, num_threads);
::operator delete(samples); ::operator delete(samples);
...@@ -154,7 +155,6 @@ namespace __gnu_parallel ...@@ -154,7 +155,6 @@ namespace __gnu_parallel
* @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.
* @param comp Comparator. * @param comp Comparator.
* @param n Length of input sequence.
* @param num_threads Number of threads that are allowed to work on * @param num_threads Number of threads that are allowed to work on
* this part. * this part.
*/ */
...@@ -162,9 +162,8 @@ namespace __gnu_parallel ...@@ -162,9 +162,8 @@ namespace __gnu_parallel
void void
parallel_sort_qs(RandomAccessIterator begin, parallel_sort_qs(RandomAccessIterator begin,
RandomAccessIterator end, RandomAccessIterator end,
Comparator comp, typename std::iterator_traits Comparator comp,
<RandomAccessIterator>::difference_type n, thread_index_t num_threads)
int num_threads)
{ {
_GLIBCXX_CALL(n) _GLIBCXX_CALL(n)
...@@ -172,8 +171,7 @@ namespace __gnu_parallel ...@@ -172,8 +171,7 @@ namespace __gnu_parallel
typedef typename traits_type::value_type value_type; typedef typename traits_type::value_type value_type;
typedef typename traits_type::difference_type difference_type; typedef typename traits_type::difference_type difference_type;
if (n == 0) difference_type n = end - begin;
return;
// At least one element per processor. // At least one element per processor.
if (num_threads > n) if (num_threads > n)
......
...@@ -60,6 +60,135 @@ ...@@ -60,6 +60,135 @@
namespace __gnu_parallel namespace __gnu_parallel
{ {
//prototype
template<bool stable, typename RandomAccessIterator,
typename Comparator, typename Parallelism>
void
parallel_sort(RandomAccessIterator begin, RandomAccessIterator end,
Comparator comp, Parallelism parallelism);
/**
* @brief Choose multiway mergesort, splitting variant at run-time,
* for parallel sorting.
* @param begin Begin iterator of input sequence.
* @param end End iterator of input sequence.
* @param comp Comparator.
* @callgraph
*/
template<bool stable, typename RandomAccessIterator, typename Comparator>
inline void
parallel_sort(RandomAccessIterator begin, RandomAccessIterator end,
Comparator comp, multiway_mergesort_tag parallelism)
{
_GLIBCXX_CALL(end - begin)
if(_Settings::get().sort_splitting == EXACT)
parallel_sort_mwms<stable, true>
(begin, end, comp, parallelism.get_num_threads());
else
parallel_sort_mwms<stable, false>
(begin, end, comp, parallelism.get_num_threads());
}
/**
* @brief Choose multiway mergesort with exact splitting,
* for parallel sorting.
* @param begin Begin iterator of input sequence.
* @param end End iterator of input sequence.
* @param comp Comparator.
* @callgraph
*/
template<bool stable, typename RandomAccessIterator, typename Comparator>
inline void
parallel_sort(RandomAccessIterator begin, RandomAccessIterator end,
Comparator comp, multiway_mergesort_exact_tag parallelism)
{
_GLIBCXX_CALL(end - begin)
parallel_sort_mwms<stable, true>
(begin, end, comp, parallelism.get_num_threads());
}
/**
* @brief Choose multiway mergesort with splitting by sampling,
* for parallel sorting.
* @param begin Begin iterator of input sequence.
* @param end End iterator of input sequence.
* @param comp Comparator.
* @callgraph
*/
template<bool stable, typename RandomAccessIterator, typename Comparator>
inline void
parallel_sort(RandomAccessIterator begin, RandomAccessIterator end,
Comparator comp, multiway_mergesort_sampling_tag parallelism)
{
_GLIBCXX_CALL(end - begin)
parallel_sort_mwms<stable, false>
(begin, end, comp, parallelism.get_num_threads());
}
/**
* @brief Choose quicksort for parallel sorting.
* @param begin Begin iterator of input sequence.
* @param end End iterator of input sequence.
* @param comp Comparator.
* @callgraph
*/
template<bool stable, typename RandomAccessIterator, typename Comparator>
inline void
parallel_sort(RandomAccessIterator begin, RandomAccessIterator end,
Comparator comp, quicksort_tag parallelism)
{
_GLIBCXX_CALL(end - begin)
_GLIBCXX_PARALLEL_ASSERT(stable == false);
parallel_sort_qs(begin, end, comp, parallelism.get_num_threads());
}
/**
* @brief Choose balanced quicksort for parallel sorting.
* @param begin Begin iterator of input sequence.
* @param end End iterator of input sequence.
* @param comp Comparator.
* @param stable Sort stable.
* @callgraph
*/
template<bool stable, typename RandomAccessIterator, typename Comparator>
inline void
parallel_sort(RandomAccessIterator begin, RandomAccessIterator end,
Comparator comp, balanced_quicksort_tag parallelism)
{
_GLIBCXX_CALL(end - begin)
_GLIBCXX_PARALLEL_ASSERT(stable == false);
parallel_sort_qsb(begin, end, comp, parallelism.get_num_threads());
}
/**
* @brief Choose multiway mergesort with exact splitting,
* for parallel sorting.
* @param begin Begin iterator of input sequence.
* @param end End iterator of input sequence.
* @param comp Comparator.
* @callgraph
*/
template<bool stable, typename RandomAccessIterator, typename Comparator>
inline void
parallel_sort(RandomAccessIterator begin, RandomAccessIterator end,
Comparator comp, default_parallel_tag parallelism)
{
_GLIBCXX_CALL(end - begin)
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.
* @param begin Begin iterator of input sequence. * @param begin Begin iterator of input sequence.
...@@ -68,55 +197,39 @@ namespace __gnu_parallel ...@@ -68,55 +197,39 @@ namespace __gnu_parallel
* @param stable Sort stable. * @param stable Sort stable.
* @callgraph * @callgraph
*/ */
template<typename RandomAccessIterator, typename Comparator> template<bool stable, typename RandomAccessIterator, typename Comparator>
inline void inline void
parallel_sort(RandomAccessIterator begin, RandomAccessIterator end, parallel_sort(RandomAccessIterator begin, RandomAccessIterator end,
Comparator comp, bool stable) Comparator comp, parallel_tag parallelism)
{ {
_GLIBCXX_CALL(end - begin) _GLIBCXX_CALL(end - begin)
typedef std::iterator_traits<RandomAccessIterator> traits_type; typedef std::iterator_traits<RandomAccessIterator> traits_type;
typedef typename traits_type::value_type value_type; typedef typename traits_type::value_type value_type;
typedef typename traits_type::difference_type difference_type; typedef typename traits_type::difference_type difference_type;
if (begin != end)
{
difference_type n = end - begin;
if (false) ; if (false) ;
#if _GLIBCXX_MERGESORT #if _GLIBCXX_MERGESORT
else if (stable) else if (stable || _Settings::get().sort_algorithm == MWMS)
{ {
if(_Settings::get().sort_splitting == EXACT) if(_Settings::get().sort_splitting == EXACT)
parallel_sort_mwms<true, true> parallel_sort_mwms<stable, true>
(begin, end, comp, get_max_threads()); (begin, end, comp, parallelism.get_num_threads());
else
parallel_sort_mwms<true, false>
(begin, end, comp, get_max_threads());
}
else if (_Settings::get().sort_algorithm == MWMS)
{
if(_Settings::get().sort_splitting == EXACT)
parallel_sort_mwms<false, true>
(begin, end, comp, get_max_threads());
else else
parallel_sort_mwms<false, false> parallel_sort_mwms<false, false>
(begin, end, comp, get_max_threads()); (begin, end, comp, parallelism.get_num_threads());
} }
#endif #endif
#if _GLIBCXX_QUICKSORT #if _GLIBCXX_QUICKSORT
else if (!stable && _Settings::get().sort_algorithm == QS) else if (_Settings::get().sort_algorithm == QS)
parallel_sort_qs(begin, end, comp, n, get_max_threads()); parallel_sort_qs(begin, end, comp, parallelism.get_num_threads());
#endif #endif
#if _GLIBCXX_BAL_QUICKSORT #if _GLIBCXX_BAL_QUICKSORT
else if (!stable && _Settings::get().sort_algorithm == QS_BALANCED) else if (_Settings::get().sort_algorithm == QS_BALANCED)
parallel_sort_qsb(begin, end, comp, n, get_max_threads()); parallel_sort_qsb(begin, end, comp, parallelism.get_num_threads());
#endif #endif
else if(stable)
__gnu_sequential::stable_sort(begin, end, comp);
else else
__gnu_sequential::sort(begin, end, comp); __gnu_sequential::sort(begin, end, comp);
} }
}
} // end namespace __gnu_parallel } // end namespace __gnu_parallel
#endif #endif
// -*- C++ -*- // -*- C++ -*-
// Copyright (C) 2007 Free Software Foundation, Inc. // Copyright (C) 2007, 2008 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
...@@ -39,6 +39,9 @@ ...@@ -39,6 +39,9 @@
#ifndef _GLIBCXX_PARALLEL_TAGS_H #ifndef _GLIBCXX_PARALLEL_TAGS_H
#define _GLIBCXX_PARALLEL_TAGS_H 1 #define _GLIBCXX_PARALLEL_TAGS_H 1
#include <omp.h>
#include <parallel/types.h>
namespace __gnu_parallel namespace __gnu_parallel
{ {
/** @brief Forces sequential execution at compile time. */ /** @brief Forces sequential execution at compile time. */
...@@ -47,8 +50,53 @@ namespace __gnu_parallel ...@@ -47,8 +50,53 @@ namespace __gnu_parallel
/** @brief Forces exact splitting in multiway merge at compile time. */ /** @brief Forces exact splitting in multiway merge at compile time. */
struct exact_tag { }; struct exact_tag { };
/** @brief Recommends parallel execution at compile time. */ /** @brief Recommends parallel execution at compile time,
struct parallel_tag { }; * optionally using a user-specified number of threads. */
struct parallel_tag
{
private:
thread_index_t num_threads;
public:
/** @brief Default constructor. Use default number of threads. */
parallel_tag()
{
this->num_threads = 0;
}
/** @brief Default constructor. Recommend number of threads to use.
* @param num_threads Desired number of threads. */
parallel_tag(thread_index_t num_threads)
{
this->num_threads = num_threads;
}
/** @brief Find out desired number of threads.
* @return Desired number of threads. */
inline thread_index_t get_num_threads()
{
if(num_threads == 0)
return omp_get_max_threads();
else
return num_threads;
}
/** @brief Set the desired number of threads.
* @param num_threads Desired number of threads. */
inline void set_num_threads(thread_index_t num_threads)
{
this->num_threads = num_threads;
}
};
/** @brief Recommends parallel execution using the
default parallel algorithm. */
struct default_parallel_tag : public parallel_tag
{
default_parallel_tag() { }
default_parallel_tag(thread_index_t num_threads)
: parallel_tag(num_threads) { }
};
/** @brief Recommends parallel execution using dynamic /** @brief Recommends parallel execution using dynamic
load-balancing at compile time. */ load-balancing at compile time. */
...@@ -67,8 +115,56 @@ namespace __gnu_parallel ...@@ -67,8 +115,56 @@ namespace __gnu_parallel
struct omp_loop_static_tag : public parallel_tag { }; struct omp_loop_static_tag : public parallel_tag { };
/** @brief Base class for for std::find() variants. */
struct find_tag { }; struct find_tag { };
/** @brief Forces parallel sorting using multiway mergesort
* at compile time. */
struct multiway_mergesort_tag : public parallel_tag
{
multiway_mergesort_tag() { }
multiway_mergesort_tag(thread_index_t num_threads)
: parallel_tag(num_threads) { }
};
/** @brief Forces parallel sorting using multiway mergesort
* with exact splitting at compile time. */
struct multiway_mergesort_exact_tag : public parallel_tag
{
multiway_mergesort_exact_tag() { }
multiway_mergesort_exact_tag(thread_index_t num_threads)
: parallel_tag(num_threads) { }
};
/** @brief Forces parallel sorting using multiway mergesort
* with splitting by sampling at compile time. */
struct multiway_mergesort_sampling_tag : public parallel_tag
{
multiway_mergesort_sampling_tag() { }
multiway_mergesort_sampling_tag(thread_index_t num_threads)
: parallel_tag(num_threads) { }
};
/** @brief Forces parallel sorting using unbalanced quicksort
* at compile time. */
struct quicksort_tag : public parallel_tag
{
quicksort_tag() { }
quicksort_tag(thread_index_t num_threads)
: parallel_tag(num_threads) { }
};
/** @brief Forces parallel sorting using balanced quicksort
* at compile time. */
struct balanced_quicksort_tag : public parallel_tag
{
balanced_quicksort_tag() { }
balanced_quicksort_tag(thread_index_t num_threads)
: parallel_tag(num_threads) { }
};
/** @brief Selects the growing block size variant for std::find(). /** @brief Selects the growing block size variant for std::find().
@see _GLIBCXX_FIND_GROWING_BLOCKS */ @see _GLIBCXX_FIND_GROWING_BLOCKS */
struct growing_blocks_tag : public find_tag { }; struct growing_blocks_tag : public find_tag { };
......
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