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
This commit is contained in:
Johannes Singler 2008-04-23 07:26:53 +00:00 committed by Johannes Singler
parent 214ece2920
commit d7066497b0
7 changed files with 1225 additions and 788 deletions

View file

@ -1,3 +1,19 @@
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

File diff suppressed because it is too large Load diff

View file

@ -252,7 +252,8 @@ template<typename RandomAccessIterator, typename Comparator>
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)
base_case_n = 2;
thread_index_t num_threads = tl.num_threads;
@ -415,7 +416,6 @@ template<typename RandomAccessIterator, typename Comparator>
* @param begin Begin iterator of sequence.
* @param end End iterator of sequence.
* @param comp Comparator.
* @param n Length of the sequence to sort.
* @param num_threads Number of threads that are allowed to work on
* this part.
*/
@ -423,8 +423,6 @@ template<typename RandomAccessIterator, typename Comparator>
void
parallel_sort_qsb(RandomAccessIterator begin, RandomAccessIterator end,
Comparator comp,
typename std::iterator_traits<RandomAccessIterator>
::difference_type n,
thread_index_t num_threads)
{
_GLIBCXX_CALL(end - begin)
@ -436,6 +434,8 @@ template<typename RandomAccessIterator, typename Comparator>
typedef QSBThreadLocal<RandomAccessIterator> tls_type;
difference_type n = end - begin;
if (n <= 1)
return;

View file

@ -248,7 +248,7 @@ namespace __gnu_parallel
typedef typename std::pair<RandomAccessIterator1, RandomAccessIterator1>
iterator_pair;
std::pair<RandomAccessIterator1, RandomAccessIterator1>
iterator_pair
seqs[2] = { std::make_pair(begin1, end1),
std::make_pair(begin2, end2) };
RandomAccessIterator3

View file

@ -87,7 +87,8 @@ namespace __gnu_parallel
__gnu_parallel::binder2nd<Comparator, value_type, value_type, bool>
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);
@ -154,7 +155,6 @@ namespace __gnu_parallel
* @param begin Begin iterator of input sequence.
* @param end End iterator input sequence, ignored.
* @param comp Comparator.
* @param n Length of input sequence.
* @param num_threads Number of threads that are allowed to work on
* this part.
*/
@ -162,9 +162,8 @@ namespace __gnu_parallel
void
parallel_sort_qs(RandomAccessIterator begin,
RandomAccessIterator end,
Comparator comp, typename std::iterator_traits
<RandomAccessIterator>::difference_type n,
int num_threads)
Comparator comp,
thread_index_t num_threads)
{
_GLIBCXX_CALL(n)
@ -172,12 +171,11 @@ namespace __gnu_parallel
typedef typename traits_type::value_type value_type;
typedef typename traits_type::difference_type difference_type;
if (n == 0)
return;
difference_type n = end - begin;
// At least one element per processor.
if (num_threads > n)
num_threads = static_cast<thread_index_t>(n);
num_threads = static_cast<thread_index_t>(n);
// Hard to avoid.
omp_set_num_threads(num_threads);

View file

@ -60,7 +60,136 @@
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.
* @param begin Begin iterator of input sequence.
* @param end End iterator of input sequence.
@ -68,54 +197,38 @@ namespace __gnu_parallel
* @param stable Sort stable.
* @callgraph
*/
template<typename RandomAccessIterator, typename Comparator>
template<bool stable, typename RandomAccessIterator, typename Comparator>
inline void
parallel_sort(RandomAccessIterator begin, RandomAccessIterator end,
Comparator comp, bool stable)
Comparator comp, parallel_tag parallelism)
{
_GLIBCXX_CALL(end - begin)
typedef std::iterator_traits<RandomAccessIterator> traits_type;
typedef typename traits_type::value_type value_type;
typedef typename traits_type::difference_type difference_type;
if (begin != end)
{
difference_type n = end - begin;
if (false) ;
if (false) ;
#if _GLIBCXX_MERGESORT
else if (stable)
{
if(_Settings::get().sort_splitting == EXACT)
parallel_sort_mwms<true, true>
(begin, end, comp, get_max_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
parallel_sort_mwms<false, false>
(begin, end, comp, get_max_threads());
}
else if (stable || _Settings::get().sort_algorithm == MWMS)
{
if(_Settings::get().sort_splitting == EXACT)
parallel_sort_mwms<stable, true>
(begin, end, comp, parallelism.get_num_threads());
else
parallel_sort_mwms<false, false>
(begin, end, comp, parallelism.get_num_threads());
}
#endif
#if _GLIBCXX_QUICKSORT
else if (!stable && _Settings::get().sort_algorithm == QS)
parallel_sort_qs(begin, end, comp, n, get_max_threads());
else if (_Settings::get().sort_algorithm == QS)
parallel_sort_qs(begin, end, comp, parallelism.get_num_threads());
#endif
#if _GLIBCXX_BAL_QUICKSORT
else if (!stable && _Settings::get().sort_algorithm == QS_BALANCED)
parallel_sort_qsb(begin, end, comp, n, get_max_threads());
else if (_Settings::get().sort_algorithm == QS_BALANCED)
parallel_sort_qsb(begin, end, comp, parallelism.get_num_threads());
#endif
else if(stable)
__gnu_sequential::stable_sort(begin, end, comp);
else
__gnu_sequential::sort(begin, end, comp);
}
else
__gnu_sequential::sort(begin, end, comp);
}
} // end namespace __gnu_parallel

View file

@ -1,6 +1,6 @@
// -*- 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
// software; you can redistribute it and/or modify it under the terms
@ -39,6 +39,9 @@
#ifndef _GLIBCXX_PARALLEL_TAGS_H
#define _GLIBCXX_PARALLEL_TAGS_H 1
#include <omp.h>
#include <parallel/types.h>
namespace __gnu_parallel
{
/** @brief Forces sequential execution at compile time. */
@ -47,8 +50,53 @@ namespace __gnu_parallel
/** @brief Forces exact splitting in multiway merge at compile time. */
struct exact_tag { };
/** @brief Recommends parallel execution at compile time. */
struct parallel_tag { };
/** @brief Recommends parallel execution at compile time,
* 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
load-balancing at compile time. */
@ -67,8 +115,56 @@ namespace __gnu_parallel
struct omp_loop_static_tag : public parallel_tag { };
/** @brief Base class for for std::find() variants. */
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().
@see _GLIBCXX_FIND_GROWING_BLOCKS */
struct growing_blocks_tag : public find_tag { };