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.
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -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,12 +171,11 @@ namespace __gnu_parallel ...@@ -172,12 +171,11 @@ 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)
num_threads = static_cast<thread_index_t>(n); num_threads = static_cast<thread_index_t>(n);
// Hard to avoid. // Hard to avoid.
omp_set_num_threads(num_threads); omp_set_num_threads(num_threads);
......
...@@ -60,7 +60,136 @@ ...@@ -60,7 +60,136 @@
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.
* @param end End iterator of input sequence. * @param end End iterator of input sequence.
...@@ -68,54 +197,38 @@ namespace __gnu_parallel ...@@ -68,54 +197,38 @@ 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) if (false) ;
{
difference_type n = end - begin;
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 else
parallel_sort_mwms<true, false> parallel_sort_mwms<false, false>
(begin, end, comp, get_max_threads()); (begin, end, comp, parallelism.get_num_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
parallel_sort_mwms<false, false>
(begin, end, comp, get_max_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) else
__gnu_sequential::stable_sort(begin, end, comp); __gnu_sequential::sort(begin, end, comp);
else
__gnu_sequential::sort(begin, end, comp);
}
} }
} // end namespace __gnu_parallel } // end namespace __gnu_parallel
......
// -*- 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