diff --git a/libstdc++-v3/doc/xml/manual/parallel_mode.xml b/libstdc++-v3/doc/xml/manual/parallel_mode.xml index fb439062fea..faea5a9e7f6 100644 --- a/libstdc++-v3/doc/xml/manual/parallel_mode.xml +++ b/libstdc++-v3/doc/xml/manual/parallel_mode.xml @@ -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.) + +For the following algorithms in general, we have +__gnu_parallel::parallel_tag and +__gnu_parallel::default_parallel_tag, in addition to +__gnu_parallel::sequential_tag. +__gnu_parallel::default_parallel_tag chooses the default +algorithm at compiletime, as does omitting the tag. +__gnu_parallel::parallel_tag 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. + + + +The multiway_merge algorithm comes with the additional choices, +__gnu_parallel::exact_tag and +__gnu_parallel::sampling_tag. +Exact and sampling are the two available splitting strategies. + + For the sort and stable_sort algorithms, there are -several possible choices, -__gnu_parallel::parallel_tag, -__gnu_parallel::default_parallel_tag, +several additional choices, namely __gnu_parallel::multiway_mergesort_tag, __gnu_parallel::multiway_mergesort_exact_tag, __gnu_parallel::multiway_mergesort_sampling_tag, -__gnu_parallel::quicksort_tag, +__gnu_parallel::quicksort_tag, and __gnu_parallel::balanced_quicksort_tag. -Multiway mergesort comes with two splitting strategies for merging, therefore -the extra choice. If non is chosen, the default splitting strategy is selected. -__gnu_parallel::default_parallel_tag chooses the default parallel -sorting algorithm at runtime. __gnu_parallel::parallel_tag -postpones the decision to runtime (see next section). -The quicksort options cannot be used for stable_sort. -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 stable_sort. diff --git a/libstdc++-v3/include/parallel/merge.h b/libstdc++-v3/include/parallel/merge.h index cabd5bd4de2..580b1479329 100644 --- a/libstdc++-v3/include/parallel/merge.h +++ b/libstdc++-v3/include/parallel/merge.h @@ -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; } diff --git a/libstdc++-v3/include/parallel/multiway_merge.h b/libstdc++-v3/include/parallel/multiway_merge.h index 37e99cdeb6a..3c75c70f3c4 100644 --- a/libstdc++-v3/include/parallel/multiway_merge.h +++ b/libstdc++-v3/include/parallel/multiway_merge.h @@ -297,7 +297,7 @@ template 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 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::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::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 - (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( - 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( - 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( - 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( - 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::value_type::first_type>::value_type& sentinel, - Comparator comp, _DifferenceTp length) + _DifferenceTp length, Comparator comp) { typedef typename std::iterator_traits ::value_type::first_type @@ -921,7 +920,7 @@ struct multiway_merge_k_variant_sentinel_switch loser_tree_traits::use_pointer , LoserTreePointerUnguarded , LoserTreeUnguarded - >::__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::value_type::first_type>::value_type& sentinel, - Comparator comp, _DifferenceTp length) + _DifferenceTp length, Comparator comp) { typedef typename std::iterator_traits ::value_type::first_type @@ -958,7 +957,7 @@ struct multiway_merge_k_variant_sentinel_switch loser_tree_traits::use_pointer , LoserTreePointer , LoserTree - >::__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::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 > *pieces) { typedef typename std::iterator_traits @@ -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 > *pieces) { typedef typename std::iterator_traits @@ -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 >* pieces; - thread_index_t num_threads = static_cast - (std::min(get_max_threads(), total_length)); + num_threads = static_cast + (std::min(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( 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 - - (seqs_begin, seqs_end, target, comp, - multiway_merge_sampling_splitting - ::value_type*, Comparator, _DifferenceTp>, - static_cast(length)); - else - return sequential_multiway_merge - ( - 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 - (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 + ( + seqs_begin, seqs_end, target, + multiway_merge_exact_splitting + ::value_type*, Comparator, _DifferenceTp>, + static_cast(length), comp, tag.get_num_threads()); + else + return sequential_multiway_merge + ( + 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 ( seqs_begin, seqs_end, - target, comp, + target, multiway_merge_exact_splitting ::value_type*, Comparator, _DifferenceTp>, - static_cast(length)); + static_cast(length), comp, tag.get_num_threads()); else return sequential_multiway_merge ( 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 - ( - seqs_begin, seqs_end, - target, comp, - multiway_merge_sampling_splitting - ::value_type*, Comparator, _DifferenceTp>, - static_cast(length)); - else - return sequential_multiway_merge - ( - 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 - (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 ( seqs_begin, seqs_end, - target, comp, - multiway_merge_exact_splitting - - ::value_type*, Comparator, _DifferenceTp>, - static_cast(length)); + target, + multiway_merge_exact_splitting + ::value_type*, Comparator, _DifferenceTp>, + static_cast(length), comp, tag.get_num_threads()); else return sequential_multiway_merge( 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 + ( + seqs_begin, seqs_end, + target, + multiway_merge_sampling_splitting + ::value_type*, Comparator, _DifferenceTp>, + static_cast(length), comp, tag.get_num_threads()); + else + return sequential_multiway_merge + ( + 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 + + (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 + ( + seqs_begin, seqs_end, + target, + multiway_merge_exact_splitting + ::value_type*, Comparator, _DifferenceTp>, + static_cast(length), comp, tag.get_num_threads()); + else + return sequential_multiway_merge + ( + 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 - (seqs_begin, seqs_end, target, comp, - multiway_merge_sampling_splitting - - ::value_type*, Comparator, _DifferenceTp>, - static_cast(length)); + (seqs_begin, seqs_end, target, + multiway_merge_sampling_splitting + ::value_type*, Comparator, _DifferenceTp>, + static_cast(length), comp, tag.get_num_threads()); else return sequential_multiway_merge ( 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 - - (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 - ( - seqs_begin, seqs_end, - target, comp, - multiway_merge_exact_splitting - - ::value_type*, Comparator, _DifferenceTp>, - static_cast(length)); - else - return sequential_multiway_merge - ( - 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 - ( - seqs_begin, seqs_end, - target, comp, - multiway_merge_sampling_splitting - - ::value_type*, Comparator, _DifferenceTp>, - static_cast(length)); - else - return sequential_multiway_merge - ( - 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 - (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 ( seqs_begin, seqs_end, - target, comp, - multiway_merge_exact_splitting - - ::value_type*, Comparator, _DifferenceTp>, - static_cast(length)); + target, + multiway_merge_exact_splitting + ::value_type*, Comparator, _DifferenceTp>, + static_cast(length), comp, tag.get_num_threads()); + else + return sequential_multiway_merge + ( + 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 + ( + seqs_begin, seqs_end, + target, + multiway_merge_sampling_splitting + ::value_type*, Comparator, _DifferenceTp>, + static_cast(length), comp, tag.get_num_threads()); else return sequential_multiway_merge ( 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 diff --git a/libstdc++-v3/include/parallel/multiway_mergesort.h b/libstdc++-v3/include/parallel/multiway_mergesort.h index 3791a144d53..9d9733ad05f 100644 --- a/libstdc++-v3/include/parallel/multiway_mergesort.h +++ b/libstdc++-v3/include/parallel/multiway_mergesort.h @@ -289,8 +289,8 @@ template