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:
parent
214ece2920
commit
d7066497b0
7 changed files with 1225 additions and 788 deletions
|
@ -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
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 { };
|
||||
|
|
Loading…
Add table
Reference in a new issue