mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-12-01 15:54:17 +08:00
parallel_mode.xml: Documented the new choices, factoring out common tags.
2008-05-16 Johannes Singler <singler@ira.uka.de> * doc/xml/manual/parallel_mode.xml: Documented the new choices, factoring out common tags. * include/parallel/multiway_merge.h: Place comparison functor at the end, to comply with established convention. (parallel_multiway_merge) Pass number of threads explicitly. Introduce new compile-time variants, make exact splitting the default. * include/parallel/tags.h: Extend exact_tag, introduce sampling_tag. * include/parallel/merge.h: (parallel_merge_advance) Adapt to changed interface. * include/parallel/multiway_mergesort.h: Likewise. From-SVN: r135411
This commit is contained in:
parent
fa9290d3b9
commit
36fc59580b
@ -575,24 +575,36 @@ This means that the actual parallelization strategy is chosen at run-time.
|
||||
(Choosing the variants at compile-time will come soon.)
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For the following algorithms in general, we have
|
||||
<code>__gnu_parallel::parallel_tag</code> and
|
||||
<code>__gnu_parallel::default_parallel_tag</code>, in addition to
|
||||
<code>__gnu_parallel::sequential_tag</code>.
|
||||
<code>__gnu_parallel::default_parallel_tag</code> chooses the default
|
||||
algorithm at compiletime, as does omitting the tag.
|
||||
<code>__gnu_parallel::parallel_tag</code> postpones the decision to runtime
|
||||
(see next section).
|
||||
For all tags, the number of threads desired for this call can optionally be
|
||||
passed to the respective tag's constructor.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The <code>multiway_merge</code> algorithm comes with the additional choices,
|
||||
<code>__gnu_parallel::exact_tag</code> and
|
||||
<code>__gnu_parallel::sampling_tag</code>.
|
||||
Exact and sampling are the two available splitting strategies.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For the <code>sort</code> and <code>stable_sort</code> algorithms, there are
|
||||
several possible choices,
|
||||
<code>__gnu_parallel::parallel_tag</code>,
|
||||
<code>__gnu_parallel::default_parallel_tag</code>,
|
||||
several additional choices, namely
|
||||
<code>__gnu_parallel::multiway_mergesort_tag</code>,
|
||||
<code>__gnu_parallel::multiway_mergesort_exact_tag</code>,
|
||||
<code>__gnu_parallel::multiway_mergesort_sampling_tag</code>,
|
||||
<code>__gnu_parallel::quicksort_tag</code>,
|
||||
<code>__gnu_parallel::quicksort_tag</code>, and
|
||||
<code>__gnu_parallel::balanced_quicksort_tag</code>.
|
||||
Multiway mergesort comes with two splitting strategies for merging, therefore
|
||||
the extra choice. If non is chosen, the default splitting strategy is selected.
|
||||
<code>__gnu_parallel::default_parallel_tag</code> chooses the default parallel
|
||||
sorting algorithm at runtime. <code>__gnu_parallel::parallel_tag</code>
|
||||
postpones the decision to runtime (see next section).
|
||||
The quicksort options cannot be used for <code>stable_sort</code>.
|
||||
For all tags, the number of threads desired for this call can optionally be
|
||||
passed to the tag's constructor.
|
||||
Multiway mergesort comes with the two splitting strategies for multi-way
|
||||
merging. The quicksort options cannot be used for <code>stable_sort</code>.
|
||||
</para>
|
||||
|
||||
</sect3>
|
||||
|
@ -254,11 +254,11 @@ namespace __gnu_parallel
|
||||
RandomAccessIterator3
|
||||
target_end = parallel_multiway_merge
|
||||
< /* stable = */ true, /* sentinels = */ false>(
|
||||
seqs, seqs + 2, target, comp,
|
||||
seqs, seqs + 2, target,
|
||||
multiway_merge_exact_splitting
|
||||
< /* stable = */ true, iterator_pair*,
|
||||
Comparator, difference_type1>,
|
||||
max_length);
|
||||
max_length, comp, omp_get_max_threads());
|
||||
|
||||
return target_end;
|
||||
}
|
||||
|
@ -297,7 +297,7 @@ template<template<typename RAI, typename C> class iterator,
|
||||
RandomAccessIteratorIterator seqs_begin,
|
||||
RandomAccessIteratorIterator seqs_end,
|
||||
RandomAccessIterator3 target,
|
||||
Comparator comp, _DifferenceTp length)
|
||||
_DifferenceTp length, Comparator comp)
|
||||
{
|
||||
_GLIBCXX_CALL(length);
|
||||
|
||||
@ -416,7 +416,7 @@ template<template<typename RAI, typename C> class iterator,
|
||||
multiway_merge_4_variant(RandomAccessIteratorIterator seqs_begin,
|
||||
RandomAccessIteratorIterator seqs_end,
|
||||
RandomAccessIterator3 target,
|
||||
Comparator comp, _DifferenceTp length)
|
||||
_DifferenceTp length, Comparator comp)
|
||||
{
|
||||
_GLIBCXX_CALL(length);
|
||||
typedef _DifferenceTp difference_type;
|
||||
@ -540,8 +540,7 @@ template<typename LT,
|
||||
multiway_merge_loser_tree(RandomAccessIteratorIterator seqs_begin,
|
||||
RandomAccessIteratorIterator seqs_end,
|
||||
RandomAccessIterator3 target,
|
||||
Comparator comp,
|
||||
_DifferenceTp length)
|
||||
_DifferenceTp length, Comparator comp)
|
||||
{
|
||||
_GLIBCXX_CALL(length)
|
||||
|
||||
@ -626,8 +625,8 @@ template<typename LT,
|
||||
const typename std::iterator_traits<typename std::iterator_traits<
|
||||
RandomAccessIteratorIterator>::value_type::first_type>::value_type&
|
||||
sentinel,
|
||||
Comparator comp,
|
||||
_DifferenceTp length)
|
||||
_DifferenceTp length,
|
||||
Comparator comp)
|
||||
{
|
||||
_GLIBCXX_CALL(length)
|
||||
typedef _DifferenceTp difference_type;
|
||||
@ -716,8 +715,8 @@ template<
|
||||
const typename std::iterator_traits<typename std::iterator_traits<
|
||||
RandomAccessIteratorIterator>::value_type::first_type>::value_type&
|
||||
sentinel,
|
||||
Comparator comp,
|
||||
_DifferenceTp length)
|
||||
_DifferenceTp length,
|
||||
Comparator comp)
|
||||
{
|
||||
_GLIBCXX_CALL(length)
|
||||
|
||||
@ -740,7 +739,7 @@ template<
|
||||
|
||||
target_end = multiway_merge_loser_tree_unguarded
|
||||
<UnguardedLoserTree>
|
||||
(seqs_begin, seqs_end, target, sentinel, comp, length);
|
||||
(seqs_begin, seqs_end, target, sentinel, length, comp);
|
||||
|
||||
#if _GLIBCXX_ASSERTIONS
|
||||
_GLIBCXX_PARALLEL_ASSERT(target_end == target + length);
|
||||
@ -808,10 +807,10 @@ struct multiway_merge_3_variant_sentinel_switch
|
||||
RandomAccessIteratorIterator seqs_begin,
|
||||
RandomAccessIteratorIterator seqs_end,
|
||||
RandomAccessIterator3 target,
|
||||
Comparator comp, _DifferenceTp length)
|
||||
_DifferenceTp length, Comparator comp)
|
||||
{
|
||||
return multiway_merge_3_variant<guarded_iterator>(
|
||||
seqs_begin, seqs_end, target, comp, length);
|
||||
seqs_begin, seqs_end, target, length, comp);
|
||||
}
|
||||
};
|
||||
|
||||
@ -833,10 +832,10 @@ struct multiway_merge_3_variant_sentinel_switch
|
||||
RandomAccessIteratorIterator seqs_begin,
|
||||
RandomAccessIteratorIterator seqs_end,
|
||||
RandomAccessIterator3 target,
|
||||
Comparator comp, _DifferenceTp length)
|
||||
_DifferenceTp length, Comparator comp)
|
||||
{
|
||||
return multiway_merge_3_variant<unguarded_iterator>(
|
||||
seqs_begin, seqs_end, target, comp, length);
|
||||
seqs_begin, seqs_end, target, length, comp);
|
||||
}
|
||||
};
|
||||
|
||||
@ -857,10 +856,10 @@ struct multiway_merge_4_variant_sentinel_switch
|
||||
RandomAccessIteratorIterator seqs_begin,
|
||||
RandomAccessIteratorIterator seqs_end,
|
||||
RandomAccessIterator3 target,
|
||||
Comparator comp, _DifferenceTp length)
|
||||
_DifferenceTp length, Comparator comp)
|
||||
{
|
||||
return multiway_merge_4_variant<guarded_iterator>(
|
||||
seqs_begin, seqs_end, target, comp, length);
|
||||
seqs_begin, seqs_end, target, length, comp);
|
||||
}
|
||||
};
|
||||
|
||||
@ -882,10 +881,10 @@ struct multiway_merge_4_variant_sentinel_switch
|
||||
RandomAccessIteratorIterator seqs_begin,
|
||||
RandomAccessIteratorIterator seqs_end,
|
||||
RandomAccessIterator3 target,
|
||||
Comparator comp, _DifferenceTp length)
|
||||
_DifferenceTp length, Comparator comp)
|
||||
{
|
||||
return multiway_merge_4_variant<unguarded_iterator>(
|
||||
seqs_begin, seqs_end, target, comp, length);
|
||||
seqs_begin, seqs_end, target, length, comp);
|
||||
}
|
||||
};
|
||||
|
||||
@ -908,7 +907,7 @@ struct multiway_merge_k_variant_sentinel_switch
|
||||
const typename std::iterator_traits<typename std::iterator_traits<
|
||||
RandomAccessIteratorIterator>::value_type::first_type>::value_type&
|
||||
sentinel,
|
||||
Comparator comp, _DifferenceTp length)
|
||||
_DifferenceTp length, Comparator comp)
|
||||
{
|
||||
typedef typename std::iterator_traits<RandomAccessIteratorIterator>
|
||||
::value_type::first_type
|
||||
@ -921,7 +920,7 @@ struct multiway_merge_k_variant_sentinel_switch
|
||||
loser_tree_traits<value_type>::use_pointer
|
||||
, LoserTreePointerUnguarded<stable, value_type, Comparator>
|
||||
, LoserTreeUnguarded<stable, value_type, Comparator>
|
||||
>::__type>(seqs_begin, seqs_end, target, sentinel, comp, length);
|
||||
>::__type>(seqs_begin, seqs_end, target, sentinel, length, comp);
|
||||
}
|
||||
};
|
||||
|
||||
@ -945,7 +944,7 @@ struct multiway_merge_k_variant_sentinel_switch
|
||||
const typename std::iterator_traits<typename std::iterator_traits<
|
||||
RandomAccessIteratorIterator>::value_type::first_type>::value_type&
|
||||
sentinel,
|
||||
Comparator comp, _DifferenceTp length)
|
||||
_DifferenceTp length, Comparator comp)
|
||||
{
|
||||
typedef typename std::iterator_traits<RandomAccessIteratorIterator>
|
||||
::value_type::first_type
|
||||
@ -958,7 +957,7 @@ struct multiway_merge_k_variant_sentinel_switch
|
||||
loser_tree_traits<value_type>::use_pointer
|
||||
, LoserTreePointer<stable, value_type, Comparator>
|
||||
, LoserTree<stable, value_type, Comparator>
|
||||
>::__type >(seqs_begin, seqs_end, target, comp, length);
|
||||
>::__type >(seqs_begin, seqs_end, target, length, comp);
|
||||
}
|
||||
};
|
||||
|
||||
@ -990,7 +989,7 @@ template<
|
||||
const typename std::iterator_traits<typename std::iterator_traits<
|
||||
RandomAccessIteratorIterator>::value_type::first_type>::value_type&
|
||||
sentinel,
|
||||
Comparator comp, _DifferenceTp length)
|
||||
_DifferenceTp length, Comparator comp)
|
||||
{
|
||||
_GLIBCXX_CALL(length)
|
||||
|
||||
@ -1043,7 +1042,7 @@ template<
|
||||
, RandomAccessIteratorIterator
|
||||
, RandomAccessIterator3
|
||||
, _DifferenceTp
|
||||
, Comparator>()(seqs_begin, seqs_end, target, comp, length);
|
||||
, Comparator>()(seqs_begin, seqs_end, target, length, comp);
|
||||
break;
|
||||
case 4:
|
||||
return_target = multiway_merge_4_variant_sentinel_switch<
|
||||
@ -1051,7 +1050,7 @@ template<
|
||||
, RandomAccessIteratorIterator
|
||||
, RandomAccessIterator3
|
||||
, _DifferenceTp
|
||||
, Comparator>()(seqs_begin, seqs_end, target, comp, length);
|
||||
, Comparator>()(seqs_begin, seqs_end, target, length, comp);
|
||||
break;
|
||||
default:
|
||||
return_target = multiway_merge_k_variant_sentinel_switch<
|
||||
@ -1060,8 +1059,7 @@ template<
|
||||
, RandomAccessIteratorIterator
|
||||
, RandomAccessIterator3
|
||||
, _DifferenceTp
|
||||
, Comparator>()
|
||||
(seqs_begin, seqs_end, target, sentinel, comp, length);
|
||||
, Comparator>()(seqs_begin, seqs_end, target, sentinel, length, comp);
|
||||
break;
|
||||
}
|
||||
#if _GLIBCXX_ASSERTIONS
|
||||
@ -1108,8 +1106,7 @@ template<
|
||||
void multiway_merge_sampling_splitting(
|
||||
RandomAccessIteratorIterator seqs_begin,
|
||||
RandomAccessIteratorIterator seqs_end,
|
||||
Comparator comp, difference_type length,
|
||||
difference_type total_length,
|
||||
difference_type length, difference_type total_length, Comparator comp,
|
||||
std::vector<std::pair<difference_type, difference_type> > *pieces)
|
||||
{
|
||||
typedef typename std::iterator_traits<RandomAccessIteratorIterator>
|
||||
@ -1190,9 +1187,7 @@ template<
|
||||
void multiway_merge_exact_splitting(
|
||||
RandomAccessIteratorIterator seqs_begin,
|
||||
RandomAccessIteratorIterator seqs_end,
|
||||
Comparator comp,
|
||||
difference_type length,
|
||||
difference_type total_length,
|
||||
difference_type length, difference_type total_length, Comparator comp,
|
||||
std::vector<std::pair<difference_type, difference_type> > *pieces)
|
||||
{
|
||||
typedef typename std::iterator_traits<RandomAccessIteratorIterator>
|
||||
@ -1297,9 +1292,10 @@ template<
|
||||
parallel_multiway_merge(RandomAccessIteratorIterator seqs_begin,
|
||||
RandomAccessIteratorIterator seqs_end,
|
||||
RandomAccessIterator3 target,
|
||||
Comparator comp,
|
||||
Splitter splitter,
|
||||
_DifferenceTp length)
|
||||
_DifferenceTp length,
|
||||
Comparator comp,
|
||||
thread_index_t num_threads)
|
||||
{
|
||||
#if _GLIBCXX_ASSERTIONS
|
||||
_GLIBCXX_PARALLEL_ASSERT(seqs_end - seqs_begin > 1);
|
||||
@ -1347,8 +1343,8 @@ template<
|
||||
|
||||
std::vector<std::pair<difference_type, difference_type> >* pieces;
|
||||
|
||||
thread_index_t num_threads = static_cast<thread_index_t>
|
||||
(std::min<difference_type>(get_max_threads(), total_length));
|
||||
num_threads = static_cast<thread_index_t>
|
||||
(std::min<difference_type>(num_threads, total_length));
|
||||
|
||||
# pragma omp parallel num_threads (num_threads)
|
||||
{
|
||||
@ -1365,8 +1361,8 @@ template<
|
||||
__gnu_parallel::_Settings::get().merge_oversampling *
|
||||
num_threads;
|
||||
|
||||
splitter(ne_seqs, ne_seqs + k, comp, length, total_length,
|
||||
pieces);
|
||||
splitter(ne_seqs, ne_seqs + k, length, total_length,
|
||||
comp, pieces);
|
||||
} //single
|
||||
|
||||
thread_index_t iam = omp_get_thread_num();
|
||||
@ -1389,7 +1385,7 @@ template<
|
||||
if(length > target_position)
|
||||
sequential_multiway_merge<stable, sentinels>(
|
||||
chunks, chunks + k, target + target_position,
|
||||
*(seqs_begin->second), comp, length - target_position);
|
||||
*(seqs_begin->second), length - target_position, comp);
|
||||
|
||||
delete[] chunks;
|
||||
} // parallel
|
||||
@ -1481,6 +1477,7 @@ template<
|
||||
*
|
||||
* @return end iterator of output sequence
|
||||
*/
|
||||
// multiway_merge
|
||||
// public interface
|
||||
template<
|
||||
typename RandomAccessIteratorPairIterator
|
||||
@ -1491,49 +1488,7 @@ RandomAccessIteratorOut
|
||||
multiway_merge(RandomAccessIteratorPairIterator seqs_begin
|
||||
, RandomAccessIteratorPairIterator seqs_end
|
||||
, RandomAccessIteratorOut target
|
||||
, Comparator comp, _DifferenceTp length)
|
||||
{
|
||||
typedef _DifferenceTp difference_type;
|
||||
_GLIBCXX_CALL(seqs_end - seqs_begin)
|
||||
|
||||
// catch special case: no sequences
|
||||
if (seqs_begin == seqs_end)
|
||||
return target;
|
||||
|
||||
// Execute merge; maybe parallel, depending on the number of merged
|
||||
// elements and the number of sequences and global thresholds in
|
||||
// Settings.
|
||||
if ((seqs_end - seqs_begin > 1) &&
|
||||
_GLIBCXX_PARALLEL_CONDITION(
|
||||
((seqs_end - seqs_begin) >=
|
||||
__gnu_parallel::_Settings::get().multiway_merge_minimal_k)
|
||||
&& ((sequence_index_t)length >=
|
||||
__gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
|
||||
return parallel_multiway_merge
|
||||
</* stable = */ false, /* sentinels = */ false>
|
||||
(seqs_begin, seqs_end, target, comp,
|
||||
multiway_merge_sampling_splitting</* stable = */ false,
|
||||
typename std::iterator_traits<RandomAccessIteratorPairIterator>
|
||||
::value_type*, Comparator, _DifferenceTp>,
|
||||
static_cast<difference_type>(length));
|
||||
else
|
||||
return sequential_multiway_merge
|
||||
</* stable = */false, /* sentinels = */ false>(
|
||||
seqs_begin, seqs_end,
|
||||
target, *(seqs_begin->second), comp, length);
|
||||
}
|
||||
|
||||
// public interface
|
||||
template<
|
||||
typename RandomAccessIteratorPairIterator
|
||||
, typename RandomAccessIteratorOut
|
||||
, typename _DifferenceTp
|
||||
, typename Comparator>
|
||||
RandomAccessIteratorOut
|
||||
multiway_merge(RandomAccessIteratorPairIterator seqs_begin
|
||||
, RandomAccessIteratorPairIterator seqs_end
|
||||
, RandomAccessIteratorOut target
|
||||
, Comparator comp, _DifferenceTp length
|
||||
, _DifferenceTp length, Comparator comp
|
||||
, __gnu_parallel::sequential_tag)
|
||||
{
|
||||
typedef _DifferenceTp difference_type;
|
||||
@ -1546,10 +1501,10 @@ multiway_merge(RandomAccessIteratorPairIterator seqs_begin
|
||||
// Execute multiway merge *sequentially*.
|
||||
return sequential_multiway_merge
|
||||
</* stable = */ false, /* sentinels = */ false>
|
||||
(seqs_begin, seqs_end, target, *(seqs_begin->second), comp, length);
|
||||
(seqs_begin, seqs_end, target, *(seqs_begin->second), length, comp);
|
||||
}
|
||||
|
||||
//public interface
|
||||
// public interface
|
||||
template<
|
||||
typename RandomAccessIteratorPairIterator
|
||||
, typename RandomAccessIteratorOut
|
||||
@ -1559,8 +1514,50 @@ RandomAccessIteratorOut
|
||||
multiway_merge(RandomAccessIteratorPairIterator seqs_begin
|
||||
, RandomAccessIteratorPairIterator seqs_end
|
||||
, RandomAccessIteratorOut target
|
||||
, Comparator comp, _DifferenceTp length
|
||||
, __gnu_parallel::exact_tag)
|
||||
, _DifferenceTp length, Comparator comp
|
||||
, __gnu_parallel::exact_tag tag)
|
||||
{
|
||||
typedef _DifferenceTp difference_type;
|
||||
_GLIBCXX_CALL(seqs_end - seqs_begin)
|
||||
|
||||
// catch special case: no sequences
|
||||
if (seqs_begin == seqs_end)
|
||||
return target;
|
||||
|
||||
// Execute merge; maybe parallel, depending on the number of merged
|
||||
// elements and the number of sequences and global thresholds in
|
||||
// Settings.
|
||||
if ((seqs_end - seqs_begin > 1) &&
|
||||
_GLIBCXX_PARALLEL_CONDITION(
|
||||
((seqs_end - seqs_begin) >=
|
||||
__gnu_parallel::_Settings::get().multiway_merge_minimal_k)
|
||||
&& ((sequence_index_t)length >=
|
||||
__gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
|
||||
return parallel_multiway_merge
|
||||
</* stable = */ false, /* sentinels = */ false>(
|
||||
seqs_begin, seqs_end, target,
|
||||
multiway_merge_exact_splitting</* stable = */ false,
|
||||
typename std::iterator_traits<RandomAccessIteratorPairIterator>
|
||||
::value_type*, Comparator, _DifferenceTp>,
|
||||
static_cast<difference_type>(length), comp, tag.get_num_threads());
|
||||
else
|
||||
return sequential_multiway_merge
|
||||
</* stable = */ false, /* sentinels = */ false>(
|
||||
seqs_begin, seqs_end, target, *(seqs_begin->second), length, comp);
|
||||
}
|
||||
|
||||
// public interface
|
||||
template<
|
||||
typename RandomAccessIteratorPairIterator
|
||||
, typename RandomAccessIteratorOut
|
||||
, typename _DifferenceTp
|
||||
, typename Comparator>
|
||||
RandomAccessIteratorOut
|
||||
multiway_merge(RandomAccessIteratorPairIterator seqs_begin
|
||||
, RandomAccessIteratorPairIterator seqs_end
|
||||
, RandomAccessIteratorOut target
|
||||
, _DifferenceTp length, Comparator comp
|
||||
, __gnu_parallel::sampling_tag tag)
|
||||
{
|
||||
typedef _DifferenceTp difference_type;
|
||||
_GLIBCXX_CALL(seqs_end - seqs_begin)
|
||||
@ -1581,16 +1578,16 @@ multiway_merge(RandomAccessIteratorPairIterator seqs_begin
|
||||
return parallel_multiway_merge
|
||||
</* stable = */ false, /* sentinels = */ false>(
|
||||
seqs_begin, seqs_end,
|
||||
target, comp,
|
||||
target,
|
||||
multiway_merge_exact_splitting</* stable = */ false,
|
||||
typename std::iterator_traits<RandomAccessIteratorPairIterator>
|
||||
::value_type*, Comparator, _DifferenceTp>,
|
||||
static_cast<difference_type>(length));
|
||||
static_cast<difference_type>(length), comp, tag.get_num_threads());
|
||||
else
|
||||
return sequential_multiway_merge
|
||||
</* stable = */ false, /* sentinels = */ false>(
|
||||
seqs_begin, seqs_end,
|
||||
target, *(seqs_begin->second), comp, length);
|
||||
target, *(seqs_begin->second), length, comp);
|
||||
}
|
||||
|
||||
// public interface
|
||||
@ -1600,42 +1597,34 @@ template<
|
||||
, typename _DifferenceTp
|
||||
, typename Comparator>
|
||||
RandomAccessIteratorOut
|
||||
stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin
|
||||
multiway_merge(RandomAccessIteratorPairIterator seqs_begin
|
||||
, RandomAccessIteratorPairIterator seqs_end
|
||||
, RandomAccessIteratorOut target
|
||||
, Comparator comp, _DifferenceTp length)
|
||||
, _DifferenceTp length, Comparator comp
|
||||
, parallel_tag tag = parallel_tag(0))
|
||||
{
|
||||
typedef _DifferenceTp difference_type;
|
||||
_GLIBCXX_CALL(seqs_end - seqs_begin)
|
||||
|
||||
// catch special case: no sequences
|
||||
if (seqs_begin == seqs_end)
|
||||
return target;
|
||||
|
||||
// Execute merge; maybe parallel, depending on the number of merged
|
||||
// elements and the number of sequences and global thresholds in
|
||||
// Settings.
|
||||
if ((seqs_end - seqs_begin > 1) &&
|
||||
_GLIBCXX_PARALLEL_CONDITION(
|
||||
((seqs_end - seqs_begin) >=
|
||||
__gnu_parallel::_Settings::get().multiway_merge_minimal_k)
|
||||
&& ((sequence_index_t)length >=
|
||||
__gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
|
||||
return parallel_multiway_merge
|
||||
</* stable = */ true, /* sentinels = */ false>(
|
||||
seqs_begin, seqs_end,
|
||||
target, comp,
|
||||
multiway_merge_sampling_splitting</* stable = */ true,
|
||||
typename std::iterator_traits<RandomAccessIteratorPairIterator>
|
||||
::value_type*, Comparator, _DifferenceTp>,
|
||||
static_cast<difference_type>(length));
|
||||
else
|
||||
return sequential_multiway_merge
|
||||
</* stable = */ true, /* sentinels = */ false>(
|
||||
seqs_begin, seqs_end,
|
||||
target, *(seqs_begin->second), comp, length);
|
||||
return multiway_merge(seqs_begin, seqs_end, target, length, comp,
|
||||
exact_tag(tag.get_num_threads()));
|
||||
}
|
||||
|
||||
// public interface
|
||||
template<
|
||||
typename RandomAccessIteratorPairIterator
|
||||
, typename RandomAccessIteratorOut
|
||||
, typename _DifferenceTp
|
||||
, typename Comparator>
|
||||
RandomAccessIteratorOut
|
||||
multiway_merge(RandomAccessIteratorPairIterator seqs_begin
|
||||
, RandomAccessIteratorPairIterator seqs_end
|
||||
, RandomAccessIteratorOut target
|
||||
, _DifferenceTp length, Comparator comp
|
||||
, default_parallel_tag tag)
|
||||
{
|
||||
return multiway_merge(seqs_begin, seqs_end, target, length, comp,
|
||||
exact_tag(tag.get_num_threads()));
|
||||
}
|
||||
|
||||
// stable_multiway_merge
|
||||
// public interface
|
||||
template<
|
||||
typename RandomAccessIteratorPairIterator
|
||||
@ -1646,7 +1635,7 @@ RandomAccessIteratorOut
|
||||
stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin
|
||||
, RandomAccessIteratorPairIterator seqs_end
|
||||
, RandomAccessIteratorOut target
|
||||
, Comparator comp, _DifferenceTp length
|
||||
, _DifferenceTp length, Comparator comp
|
||||
, __gnu_parallel::sequential_tag)
|
||||
{
|
||||
typedef _DifferenceTp difference_type;
|
||||
@ -1659,7 +1648,7 @@ stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin
|
||||
// Execute multiway merge *sequentially*.
|
||||
return sequential_multiway_merge
|
||||
</* stable = */ true, /* sentinels = */ false>
|
||||
(seqs_begin, seqs_end, target, *(seqs_begin->second), comp, length);
|
||||
(seqs_begin, seqs_end, target, *(seqs_begin->second), length, comp);
|
||||
}
|
||||
|
||||
// public interface
|
||||
@ -1672,8 +1661,8 @@ RandomAccessIteratorOut
|
||||
stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin
|
||||
, RandomAccessIteratorPairIterator seqs_end
|
||||
, RandomAccessIteratorOut target
|
||||
, Comparator comp, _DifferenceTp length
|
||||
, __gnu_parallel::exact_tag)
|
||||
, _DifferenceTp length, Comparator comp
|
||||
, __gnu_parallel::exact_tag tag)
|
||||
{
|
||||
typedef _DifferenceTp difference_type;
|
||||
_GLIBCXX_CALL(seqs_end - seqs_begin)
|
||||
@ -1694,17 +1683,95 @@ stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin
|
||||
return parallel_multiway_merge
|
||||
</* stable = */ true, /* sentinels = */ false>(
|
||||
seqs_begin, seqs_end,
|
||||
target, comp,
|
||||
multiway_merge_exact_splitting
|
||||
</* stable = */ true,
|
||||
typename std::iterator_traits<RandomAccessIteratorPairIterator>
|
||||
::value_type*, Comparator, _DifferenceTp>,
|
||||
static_cast<difference_type>(length));
|
||||
target,
|
||||
multiway_merge_exact_splitting</* stable = */ true,
|
||||
typename std::iterator_traits<RandomAccessIteratorPairIterator>
|
||||
::value_type*, Comparator, _DifferenceTp>,
|
||||
static_cast<difference_type>(length), comp, tag.get_num_threads());
|
||||
else
|
||||
return sequential_multiway_merge</* stable = */ true,
|
||||
/* sentinels = */ false>(
|
||||
seqs_begin, seqs_end,
|
||||
target, *(seqs_begin->second), comp, length);
|
||||
target, *(seqs_begin->second), length, comp);
|
||||
}
|
||||
|
||||
// public interface
|
||||
template<
|
||||
typename RandomAccessIteratorPairIterator
|
||||
, typename RandomAccessIteratorOut
|
||||
, typename _DifferenceTp
|
||||
, typename Comparator>
|
||||
RandomAccessIteratorOut
|
||||
stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin
|
||||
, RandomAccessIteratorPairIterator seqs_end
|
||||
, RandomAccessIteratorOut target
|
||||
, _DifferenceTp length, Comparator comp
|
||||
, sampling_tag tag)
|
||||
{
|
||||
typedef _DifferenceTp difference_type;
|
||||
_GLIBCXX_CALL(seqs_end - seqs_begin)
|
||||
|
||||
// catch special case: no sequences
|
||||
if (seqs_begin == seqs_end)
|
||||
return target;
|
||||
|
||||
// Execute merge; maybe parallel, depending on the number of merged
|
||||
// elements and the number of sequences and global thresholds in
|
||||
// Settings.
|
||||
if ((seqs_end - seqs_begin > 1) &&
|
||||
_GLIBCXX_PARALLEL_CONDITION(
|
||||
((seqs_end - seqs_begin) >=
|
||||
__gnu_parallel::_Settings::get().multiway_merge_minimal_k)
|
||||
&& ((sequence_index_t)length >=
|
||||
__gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
|
||||
return parallel_multiway_merge
|
||||
</* stable = */ true, /* sentinels = */ false>(
|
||||
seqs_begin, seqs_end,
|
||||
target,
|
||||
multiway_merge_sampling_splitting</* stable = */ true,
|
||||
typename std::iterator_traits<RandomAccessIteratorPairIterator>
|
||||
::value_type*, Comparator, _DifferenceTp>,
|
||||
static_cast<difference_type>(length), comp, tag.get_num_threads());
|
||||
else
|
||||
return sequential_multiway_merge
|
||||
</* stable = */ true, /* sentinels = */ false>(
|
||||
seqs_begin, seqs_end,
|
||||
target, *(seqs_begin->second), length, comp);
|
||||
}
|
||||
|
||||
|
||||
// public interface
|
||||
template<
|
||||
typename RandomAccessIteratorPairIterator
|
||||
, typename RandomAccessIteratorOut
|
||||
, typename _DifferenceTp
|
||||
, typename Comparator>
|
||||
RandomAccessIteratorOut
|
||||
stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin
|
||||
, RandomAccessIteratorPairIterator seqs_end
|
||||
, RandomAccessIteratorOut target
|
||||
, _DifferenceTp length, Comparator comp
|
||||
, parallel_tag tag = parallel_tag(0))
|
||||
{
|
||||
return stable_multiway_merge(seqs_begin, seqs_end, target, length, comp,
|
||||
exact_tag(tag.get_num_threads()));
|
||||
}
|
||||
|
||||
// public interface
|
||||
template<
|
||||
typename RandomAccessIteratorPairIterator
|
||||
, typename RandomAccessIteratorOut
|
||||
, typename _DifferenceTp
|
||||
, typename Comparator>
|
||||
RandomAccessIteratorOut
|
||||
stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin
|
||||
, RandomAccessIteratorPairIterator seqs_end
|
||||
, RandomAccessIteratorOut target
|
||||
, _DifferenceTp length, Comparator comp
|
||||
, default_parallel_tag tag)
|
||||
{
|
||||
return stable_multiway_merge(seqs_begin, seqs_end, target, length, comp,
|
||||
exact_tag(tag.get_num_threads()));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1782,6 +1849,7 @@ stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin
|
||||
*
|
||||
* @return end iterator of output sequence
|
||||
*/
|
||||
// multiway_merge_sentinels
|
||||
// public interface
|
||||
template<
|
||||
typename RandomAccessIteratorPairIterator
|
||||
@ -1792,7 +1860,79 @@ RandomAccessIteratorOut
|
||||
multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
|
||||
, RandomAccessIteratorPairIterator seqs_end
|
||||
, RandomAccessIteratorOut target
|
||||
, Comparator comp, _DifferenceTp length)
|
||||
, _DifferenceTp length, Comparator comp
|
||||
, __gnu_parallel::sequential_tag)
|
||||
{
|
||||
typedef _DifferenceTp difference_type;
|
||||
_GLIBCXX_CALL(seqs_end - seqs_begin)
|
||||
|
||||
// catch special case: no sequences
|
||||
if (seqs_begin == seqs_end)
|
||||
return target;
|
||||
|
||||
// Execute multiway merge *sequentially*.
|
||||
return sequential_multiway_merge
|
||||
</* stable = */ false, /* sentinels = */ true>
|
||||
(seqs_begin, seqs_end,
|
||||
target, *(seqs_begin->second), length, comp);
|
||||
}
|
||||
|
||||
// public interface
|
||||
template<
|
||||
typename RandomAccessIteratorPairIterator
|
||||
, typename RandomAccessIteratorOut
|
||||
, typename _DifferenceTp
|
||||
, typename Comparator>
|
||||
RandomAccessIteratorOut
|
||||
multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
|
||||
, RandomAccessIteratorPairIterator seqs_end
|
||||
, RandomAccessIteratorOut target
|
||||
, _DifferenceTp length, Comparator comp
|
||||
, __gnu_parallel::exact_tag tag)
|
||||
{
|
||||
typedef _DifferenceTp difference_type;
|
||||
_GLIBCXX_CALL(seqs_end - seqs_begin)
|
||||
|
||||
// catch special case: no sequences
|
||||
if (seqs_begin == seqs_end)
|
||||
return target;
|
||||
|
||||
// Execute merge; maybe parallel, depending on the number of merged
|
||||
// elements and the number of sequences and global thresholds in
|
||||
// Settings.
|
||||
if ((seqs_end - seqs_begin > 1) &&
|
||||
_GLIBCXX_PARALLEL_CONDITION(
|
||||
((seqs_end - seqs_begin) >=
|
||||
__gnu_parallel::_Settings::get().multiway_merge_minimal_k)
|
||||
&& ((sequence_index_t)length >=
|
||||
__gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
|
||||
return parallel_multiway_merge
|
||||
</* stable = */ false, /* sentinels = */ true>(
|
||||
seqs_begin, seqs_end,
|
||||
target,
|
||||
multiway_merge_exact_splitting</* stable = */ false,
|
||||
typename std::iterator_traits<RandomAccessIteratorPairIterator>
|
||||
::value_type*, Comparator, _DifferenceTp>,
|
||||
static_cast<difference_type>(length), comp, tag.get_num_threads());
|
||||
else
|
||||
return sequential_multiway_merge
|
||||
</* stable = */ false, /* sentinels = */ true>(
|
||||
seqs_begin, seqs_end,
|
||||
target, *(seqs_begin->second), length, comp);
|
||||
}
|
||||
|
||||
// public interface
|
||||
template<
|
||||
typename RandomAccessIteratorPairIterator
|
||||
, typename RandomAccessIteratorOut
|
||||
, typename _DifferenceTp
|
||||
, typename Comparator>
|
||||
RandomAccessIteratorOut
|
||||
multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
|
||||
, RandomAccessIteratorPairIterator seqs_end
|
||||
, RandomAccessIteratorOut target
|
||||
, _DifferenceTp length, Comparator comp
|
||||
, sampling_tag tag)
|
||||
{
|
||||
typedef _DifferenceTp difference_type;
|
||||
_GLIBCXX_CALL(seqs_end - seqs_begin)
|
||||
@ -1812,43 +1952,16 @@ multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
|
||||
__gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
|
||||
return parallel_multiway_merge
|
||||
</* stable = */ false, /* sentinels = */ true>
|
||||
(seqs_begin, seqs_end, target, comp,
|
||||
multiway_merge_sampling_splitting
|
||||
</* stable = */ false,
|
||||
typename std::iterator_traits<RandomAccessIteratorPairIterator>
|
||||
::value_type*, Comparator, _DifferenceTp>,
|
||||
static_cast<difference_type>(length));
|
||||
(seqs_begin, seqs_end, target,
|
||||
multiway_merge_sampling_splitting</* stable = */ false,
|
||||
typename std::iterator_traits<RandomAccessIteratorPairIterator>
|
||||
::value_type*, Comparator, _DifferenceTp>,
|
||||
static_cast<difference_type>(length), comp, tag.get_num_threads());
|
||||
else
|
||||
return sequential_multiway_merge
|
||||
</* stable = */false, /* sentinels = */ true>(
|
||||
seqs_begin, seqs_end,
|
||||
target, *(seqs_begin->second), comp, length);
|
||||
}
|
||||
|
||||
//public interface
|
||||
template<
|
||||
typename RandomAccessIteratorPairIterator
|
||||
, typename RandomAccessIteratorOut
|
||||
, typename _DifferenceTp
|
||||
, typename Comparator>
|
||||
RandomAccessIteratorOut
|
||||
multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
|
||||
, RandomAccessIteratorPairIterator seqs_end
|
||||
, RandomAccessIteratorOut target
|
||||
, Comparator comp, _DifferenceTp length
|
||||
, __gnu_parallel::sequential_tag)
|
||||
{
|
||||
typedef _DifferenceTp difference_type;
|
||||
_GLIBCXX_CALL(seqs_end - seqs_begin)
|
||||
|
||||
// catch special case: no sequences
|
||||
if (seqs_begin == seqs_end)
|
||||
return target;
|
||||
|
||||
// Execute multiway merge *sequentially*.
|
||||
return sequential_multiway_merge
|
||||
</* stable = */ false, /* sentinels = */ true>
|
||||
(seqs_begin, seqs_end, target, *(seqs_begin->second), comp, length);
|
||||
target, *(seqs_begin->second), length, comp);
|
||||
}
|
||||
|
||||
// public interface
|
||||
@ -1861,41 +1974,31 @@ RandomAccessIteratorOut
|
||||
multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
|
||||
, RandomAccessIteratorPairIterator seqs_end
|
||||
, RandomAccessIteratorOut target
|
||||
, Comparator comp, _DifferenceTp length
|
||||
, __gnu_parallel::exact_tag)
|
||||
, _DifferenceTp length, Comparator comp
|
||||
, parallel_tag tag = parallel_tag(0))
|
||||
{
|
||||
typedef _DifferenceTp difference_type;
|
||||
_GLIBCXX_CALL(seqs_end - seqs_begin)
|
||||
|
||||
// catch special case: no sequences
|
||||
if (seqs_begin == seqs_end)
|
||||
return target;
|
||||
|
||||
// Execute merge; maybe parallel, depending on the number of merged
|
||||
// elements and the number of sequences and global thresholds in
|
||||
// Settings.
|
||||
if ((seqs_end - seqs_begin > 1) &&
|
||||
_GLIBCXX_PARALLEL_CONDITION(
|
||||
((seqs_end - seqs_begin) >=
|
||||
__gnu_parallel::_Settings::get().multiway_merge_minimal_k)
|
||||
&& ((sequence_index_t)length >=
|
||||
__gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
|
||||
return parallel_multiway_merge
|
||||
</* stable = */ false, /* sentinels = */ true>(
|
||||
seqs_begin, seqs_end,
|
||||
target, comp,
|
||||
multiway_merge_exact_splitting
|
||||
</* stable = */ false,
|
||||
typename std::iterator_traits<RandomAccessIteratorPairIterator>
|
||||
::value_type*, Comparator, _DifferenceTp>,
|
||||
static_cast<difference_type>(length));
|
||||
else
|
||||
return sequential_multiway_merge
|
||||
</* stable = */ false, /* sentinels = */ true>(
|
||||
seqs_begin, seqs_end,
|
||||
target, *(seqs_begin->second), comp, length);
|
||||
return multiway_merge_sentinels(seqs_begin, seqs_end, target, length, comp,
|
||||
exact_tag(tag.get_num_threads()));
|
||||
}
|
||||
|
||||
// public interface
|
||||
template<
|
||||
typename RandomAccessIteratorPairIterator
|
||||
, typename RandomAccessIteratorOut
|
||||
, typename _DifferenceTp
|
||||
, typename Comparator>
|
||||
RandomAccessIteratorOut
|
||||
multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
|
||||
, RandomAccessIteratorPairIterator seqs_end
|
||||
, RandomAccessIteratorOut target
|
||||
, _DifferenceTp length, Comparator comp
|
||||
, default_parallel_tag tag)
|
||||
{
|
||||
return multiway_merge_sentinels(seqs_begin, seqs_end, target, length, comp,
|
||||
exact_tag(tag.get_num_threads()));
|
||||
}
|
||||
|
||||
// stable_multiway_merge_sentinels
|
||||
// public interface
|
||||
template<
|
||||
typename RandomAccessIteratorPairIterator
|
||||
@ -1906,51 +2009,7 @@ RandomAccessIteratorOut
|
||||
stable_multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
|
||||
, RandomAccessIteratorPairIterator seqs_end
|
||||
, RandomAccessIteratorOut target
|
||||
, Comparator comp, _DifferenceTp length)
|
||||
{
|
||||
typedef _DifferenceTp difference_type;
|
||||
_GLIBCXX_CALL(seqs_end - seqs_begin)
|
||||
|
||||
// catch special case: no sequences
|
||||
if (seqs_begin == seqs_end)
|
||||
return target;
|
||||
|
||||
// Execute merge; maybe parallel, depending on the number of merged
|
||||
// elements and the number of sequences and global thresholds in
|
||||
// Settings.
|
||||
if ((seqs_end - seqs_begin > 1) &&
|
||||
_GLIBCXX_PARALLEL_CONDITION(
|
||||
((seqs_end - seqs_begin) >=
|
||||
__gnu_parallel::_Settings::get().multiway_merge_minimal_k)
|
||||
&& ((sequence_index_t)length >=
|
||||
__gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
|
||||
return parallel_multiway_merge
|
||||
</* stable = */ true, /* sentinels = */ true>(
|
||||
seqs_begin, seqs_end,
|
||||
target, comp,
|
||||
multiway_merge_sampling_splitting
|
||||
</* stable = */ true,
|
||||
typename std::iterator_traits<RandomAccessIteratorPairIterator>
|
||||
::value_type*, Comparator, _DifferenceTp>,
|
||||
static_cast<difference_type>(length));
|
||||
else
|
||||
return sequential_multiway_merge
|
||||
</* stable = */ true, /* sentinels = */ true>(
|
||||
seqs_begin, seqs_end,
|
||||
target, *(seqs_begin->second), comp, length);
|
||||
}
|
||||
|
||||
// public interface
|
||||
template<
|
||||
typename RandomAccessIteratorPairIterator
|
||||
, typename RandomAccessIteratorOut
|
||||
, typename _DifferenceTp
|
||||
, typename Comparator>
|
||||
RandomAccessIteratorOut
|
||||
stable_multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
|
||||
, RandomAccessIteratorPairIterator seqs_end
|
||||
, RandomAccessIteratorOut target
|
||||
, Comparator comp, _DifferenceTp length
|
||||
, _DifferenceTp length, Comparator comp
|
||||
, __gnu_parallel::sequential_tag)
|
||||
{
|
||||
typedef _DifferenceTp difference_type;
|
||||
@ -1963,7 +2022,7 @@ stable_multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
|
||||
// Execute multiway merge *sequentially*.
|
||||
return sequential_multiway_merge
|
||||
</* stable = */ true, /* sentinels = */ true>
|
||||
(seqs_begin, seqs_end, target, *(seqs_begin->second), comp, length);
|
||||
(seqs_begin, seqs_end, target, *(seqs_begin->second), length, comp);
|
||||
}
|
||||
|
||||
// public interface
|
||||
@ -1976,8 +2035,8 @@ RandomAccessIteratorOut
|
||||
stable_multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
|
||||
, RandomAccessIteratorPairIterator seqs_end
|
||||
, RandomAccessIteratorOut target
|
||||
, Comparator comp, _DifferenceTp length
|
||||
, __gnu_parallel::exact_tag)
|
||||
, _DifferenceTp length, Comparator comp
|
||||
, __gnu_parallel::exact_tag tag)
|
||||
{
|
||||
typedef _DifferenceTp difference_type;
|
||||
_GLIBCXX_CALL(seqs_end - seqs_begin)
|
||||
@ -1998,17 +2057,93 @@ stable_multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
|
||||
return parallel_multiway_merge
|
||||
</* stable = */ true, /* sentinels = */ true>(
|
||||
seqs_begin, seqs_end,
|
||||
target, comp,
|
||||
multiway_merge_exact_splitting
|
||||
</* stable = */ true,
|
||||
typename std::iterator_traits<RandomAccessIteratorPairIterator>
|
||||
::value_type*, Comparator, _DifferenceTp>,
|
||||
static_cast<difference_type>(length));
|
||||
target,
|
||||
multiway_merge_exact_splitting</* stable = */ true,
|
||||
typename std::iterator_traits<RandomAccessIteratorPairIterator>
|
||||
::value_type*, Comparator, _DifferenceTp>,
|
||||
static_cast<difference_type>(length), comp, tag.get_num_threads());
|
||||
else
|
||||
return sequential_multiway_merge
|
||||
</* stable = */ true, /* sentinels = */ true>(
|
||||
seqs_begin, seqs_end, target, *(seqs_begin->second), length, comp);
|
||||
}
|
||||
|
||||
// public interface
|
||||
template<
|
||||
typename RandomAccessIteratorPairIterator
|
||||
, typename RandomAccessIteratorOut
|
||||
, typename _DifferenceTp
|
||||
, typename Comparator>
|
||||
RandomAccessIteratorOut
|
||||
stable_multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
|
||||
, RandomAccessIteratorPairIterator seqs_end
|
||||
, RandomAccessIteratorOut target
|
||||
, _DifferenceTp length, Comparator comp
|
||||
, sampling_tag tag)
|
||||
{
|
||||
typedef _DifferenceTp difference_type;
|
||||
_GLIBCXX_CALL(seqs_end - seqs_begin)
|
||||
|
||||
// catch special case: no sequences
|
||||
if (seqs_begin == seqs_end)
|
||||
return target;
|
||||
|
||||
// Execute merge; maybe parallel, depending on the number of merged
|
||||
// elements and the number of sequences and global thresholds in
|
||||
// Settings.
|
||||
if ((seqs_end - seqs_begin > 1) &&
|
||||
_GLIBCXX_PARALLEL_CONDITION(
|
||||
((seqs_end - seqs_begin) >=
|
||||
__gnu_parallel::_Settings::get().multiway_merge_minimal_k)
|
||||
&& ((sequence_index_t)length >=
|
||||
__gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
|
||||
return parallel_multiway_merge
|
||||
</* stable = */ true, /* sentinels = */ true>(
|
||||
seqs_begin, seqs_end,
|
||||
target,
|
||||
multiway_merge_sampling_splitting</* stable = */ true,
|
||||
typename std::iterator_traits<RandomAccessIteratorPairIterator>
|
||||
::value_type*, Comparator, _DifferenceTp>,
|
||||
static_cast<difference_type>(length), comp, tag.get_num_threads());
|
||||
else
|
||||
return sequential_multiway_merge
|
||||
</* stable = */ true, /* sentinels = */ true>(
|
||||
seqs_begin, seqs_end,
|
||||
target, *(seqs_begin->second), comp, length);
|
||||
target, *(seqs_begin->second), length, comp);
|
||||
}
|
||||
|
||||
// public interface
|
||||
template<
|
||||
typename RandomAccessIteratorPairIterator
|
||||
, typename RandomAccessIteratorOut
|
||||
, typename _DifferenceTp
|
||||
, typename Comparator>
|
||||
RandomAccessIteratorOut
|
||||
stable_multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
|
||||
, RandomAccessIteratorPairIterator seqs_end
|
||||
, RandomAccessIteratorOut target
|
||||
, _DifferenceTp length, Comparator comp
|
||||
, parallel_tag tag = parallel_tag(0))
|
||||
{
|
||||
return stable_multiway_merge_sentinels(seqs_begin, seqs_end, target, length, comp,
|
||||
exact_tag(tag.get_num_threads()));
|
||||
}
|
||||
|
||||
// public interface
|
||||
template<
|
||||
typename RandomAccessIteratorPairIterator
|
||||
, typename RandomAccessIteratorOut
|
||||
, typename _DifferenceTp
|
||||
, typename Comparator>
|
||||
RandomAccessIteratorOut
|
||||
stable_multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
|
||||
, RandomAccessIteratorPairIterator seqs_end
|
||||
, RandomAccessIteratorOut target
|
||||
, _DifferenceTp length, Comparator comp
|
||||
, default_parallel_tag tag)
|
||||
{
|
||||
return stable_multiway_merge_sentinels(seqs_begin, seqs_end, target, length, comp,
|
||||
exact_tag(tag.get_num_threads()));
|
||||
}
|
||||
|
||||
}; // namespace __gnu_parallel
|
||||
|
@ -289,8 +289,8 @@ template<typename SeqRandomAccessIterator, typename RandomAccessIterator,
|
||||
Comparator& comp,
|
||||
DiffType length_am) const
|
||||
{
|
||||
stable_multiway_merge(seqs_begin, seqs_end, target, comp,
|
||||
length_am, sequential_tag());
|
||||
stable_multiway_merge(seqs_begin, seqs_end, target, length_am, comp,
|
||||
sequential_tag());
|
||||
}
|
||||
};
|
||||
|
||||
@ -306,8 +306,8 @@ template<typename SeqRandomAccessIterator, typename RandomAccessIterator,
|
||||
Comparator& comp,
|
||||
DiffType length_am) const
|
||||
{
|
||||
multiway_merge(seqs_begin, seqs_end, target, comp,
|
||||
length_am, sequential_tag());
|
||||
multiway_merge(seqs_begin, seqs_end, target, length_am, comp,
|
||||
sequential_tag());
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -47,9 +47,6 @@ namespace __gnu_parallel
|
||||
/** @brief Forces sequential execution at compile time. */
|
||||
struct sequential_tag { };
|
||||
|
||||
/** @brief Forces exact splitting in multiway merge at compile time. */
|
||||
struct exact_tag { };
|
||||
|
||||
/** @brief Recommends parallel execution at compile time,
|
||||
* optionally using a user-specified number of threads. */
|
||||
struct parallel_tag
|
||||
@ -119,6 +116,25 @@ namespace __gnu_parallel
|
||||
struct find_tag { };
|
||||
|
||||
|
||||
/** @brief Forces parallel merging
|
||||
* with exact splitting, at compile time. */
|
||||
struct exact_tag : public parallel_tag
|
||||
{
|
||||
exact_tag() { }
|
||||
exact_tag(thread_index_t num_threads)
|
||||
: parallel_tag(num_threads) { }
|
||||
};
|
||||
|
||||
/** @brief Forces parallel merging
|
||||
* with exact splitting, at compile time. */
|
||||
struct sampling_tag : public parallel_tag
|
||||
{
|
||||
sampling_tag() { }
|
||||
sampling_tag(thread_index_t num_threads)
|
||||
: parallel_tag(num_threads) { }
|
||||
};
|
||||
|
||||
|
||||
/** @brief Forces parallel sorting using multiway mergesort
|
||||
* at compile time. */
|
||||
struct multiway_mergesort_tag : public parallel_tag
|
||||
|
Loading…
Reference in New Issue
Block a user