sort.h 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. // -*- C++ -*-
  2. // Copyright (C) 2007-2022 Free Software Foundation, Inc.
  3. //
  4. // This file is part of the GNU ISO C++ Library. This library is free
  5. // software; you can redistribute it and/or modify it under the terms
  6. // of the GNU General Public License as published by the Free Software
  7. // Foundation; either version 3, or (at your option) any later
  8. // version.
  9. // This library is distributed in the hope that it will be useful, but
  10. // WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. // General Public License for more details.
  13. // Under Section 7 of GPL version 3, you are granted additional
  14. // permissions described in the GCC Runtime Library Exception, version
  15. // 3.1, as published by the Free Software Foundation.
  16. // You should have received a copy of the GNU General Public License and
  17. // a copy of the GCC Runtime Library Exception along with this program;
  18. // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  19. // <http://www.gnu.org/licenses/>.
  20. /** @file parallel/sort.h
  21. * @brief Parallel sorting algorithm switch.
  22. * This file is a GNU parallel extension to the Standard C++ Library.
  23. */
  24. // Written by Johannes Singler.
  25. #ifndef _GLIBCXX_PARALLEL_SORT_H
  26. #define _GLIBCXX_PARALLEL_SORT_H 1
  27. #include <parallel/basic_iterator.h>
  28. #include <parallel/features.h>
  29. #include <parallel/parallel.h>
  30. #if _GLIBCXX_PARALLEL_ASSERTIONS
  31. #include <parallel/checkers.h>
  32. #endif
  33. #if _GLIBCXX_MERGESORT
  34. #include <parallel/multiway_mergesort.h>
  35. #endif
  36. #if _GLIBCXX_QUICKSORT
  37. #include <parallel/quicksort.h>
  38. #endif
  39. #if _GLIBCXX_BAL_QUICKSORT
  40. #include <parallel/balanced_quicksort.h>
  41. #endif
  42. namespace __gnu_parallel
  43. {
  44. //prototype
  45. template<bool __stable, typename _RAIter,
  46. typename _Compare, typename _Parallelism>
  47. void
  48. __parallel_sort(_RAIter __begin, _RAIter __end,
  49. _Compare __comp, _Parallelism __parallelism);
  50. /**
  51. * @brief Choose multiway mergesort, splitting variant at run-time,
  52. * for parallel sorting.
  53. * @param __begin Begin iterator of input sequence.
  54. * @param __end End iterator of input sequence.
  55. * @param __comp Comparator.
  56. * @tparam __stable Sort stable.
  57. * @callgraph
  58. */
  59. template<bool __stable, typename _RAIter, typename _Compare>
  60. inline void
  61. __parallel_sort(_RAIter __begin, _RAIter __end,
  62. _Compare __comp, multiway_mergesort_tag __parallelism)
  63. {
  64. _GLIBCXX_CALL(__end - __begin)
  65. if(_Settings::get().sort_splitting == EXACT)
  66. parallel_sort_mwms<__stable, true>
  67. (__begin, __end, __comp, __parallelism.__get_num_threads());
  68. else
  69. parallel_sort_mwms<__stable, false>
  70. (__begin, __end, __comp, __parallelism.__get_num_threads());
  71. }
  72. /**
  73. * @brief Choose multiway mergesort with exact splitting,
  74. * for parallel sorting.
  75. * @param __begin Begin iterator of input sequence.
  76. * @param __end End iterator of input sequence.
  77. * @param __comp Comparator.
  78. * @tparam __stable Sort stable.
  79. * @callgraph
  80. */
  81. template<bool __stable, typename _RAIter, typename _Compare>
  82. inline void
  83. __parallel_sort(_RAIter __begin, _RAIter __end,
  84. _Compare __comp,
  85. multiway_mergesort_exact_tag __parallelism)
  86. {
  87. _GLIBCXX_CALL(__end - __begin)
  88. parallel_sort_mwms<__stable, true>
  89. (__begin, __end, __comp, __parallelism.__get_num_threads());
  90. }
  91. /**
  92. * @brief Choose multiway mergesort with splitting by sampling,
  93. * for parallel sorting.
  94. * @param __begin Begin iterator of input sequence.
  95. * @param __end End iterator of input sequence.
  96. * @param __comp Comparator.
  97. * @tparam __stable Sort stable.
  98. * @callgraph
  99. */
  100. template<bool __stable, typename _RAIter, typename _Compare>
  101. inline void
  102. __parallel_sort(_RAIter __begin, _RAIter __end,
  103. _Compare __comp,
  104. multiway_mergesort_sampling_tag __parallelism)
  105. {
  106. _GLIBCXX_CALL(__end - __begin)
  107. parallel_sort_mwms<__stable, false>
  108. (__begin, __end, __comp, __parallelism.__get_num_threads());
  109. }
  110. /**
  111. * @brief Choose quicksort for parallel sorting.
  112. * @param __begin Begin iterator of input sequence.
  113. * @param __end End iterator of input sequence.
  114. * @param __comp Comparator.
  115. * @tparam __stable Sort stable.
  116. * @callgraph
  117. */
  118. template<bool __stable, typename _RAIter, typename _Compare>
  119. inline void
  120. __parallel_sort(_RAIter __begin, _RAIter __end,
  121. _Compare __comp, quicksort_tag __parallelism)
  122. {
  123. _GLIBCXX_CALL(__end - __begin)
  124. _GLIBCXX_PARALLEL_ASSERT(__stable == false);
  125. __parallel_sort_qs(__begin, __end, __comp,
  126. __parallelism.__get_num_threads());
  127. }
  128. /**
  129. * @brief Choose balanced quicksort for parallel sorting.
  130. * @param __begin Begin iterator of input sequence.
  131. * @param __end End iterator of input sequence.
  132. * @param __comp Comparator.
  133. * @tparam __stable Sort stable.
  134. * @callgraph
  135. */
  136. template<bool __stable, typename _RAIter, typename _Compare>
  137. inline void
  138. __parallel_sort(_RAIter __begin, _RAIter __end,
  139. _Compare __comp, balanced_quicksort_tag __parallelism)
  140. {
  141. _GLIBCXX_CALL(__end - __begin)
  142. _GLIBCXX_PARALLEL_ASSERT(__stable == false);
  143. __parallel_sort_qsb(__begin, __end, __comp,
  144. __parallelism.__get_num_threads());
  145. }
  146. /**
  147. * @brief Choose multiway mergesort with exact splitting,
  148. * for parallel sorting.
  149. * @param __begin Begin iterator of input sequence.
  150. * @param __end End iterator of input sequence.
  151. * @param __comp Comparator.
  152. * @tparam __stable Sort stable.
  153. * @callgraph
  154. */
  155. template<bool __stable, typename _RAIter, typename _Compare>
  156. inline void
  157. __parallel_sort(_RAIter __begin, _RAIter __end,
  158. _Compare __comp, default_parallel_tag __parallelism)
  159. {
  160. _GLIBCXX_CALL(__end - __begin)
  161. __parallel_sort<__stable>
  162. (__begin, __end, __comp,
  163. multiway_mergesort_exact_tag(__parallelism.__get_num_threads()));
  164. }
  165. /**
  166. * @brief Choose a parallel sorting algorithm.
  167. * @param __begin Begin iterator of input sequence.
  168. * @param __end End iterator of input sequence.
  169. * @param __comp Comparator.
  170. * @tparam __stable Sort stable.
  171. * @callgraph
  172. */
  173. template<bool __stable, typename _RAIter, typename _Compare>
  174. inline void
  175. __parallel_sort(_RAIter __begin, _RAIter __end,
  176. _Compare __comp, parallel_tag __parallelism)
  177. {
  178. _GLIBCXX_CALL(__end - __begin)
  179. typedef std::iterator_traits<_RAIter> _TraitsType;
  180. typedef typename _TraitsType::value_type _ValueType;
  181. typedef typename _TraitsType::difference_type _DifferenceType;
  182. if (false) ;
  183. #if _GLIBCXX_MERGESORT
  184. else if (__stable || _Settings::get().sort_algorithm == MWMS)
  185. {
  186. if(_Settings::get().sort_splitting == EXACT)
  187. parallel_sort_mwms<__stable, true>
  188. (__begin, __end, __comp, __parallelism.__get_num_threads());
  189. else
  190. parallel_sort_mwms<false, false>
  191. (__begin, __end, __comp, __parallelism.__get_num_threads());
  192. }
  193. #endif
  194. #if _GLIBCXX_QUICKSORT
  195. else if (_Settings::get().sort_algorithm == QS)
  196. __parallel_sort_qs(__begin, __end, __comp,
  197. __parallelism.__get_num_threads());
  198. #endif
  199. #if _GLIBCXX_BAL_QUICKSORT
  200. else if (_Settings::get().sort_algorithm == QS_BALANCED)
  201. __parallel_sort_qsb(__begin, __end, __comp,
  202. __parallelism.__get_num_threads());
  203. #endif
  204. else
  205. __gnu_sequential::sort(__begin, __end, __comp);
  206. }
  207. } // end namespace __gnu_parallel
  208. #endif /* _GLIBCXX_PARALLEL_SORT_H */