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.)
|
(Choosing the variants at compile-time will come soon.)
|
||||||
</para>
|
</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>
|
<para>
|
||||||
For the <code>sort</code> and <code>stable_sort</code> algorithms, there are
|
For the <code>sort</code> and <code>stable_sort</code> algorithms, there are
|
||||||
several possible choices,
|
several additional choices, namely
|
||||||
<code>__gnu_parallel::parallel_tag</code>,
|
|
||||||
<code>__gnu_parallel::default_parallel_tag</code>,
|
|
||||||
<code>__gnu_parallel::multiway_mergesort_tag</code>,
|
<code>__gnu_parallel::multiway_mergesort_tag</code>,
|
||||||
<code>__gnu_parallel::multiway_mergesort_exact_tag</code>,
|
<code>__gnu_parallel::multiway_mergesort_exact_tag</code>,
|
||||||
<code>__gnu_parallel::multiway_mergesort_sampling_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>.
|
<code>__gnu_parallel::balanced_quicksort_tag</code>.
|
||||||
Multiway mergesort comes with two splitting strategies for merging, therefore
|
Multiway mergesort comes with the two splitting strategies for multi-way
|
||||||
the extra choice. If non is chosen, the default splitting strategy is selected.
|
merging. The quicksort options cannot be used for <code>stable_sort</code>.
|
||||||
<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.
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
</sect3>
|
</sect3>
|
||||||
|
@ -254,11 +254,11 @@ namespace __gnu_parallel
|
|||||||
RandomAccessIterator3
|
RandomAccessIterator3
|
||||||
target_end = parallel_multiway_merge
|
target_end = parallel_multiway_merge
|
||||||
< /* stable = */ true, /* sentinels = */ false>(
|
< /* stable = */ true, /* sentinels = */ false>(
|
||||||
seqs, seqs + 2, target, comp,
|
seqs, seqs + 2, target,
|
||||||
multiway_merge_exact_splitting
|
multiway_merge_exact_splitting
|
||||||
< /* stable = */ true, iterator_pair*,
|
< /* stable = */ true, iterator_pair*,
|
||||||
Comparator, difference_type1>,
|
Comparator, difference_type1>,
|
||||||
max_length);
|
max_length, comp, omp_get_max_threads());
|
||||||
|
|
||||||
return target_end;
|
return target_end;
|
||||||
}
|
}
|
||||||
|
@ -297,7 +297,7 @@ template<template<typename RAI, typename C> class iterator,
|
|||||||
RandomAccessIteratorIterator seqs_begin,
|
RandomAccessIteratorIterator seqs_begin,
|
||||||
RandomAccessIteratorIterator seqs_end,
|
RandomAccessIteratorIterator seqs_end,
|
||||||
RandomAccessIterator3 target,
|
RandomAccessIterator3 target,
|
||||||
Comparator comp, _DifferenceTp length)
|
_DifferenceTp length, Comparator comp)
|
||||||
{
|
{
|
||||||
_GLIBCXX_CALL(length);
|
_GLIBCXX_CALL(length);
|
||||||
|
|
||||||
@ -416,7 +416,7 @@ template<template<typename RAI, typename C> class iterator,
|
|||||||
multiway_merge_4_variant(RandomAccessIteratorIterator seqs_begin,
|
multiway_merge_4_variant(RandomAccessIteratorIterator seqs_begin,
|
||||||
RandomAccessIteratorIterator seqs_end,
|
RandomAccessIteratorIterator seqs_end,
|
||||||
RandomAccessIterator3 target,
|
RandomAccessIterator3 target,
|
||||||
Comparator comp, _DifferenceTp length)
|
_DifferenceTp length, Comparator comp)
|
||||||
{
|
{
|
||||||
_GLIBCXX_CALL(length);
|
_GLIBCXX_CALL(length);
|
||||||
typedef _DifferenceTp difference_type;
|
typedef _DifferenceTp difference_type;
|
||||||
@ -540,8 +540,7 @@ template<typename LT,
|
|||||||
multiway_merge_loser_tree(RandomAccessIteratorIterator seqs_begin,
|
multiway_merge_loser_tree(RandomAccessIteratorIterator seqs_begin,
|
||||||
RandomAccessIteratorIterator seqs_end,
|
RandomAccessIteratorIterator seqs_end,
|
||||||
RandomAccessIterator3 target,
|
RandomAccessIterator3 target,
|
||||||
Comparator comp,
|
_DifferenceTp length, Comparator comp)
|
||||||
_DifferenceTp length)
|
|
||||||
{
|
{
|
||||||
_GLIBCXX_CALL(length)
|
_GLIBCXX_CALL(length)
|
||||||
|
|
||||||
@ -626,8 +625,8 @@ template<typename LT,
|
|||||||
const typename std::iterator_traits<typename std::iterator_traits<
|
const typename std::iterator_traits<typename std::iterator_traits<
|
||||||
RandomAccessIteratorIterator>::value_type::first_type>::value_type&
|
RandomAccessIteratorIterator>::value_type::first_type>::value_type&
|
||||||
sentinel,
|
sentinel,
|
||||||
Comparator comp,
|
_DifferenceTp length,
|
||||||
_DifferenceTp length)
|
Comparator comp)
|
||||||
{
|
{
|
||||||
_GLIBCXX_CALL(length)
|
_GLIBCXX_CALL(length)
|
||||||
typedef _DifferenceTp difference_type;
|
typedef _DifferenceTp difference_type;
|
||||||
@ -716,8 +715,8 @@ template<
|
|||||||
const typename std::iterator_traits<typename std::iterator_traits<
|
const typename std::iterator_traits<typename std::iterator_traits<
|
||||||
RandomAccessIteratorIterator>::value_type::first_type>::value_type&
|
RandomAccessIteratorIterator>::value_type::first_type>::value_type&
|
||||||
sentinel,
|
sentinel,
|
||||||
Comparator comp,
|
_DifferenceTp length,
|
||||||
_DifferenceTp length)
|
Comparator comp)
|
||||||
{
|
{
|
||||||
_GLIBCXX_CALL(length)
|
_GLIBCXX_CALL(length)
|
||||||
|
|
||||||
@ -740,7 +739,7 @@ template<
|
|||||||
|
|
||||||
target_end = multiway_merge_loser_tree_unguarded
|
target_end = multiway_merge_loser_tree_unguarded
|
||||||
<UnguardedLoserTree>
|
<UnguardedLoserTree>
|
||||||
(seqs_begin, seqs_end, target, sentinel, comp, length);
|
(seqs_begin, seqs_end, target, sentinel, length, comp);
|
||||||
|
|
||||||
#if _GLIBCXX_ASSERTIONS
|
#if _GLIBCXX_ASSERTIONS
|
||||||
_GLIBCXX_PARALLEL_ASSERT(target_end == target + length);
|
_GLIBCXX_PARALLEL_ASSERT(target_end == target + length);
|
||||||
@ -808,10 +807,10 @@ struct multiway_merge_3_variant_sentinel_switch
|
|||||||
RandomAccessIteratorIterator seqs_begin,
|
RandomAccessIteratorIterator seqs_begin,
|
||||||
RandomAccessIteratorIterator seqs_end,
|
RandomAccessIteratorIterator seqs_end,
|
||||||
RandomAccessIterator3 target,
|
RandomAccessIterator3 target,
|
||||||
Comparator comp, _DifferenceTp length)
|
_DifferenceTp length, Comparator comp)
|
||||||
{
|
{
|
||||||
return multiway_merge_3_variant<guarded_iterator>(
|
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_begin,
|
||||||
RandomAccessIteratorIterator seqs_end,
|
RandomAccessIteratorIterator seqs_end,
|
||||||
RandomAccessIterator3 target,
|
RandomAccessIterator3 target,
|
||||||
Comparator comp, _DifferenceTp length)
|
_DifferenceTp length, Comparator comp)
|
||||||
{
|
{
|
||||||
return multiway_merge_3_variant<unguarded_iterator>(
|
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_begin,
|
||||||
RandomAccessIteratorIterator seqs_end,
|
RandomAccessIteratorIterator seqs_end,
|
||||||
RandomAccessIterator3 target,
|
RandomAccessIterator3 target,
|
||||||
Comparator comp, _DifferenceTp length)
|
_DifferenceTp length, Comparator comp)
|
||||||
{
|
{
|
||||||
return multiway_merge_4_variant<guarded_iterator>(
|
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_begin,
|
||||||
RandomAccessIteratorIterator seqs_end,
|
RandomAccessIteratorIterator seqs_end,
|
||||||
RandomAccessIterator3 target,
|
RandomAccessIterator3 target,
|
||||||
Comparator comp, _DifferenceTp length)
|
_DifferenceTp length, Comparator comp)
|
||||||
{
|
{
|
||||||
return multiway_merge_4_variant<unguarded_iterator>(
|
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<
|
const typename std::iterator_traits<typename std::iterator_traits<
|
||||||
RandomAccessIteratorIterator>::value_type::first_type>::value_type&
|
RandomAccessIteratorIterator>::value_type::first_type>::value_type&
|
||||||
sentinel,
|
sentinel,
|
||||||
Comparator comp, _DifferenceTp length)
|
_DifferenceTp length, Comparator comp)
|
||||||
{
|
{
|
||||||
typedef typename std::iterator_traits<RandomAccessIteratorIterator>
|
typedef typename std::iterator_traits<RandomAccessIteratorIterator>
|
||||||
::value_type::first_type
|
::value_type::first_type
|
||||||
@ -921,7 +920,7 @@ struct multiway_merge_k_variant_sentinel_switch
|
|||||||
loser_tree_traits<value_type>::use_pointer
|
loser_tree_traits<value_type>::use_pointer
|
||||||
, LoserTreePointerUnguarded<stable, value_type, Comparator>
|
, LoserTreePointerUnguarded<stable, value_type, Comparator>
|
||||||
, LoserTreeUnguarded<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<
|
const typename std::iterator_traits<typename std::iterator_traits<
|
||||||
RandomAccessIteratorIterator>::value_type::first_type>::value_type&
|
RandomAccessIteratorIterator>::value_type::first_type>::value_type&
|
||||||
sentinel,
|
sentinel,
|
||||||
Comparator comp, _DifferenceTp length)
|
_DifferenceTp length, Comparator comp)
|
||||||
{
|
{
|
||||||
typedef typename std::iterator_traits<RandomAccessIteratorIterator>
|
typedef typename std::iterator_traits<RandomAccessIteratorIterator>
|
||||||
::value_type::first_type
|
::value_type::first_type
|
||||||
@ -958,7 +957,7 @@ struct multiway_merge_k_variant_sentinel_switch
|
|||||||
loser_tree_traits<value_type>::use_pointer
|
loser_tree_traits<value_type>::use_pointer
|
||||||
, LoserTreePointer<stable, value_type, Comparator>
|
, LoserTreePointer<stable, value_type, Comparator>
|
||||||
, LoserTree<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<
|
const typename std::iterator_traits<typename std::iterator_traits<
|
||||||
RandomAccessIteratorIterator>::value_type::first_type>::value_type&
|
RandomAccessIteratorIterator>::value_type::first_type>::value_type&
|
||||||
sentinel,
|
sentinel,
|
||||||
Comparator comp, _DifferenceTp length)
|
_DifferenceTp length, Comparator comp)
|
||||||
{
|
{
|
||||||
_GLIBCXX_CALL(length)
|
_GLIBCXX_CALL(length)
|
||||||
|
|
||||||
@ -1043,7 +1042,7 @@ template<
|
|||||||
, RandomAccessIteratorIterator
|
, RandomAccessIteratorIterator
|
||||||
, RandomAccessIterator3
|
, RandomAccessIterator3
|
||||||
, _DifferenceTp
|
, _DifferenceTp
|
||||||
, Comparator>()(seqs_begin, seqs_end, target, comp, length);
|
, Comparator>()(seqs_begin, seqs_end, target, length, comp);
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
return_target = multiway_merge_4_variant_sentinel_switch<
|
return_target = multiway_merge_4_variant_sentinel_switch<
|
||||||
@ -1051,7 +1050,7 @@ template<
|
|||||||
, RandomAccessIteratorIterator
|
, RandomAccessIteratorIterator
|
||||||
, RandomAccessIterator3
|
, RandomAccessIterator3
|
||||||
, _DifferenceTp
|
, _DifferenceTp
|
||||||
, Comparator>()(seqs_begin, seqs_end, target, comp, length);
|
, Comparator>()(seqs_begin, seqs_end, target, length, comp);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return_target = multiway_merge_k_variant_sentinel_switch<
|
return_target = multiway_merge_k_variant_sentinel_switch<
|
||||||
@ -1060,8 +1059,7 @@ template<
|
|||||||
, RandomAccessIteratorIterator
|
, RandomAccessIteratorIterator
|
||||||
, RandomAccessIterator3
|
, RandomAccessIterator3
|
||||||
, _DifferenceTp
|
, _DifferenceTp
|
||||||
, Comparator>()
|
, Comparator>()(seqs_begin, seqs_end, target, sentinel, length, comp);
|
||||||
(seqs_begin, seqs_end, target, sentinel, comp, length);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#if _GLIBCXX_ASSERTIONS
|
#if _GLIBCXX_ASSERTIONS
|
||||||
@ -1108,8 +1106,7 @@ template<
|
|||||||
void multiway_merge_sampling_splitting(
|
void multiway_merge_sampling_splitting(
|
||||||
RandomAccessIteratorIterator seqs_begin,
|
RandomAccessIteratorIterator seqs_begin,
|
||||||
RandomAccessIteratorIterator seqs_end,
|
RandomAccessIteratorIterator seqs_end,
|
||||||
Comparator comp, difference_type length,
|
difference_type length, difference_type total_length, Comparator comp,
|
||||||
difference_type total_length,
|
|
||||||
std::vector<std::pair<difference_type, difference_type> > *pieces)
|
std::vector<std::pair<difference_type, difference_type> > *pieces)
|
||||||
{
|
{
|
||||||
typedef typename std::iterator_traits<RandomAccessIteratorIterator>
|
typedef typename std::iterator_traits<RandomAccessIteratorIterator>
|
||||||
@ -1190,9 +1187,7 @@ template<
|
|||||||
void multiway_merge_exact_splitting(
|
void multiway_merge_exact_splitting(
|
||||||
RandomAccessIteratorIterator seqs_begin,
|
RandomAccessIteratorIterator seqs_begin,
|
||||||
RandomAccessIteratorIterator seqs_end,
|
RandomAccessIteratorIterator seqs_end,
|
||||||
Comparator comp,
|
difference_type length, difference_type total_length, Comparator comp,
|
||||||
difference_type length,
|
|
||||||
difference_type total_length,
|
|
||||||
std::vector<std::pair<difference_type, difference_type> > *pieces)
|
std::vector<std::pair<difference_type, difference_type> > *pieces)
|
||||||
{
|
{
|
||||||
typedef typename std::iterator_traits<RandomAccessIteratorIterator>
|
typedef typename std::iterator_traits<RandomAccessIteratorIterator>
|
||||||
@ -1297,9 +1292,10 @@ template<
|
|||||||
parallel_multiway_merge(RandomAccessIteratorIterator seqs_begin,
|
parallel_multiway_merge(RandomAccessIteratorIterator seqs_begin,
|
||||||
RandomAccessIteratorIterator seqs_end,
|
RandomAccessIteratorIterator seqs_end,
|
||||||
RandomAccessIterator3 target,
|
RandomAccessIterator3 target,
|
||||||
Comparator comp,
|
|
||||||
Splitter splitter,
|
Splitter splitter,
|
||||||
_DifferenceTp length)
|
_DifferenceTp length,
|
||||||
|
Comparator comp,
|
||||||
|
thread_index_t num_threads)
|
||||||
{
|
{
|
||||||
#if _GLIBCXX_ASSERTIONS
|
#if _GLIBCXX_ASSERTIONS
|
||||||
_GLIBCXX_PARALLEL_ASSERT(seqs_end - seqs_begin > 1);
|
_GLIBCXX_PARALLEL_ASSERT(seqs_end - seqs_begin > 1);
|
||||||
@ -1347,8 +1343,8 @@ template<
|
|||||||
|
|
||||||
std::vector<std::pair<difference_type, difference_type> >* pieces;
|
std::vector<std::pair<difference_type, difference_type> >* pieces;
|
||||||
|
|
||||||
thread_index_t num_threads = static_cast<thread_index_t>
|
num_threads = static_cast<thread_index_t>
|
||||||
(std::min<difference_type>(get_max_threads(), total_length));
|
(std::min<difference_type>(num_threads, total_length));
|
||||||
|
|
||||||
# pragma omp parallel num_threads (num_threads)
|
# pragma omp parallel num_threads (num_threads)
|
||||||
{
|
{
|
||||||
@ -1365,8 +1361,8 @@ template<
|
|||||||
__gnu_parallel::_Settings::get().merge_oversampling *
|
__gnu_parallel::_Settings::get().merge_oversampling *
|
||||||
num_threads;
|
num_threads;
|
||||||
|
|
||||||
splitter(ne_seqs, ne_seqs + k, comp, length, total_length,
|
splitter(ne_seqs, ne_seqs + k, length, total_length,
|
||||||
pieces);
|
comp, pieces);
|
||||||
} //single
|
} //single
|
||||||
|
|
||||||
thread_index_t iam = omp_get_thread_num();
|
thread_index_t iam = omp_get_thread_num();
|
||||||
@ -1389,7 +1385,7 @@ template<
|
|||||||
if(length > target_position)
|
if(length > target_position)
|
||||||
sequential_multiway_merge<stable, sentinels>(
|
sequential_multiway_merge<stable, sentinels>(
|
||||||
chunks, chunks + k, target + target_position,
|
chunks, chunks + k, target + target_position,
|
||||||
*(seqs_begin->second), comp, length - target_position);
|
*(seqs_begin->second), length - target_position, comp);
|
||||||
|
|
||||||
delete[] chunks;
|
delete[] chunks;
|
||||||
} // parallel
|
} // parallel
|
||||||
@ -1481,6 +1477,7 @@ template<
|
|||||||
*
|
*
|
||||||
* @return end iterator of output sequence
|
* @return end iterator of output sequence
|
||||||
*/
|
*/
|
||||||
|
// multiway_merge
|
||||||
// public interface
|
// public interface
|
||||||
template<
|
template<
|
||||||
typename RandomAccessIteratorPairIterator
|
typename RandomAccessIteratorPairIterator
|
||||||
@ -1491,49 +1488,7 @@ RandomAccessIteratorOut
|
|||||||
multiway_merge(RandomAccessIteratorPairIterator seqs_begin
|
multiway_merge(RandomAccessIteratorPairIterator seqs_begin
|
||||||
, RandomAccessIteratorPairIterator seqs_end
|
, RandomAccessIteratorPairIterator seqs_end
|
||||||
, RandomAccessIteratorOut target
|
, RandomAccessIteratorOut target
|
||||||
, Comparator comp, _DifferenceTp length)
|
, _DifferenceTp length, Comparator comp
|
||||||
{
|
|
||||||
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
|
|
||||||
, __gnu_parallel::sequential_tag)
|
, __gnu_parallel::sequential_tag)
|
||||||
{
|
{
|
||||||
typedef _DifferenceTp difference_type;
|
typedef _DifferenceTp difference_type;
|
||||||
@ -1546,10 +1501,10 @@ multiway_merge(RandomAccessIteratorPairIterator seqs_begin
|
|||||||
// Execute multiway merge *sequentially*.
|
// Execute multiway merge *sequentially*.
|
||||||
return sequential_multiway_merge
|
return sequential_multiway_merge
|
||||||
</* stable = */ false, /* sentinels = */ false>
|
</* 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<
|
template<
|
||||||
typename RandomAccessIteratorPairIterator
|
typename RandomAccessIteratorPairIterator
|
||||||
, typename RandomAccessIteratorOut
|
, typename RandomAccessIteratorOut
|
||||||
@ -1559,8 +1514,50 @@ RandomAccessIteratorOut
|
|||||||
multiway_merge(RandomAccessIteratorPairIterator seqs_begin
|
multiway_merge(RandomAccessIteratorPairIterator seqs_begin
|
||||||
, RandomAccessIteratorPairIterator seqs_end
|
, RandomAccessIteratorPairIterator seqs_end
|
||||||
, RandomAccessIteratorOut target
|
, RandomAccessIteratorOut target
|
||||||
, Comparator comp, _DifferenceTp length
|
, _DifferenceTp length, Comparator comp
|
||||||
, __gnu_parallel::exact_tag)
|
, __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;
|
typedef _DifferenceTp difference_type;
|
||||||
_GLIBCXX_CALL(seqs_end - seqs_begin)
|
_GLIBCXX_CALL(seqs_end - seqs_begin)
|
||||||
@ -1581,16 +1578,16 @@ multiway_merge(RandomAccessIteratorPairIterator seqs_begin
|
|||||||
return parallel_multiway_merge
|
return parallel_multiway_merge
|
||||||
</* stable = */ false, /* sentinels = */ false>(
|
</* stable = */ false, /* sentinels = */ false>(
|
||||||
seqs_begin, seqs_end,
|
seqs_begin, seqs_end,
|
||||||
target, comp,
|
target,
|
||||||
multiway_merge_exact_splitting</* stable = */ false,
|
multiway_merge_exact_splitting</* stable = */ false,
|
||||||
typename std::iterator_traits<RandomAccessIteratorPairIterator>
|
typename std::iterator_traits<RandomAccessIteratorPairIterator>
|
||||||
::value_type*, Comparator, _DifferenceTp>,
|
::value_type*, Comparator, _DifferenceTp>,
|
||||||
static_cast<difference_type>(length));
|
static_cast<difference_type>(length), comp, tag.get_num_threads());
|
||||||
else
|
else
|
||||||
return sequential_multiway_merge
|
return sequential_multiway_merge
|
||||||
</* stable = */ false, /* sentinels = */ false>(
|
</* stable = */ false, /* sentinels = */ false>(
|
||||||
seqs_begin, seqs_end,
|
seqs_begin, seqs_end,
|
||||||
target, *(seqs_begin->second), comp, length);
|
target, *(seqs_begin->second), length, comp);
|
||||||
}
|
}
|
||||||
|
|
||||||
// public interface
|
// public interface
|
||||||
@ -1600,42 +1597,34 @@ template<
|
|||||||
, typename _DifferenceTp
|
, typename _DifferenceTp
|
||||||
, typename Comparator>
|
, typename Comparator>
|
||||||
RandomAccessIteratorOut
|
RandomAccessIteratorOut
|
||||||
stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin
|
multiway_merge(RandomAccessIteratorPairIterator seqs_begin
|
||||||
, RandomAccessIteratorPairIterator seqs_end
|
, RandomAccessIteratorPairIterator seqs_end
|
||||||
, RandomAccessIteratorOut target
|
, RandomAccessIteratorOut target
|
||||||
, Comparator comp, _DifferenceTp length)
|
, _DifferenceTp length, Comparator comp
|
||||||
|
, parallel_tag tag = parallel_tag(0))
|
||||||
{
|
{
|
||||||
typedef _DifferenceTp difference_type;
|
return multiway_merge(seqs_begin, seqs_end, target, length, comp,
|
||||||
_GLIBCXX_CALL(seqs_end - seqs_begin)
|
exact_tag(tag.get_num_threads()));
|
||||||
|
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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
|
// public interface
|
||||||
template<
|
template<
|
||||||
typename RandomAccessIteratorPairIterator
|
typename RandomAccessIteratorPairIterator
|
||||||
@ -1646,7 +1635,7 @@ RandomAccessIteratorOut
|
|||||||
stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin
|
stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin
|
||||||
, RandomAccessIteratorPairIterator seqs_end
|
, RandomAccessIteratorPairIterator seqs_end
|
||||||
, RandomAccessIteratorOut target
|
, RandomAccessIteratorOut target
|
||||||
, Comparator comp, _DifferenceTp length
|
, _DifferenceTp length, Comparator comp
|
||||||
, __gnu_parallel::sequential_tag)
|
, __gnu_parallel::sequential_tag)
|
||||||
{
|
{
|
||||||
typedef _DifferenceTp difference_type;
|
typedef _DifferenceTp difference_type;
|
||||||
@ -1659,7 +1648,7 @@ stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin
|
|||||||
// Execute multiway merge *sequentially*.
|
// Execute multiway merge *sequentially*.
|
||||||
return sequential_multiway_merge
|
return sequential_multiway_merge
|
||||||
</* stable = */ true, /* sentinels = */ false>
|
</* 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
|
// public interface
|
||||||
@ -1672,8 +1661,8 @@ RandomAccessIteratorOut
|
|||||||
stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin
|
stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin
|
||||||
, RandomAccessIteratorPairIterator seqs_end
|
, RandomAccessIteratorPairIterator seqs_end
|
||||||
, RandomAccessIteratorOut target
|
, RandomAccessIteratorOut target
|
||||||
, Comparator comp, _DifferenceTp length
|
, _DifferenceTp length, Comparator comp
|
||||||
, __gnu_parallel::exact_tag)
|
, __gnu_parallel::exact_tag tag)
|
||||||
{
|
{
|
||||||
typedef _DifferenceTp difference_type;
|
typedef _DifferenceTp difference_type;
|
||||||
_GLIBCXX_CALL(seqs_end - seqs_begin)
|
_GLIBCXX_CALL(seqs_end - seqs_begin)
|
||||||
@ -1694,17 +1683,95 @@ stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin
|
|||||||
return parallel_multiway_merge
|
return parallel_multiway_merge
|
||||||
</* stable = */ true, /* sentinels = */ false>(
|
</* stable = */ true, /* sentinels = */ false>(
|
||||||
seqs_begin, seqs_end,
|
seqs_begin, seqs_end,
|
||||||
target, comp,
|
target,
|
||||||
multiway_merge_exact_splitting
|
multiway_merge_exact_splitting</* stable = */ true,
|
||||||
</* stable = */ true,
|
typename std::iterator_traits<RandomAccessIteratorPairIterator>
|
||||||
typename std::iterator_traits<RandomAccessIteratorPairIterator>
|
::value_type*, Comparator, _DifferenceTp>,
|
||||||
::value_type*, Comparator, _DifferenceTp>,
|
static_cast<difference_type>(length), comp, tag.get_num_threads());
|
||||||
static_cast<difference_type>(length));
|
|
||||||
else
|
else
|
||||||
return sequential_multiway_merge</* stable = */ true,
|
return sequential_multiway_merge</* stable = */ true,
|
||||||
/* sentinels = */ false>(
|
/* sentinels = */ false>(
|
||||||
seqs_begin, seqs_end,
|
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
|
* @return end iterator of output sequence
|
||||||
*/
|
*/
|
||||||
|
// multiway_merge_sentinels
|
||||||
// public interface
|
// public interface
|
||||||
template<
|
template<
|
||||||
typename RandomAccessIteratorPairIterator
|
typename RandomAccessIteratorPairIterator
|
||||||
@ -1792,7 +1860,79 @@ RandomAccessIteratorOut
|
|||||||
multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
|
multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
|
||||||
, RandomAccessIteratorPairIterator seqs_end
|
, RandomAccessIteratorPairIterator seqs_end
|
||||||
, RandomAccessIteratorOut target
|
, 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;
|
typedef _DifferenceTp difference_type;
|
||||||
_GLIBCXX_CALL(seqs_end - seqs_begin)
|
_GLIBCXX_CALL(seqs_end - seqs_begin)
|
||||||
@ -1812,43 +1952,16 @@ multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
|
|||||||
__gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
|
__gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
|
||||||
return parallel_multiway_merge
|
return parallel_multiway_merge
|
||||||
</* stable = */ false, /* sentinels = */ true>
|
</* stable = */ false, /* sentinels = */ true>
|
||||||
(seqs_begin, seqs_end, target, comp,
|
(seqs_begin, seqs_end, target,
|
||||||
multiway_merge_sampling_splitting
|
multiway_merge_sampling_splitting</* stable = */ false,
|
||||||
</* stable = */ false,
|
typename std::iterator_traits<RandomAccessIteratorPairIterator>
|
||||||
typename std::iterator_traits<RandomAccessIteratorPairIterator>
|
::value_type*, Comparator, _DifferenceTp>,
|
||||||
::value_type*, Comparator, _DifferenceTp>,
|
static_cast<difference_type>(length), comp, tag.get_num_threads());
|
||||||
static_cast<difference_type>(length));
|
|
||||||
else
|
else
|
||||||
return sequential_multiway_merge
|
return sequential_multiway_merge
|
||||||
</* stable = */false, /* sentinels = */ true>(
|
</* stable = */false, /* sentinels = */ true>(
|
||||||
seqs_begin, seqs_end,
|
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
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// public interface
|
// public interface
|
||||||
@ -1861,41 +1974,31 @@ RandomAccessIteratorOut
|
|||||||
multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
|
multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
|
||||||
, RandomAccessIteratorPairIterator seqs_end
|
, RandomAccessIteratorPairIterator seqs_end
|
||||||
, RandomAccessIteratorOut target
|
, RandomAccessIteratorOut target
|
||||||
, Comparator comp, _DifferenceTp length
|
, _DifferenceTp length, Comparator comp
|
||||||
, __gnu_parallel::exact_tag)
|
, parallel_tag tag = parallel_tag(0))
|
||||||
{
|
{
|
||||||
typedef _DifferenceTp difference_type;
|
return multiway_merge_sentinels(seqs_begin, seqs_end, target, length, comp,
|
||||||
_GLIBCXX_CALL(seqs_end - seqs_begin)
|
exact_tag(tag.get_num_threads()));
|
||||||
|
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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
|
// public interface
|
||||||
template<
|
template<
|
||||||
typename RandomAccessIteratorPairIterator
|
typename RandomAccessIteratorPairIterator
|
||||||
@ -1906,51 +2009,7 @@ RandomAccessIteratorOut
|
|||||||
stable_multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
|
stable_multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
|
||||||
, RandomAccessIteratorPairIterator seqs_end
|
, RandomAccessIteratorPairIterator seqs_end
|
||||||
, RandomAccessIteratorOut target
|
, RandomAccessIteratorOut target
|
||||||
, Comparator comp, _DifferenceTp length)
|
, _DifferenceTp length, Comparator comp
|
||||||
{
|
|
||||||
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
|
|
||||||
, __gnu_parallel::sequential_tag)
|
, __gnu_parallel::sequential_tag)
|
||||||
{
|
{
|
||||||
typedef _DifferenceTp difference_type;
|
typedef _DifferenceTp difference_type;
|
||||||
@ -1963,7 +2022,7 @@ stable_multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
|
|||||||
// Execute multiway merge *sequentially*.
|
// Execute multiway merge *sequentially*.
|
||||||
return sequential_multiway_merge
|
return sequential_multiway_merge
|
||||||
</* stable = */ true, /* sentinels = */ true>
|
</* 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
|
// public interface
|
||||||
@ -1976,8 +2035,8 @@ RandomAccessIteratorOut
|
|||||||
stable_multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
|
stable_multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
|
||||||
, RandomAccessIteratorPairIterator seqs_end
|
, RandomAccessIteratorPairIterator seqs_end
|
||||||
, RandomAccessIteratorOut target
|
, RandomAccessIteratorOut target
|
||||||
, Comparator comp, _DifferenceTp length
|
, _DifferenceTp length, Comparator comp
|
||||||
, __gnu_parallel::exact_tag)
|
, __gnu_parallel::exact_tag tag)
|
||||||
{
|
{
|
||||||
typedef _DifferenceTp difference_type;
|
typedef _DifferenceTp difference_type;
|
||||||
_GLIBCXX_CALL(seqs_end - seqs_begin)
|
_GLIBCXX_CALL(seqs_end - seqs_begin)
|
||||||
@ -1998,17 +2057,93 @@ stable_multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
|
|||||||
return parallel_multiway_merge
|
return parallel_multiway_merge
|
||||||
</* stable = */ true, /* sentinels = */ true>(
|
</* stable = */ true, /* sentinels = */ true>(
|
||||||
seqs_begin, seqs_end,
|
seqs_begin, seqs_end,
|
||||||
target, comp,
|
target,
|
||||||
multiway_merge_exact_splitting
|
multiway_merge_exact_splitting</* stable = */ true,
|
||||||
</* stable = */ true,
|
typename std::iterator_traits<RandomAccessIteratorPairIterator>
|
||||||
typename std::iterator_traits<RandomAccessIteratorPairIterator>
|
::value_type*, Comparator, _DifferenceTp>,
|
||||||
::value_type*, Comparator, _DifferenceTp>,
|
static_cast<difference_type>(length), comp, tag.get_num_threads());
|
||||||
static_cast<difference_type>(length));
|
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
|
else
|
||||||
return sequential_multiway_merge
|
return sequential_multiway_merge
|
||||||
</* stable = */ true, /* sentinels = */ true>(
|
</* stable = */ true, /* sentinels = */ true>(
|
||||||
seqs_begin, seqs_end,
|
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
|
}; // namespace __gnu_parallel
|
||||||
|
@ -289,8 +289,8 @@ template<typename SeqRandomAccessIterator, typename RandomAccessIterator,
|
|||||||
Comparator& comp,
|
Comparator& comp,
|
||||||
DiffType length_am) const
|
DiffType length_am) const
|
||||||
{
|
{
|
||||||
stable_multiway_merge(seqs_begin, seqs_end, target, comp,
|
stable_multiway_merge(seqs_begin, seqs_end, target, length_am, comp,
|
||||||
length_am, sequential_tag());
|
sequential_tag());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -306,8 +306,8 @@ template<typename SeqRandomAccessIterator, typename RandomAccessIterator,
|
|||||||
Comparator& comp,
|
Comparator& comp,
|
||||||
DiffType length_am) const
|
DiffType length_am) const
|
||||||
{
|
{
|
||||||
multiway_merge(seqs_begin, seqs_end, target, comp,
|
multiway_merge(seqs_begin, seqs_end, target, length_am, comp,
|
||||||
length_am, sequential_tag());
|
sequential_tag());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -47,9 +47,6 @@ namespace __gnu_parallel
|
|||||||
/** @brief Forces sequential execution at compile time. */
|
/** @brief Forces sequential execution at compile time. */
|
||||||
struct sequential_tag { };
|
struct sequential_tag { };
|
||||||
|
|
||||||
/** @brief Forces exact splitting in multiway merge at compile time. */
|
|
||||||
struct exact_tag { };
|
|
||||||
|
|
||||||
/** @brief Recommends parallel execution at compile time,
|
/** @brief Recommends parallel execution at compile time,
|
||||||
* optionally using a user-specified number of threads. */
|
* optionally using a user-specified number of threads. */
|
||||||
struct parallel_tag
|
struct parallel_tag
|
||||||
@ -119,6 +116,25 @@ namespace __gnu_parallel
|
|||||||
struct find_tag { };
|
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
|
/** @brief Forces parallel sorting using multiway mergesort
|
||||||
* at compile time. */
|
* at compile time. */
|
||||||
struct multiway_mergesort_tag : public parallel_tag
|
struct multiway_mergesort_tag : public parallel_tag
|
||||||
|
Loading…
x
Reference in New Issue
Block a user