STXXL  1.4-dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
parallel.h
Go to the documentation of this file.
1 /***************************************************************************
2  * include/stxxl/bits/parallel.h
3  *
4  * Part of the STXXL. See http://stxxl.sourceforge.net
5  *
6  * Copyright (C) 2008-2010 Andreas Beckmann <[email protected]>
7  * Copyright (C) 2011 Johannes Singler <[email protected]>
8  * Copyright (C) 2015 Timo Bingmann <[email protected]>
9  *
10  * Distributed under the Boost Software License, Version 1.0.
11  * (See accompanying file LICENSE_1_0.txt or copy at
12  * http://www.boost.org/LICENSE_1_0.txt)
13  **************************************************************************/
14 
15 #ifndef STXXL_PARALLEL_HEADER
16 #define STXXL_PARALLEL_HEADER
17 
18 #include <stxxl/bits/config.h>
19 
20 #include <cassert>
21 
22 #if STXXL_PARALLEL
23  #include <omp.h>
24 #endif
25 
26 #include <stxxl/bits/namespace.h>
28 #include <stxxl/bits/verbose.h>
29 
30 #if defined(_GLIBCXX_PARALLEL)
31 //use _STXXL_FORCE_SEQUENTIAL to tag calls which are not worthwhile parallelizing
32 #define _STXXL_FORCE_SEQUENTIAL , __gnu_parallel::sequential_tag()
33 #else
34 #define _STXXL_FORCE_SEQUENTIAL
35 #endif
36 
37 #if 0
38 // sorting triggers is done sequentially
39 #define _STXXL_SORT_TRIGGER_FORCE_SEQUENTIAL _STXXL_FORCE_SEQUENTIAL
40 #else
41 // sorting triggers may be parallelized
42 #define _STXXL_SORT_TRIGGER_FORCE_SEQUENTIAL
43 #endif
44 
45 #if !STXXL_PARALLEL
46 #undef STXXL_PARALLEL_MULTIWAY_MERGE
47 #define STXXL_PARALLEL_MULTIWAY_MERGE 0
48 #endif
49 
50 #if defined(STXXL_PARALLEL_MODE) && ((__GNUC__ * 10000 + __GNUC_MINOR__ * 100) < 40400)
51 #undef STXXL_PARALLEL_MULTIWAY_MERGE
52 #define STXXL_PARALLEL_MULTIWAY_MERGE 0
53 #endif
54 
55 #if !defined(STXXL_PARALLEL_MULTIWAY_MERGE)
56 #define STXXL_PARALLEL_MULTIWAY_MERGE 1
57 #endif
58 
59 #if !defined(STXXL_NOT_CONSIDER_SORT_MEMORY_OVERHEAD)
60 #define STXXL_NOT_CONSIDER_SORT_MEMORY_OVERHEAD 0
61 #endif
62 
63 #if STXXL_WITH_GNU_PARALLEL
64 #include <parallel/algorithm>
65 #else
66 #include <algorithm>
67 #endif
68 
70 
72 
73 inline unsigned sort_memory_usage_factor()
74 {
75 #if STXXL_PARALLEL && !STXXL_NOT_CONSIDER_SORT_MEMORY_OVERHEAD && defined(STXXL_PARALLEL_MODE)
76  return (__gnu_parallel::_Settings::get().sort_algorithm == __gnu_parallel::MWMS && omp_get_max_threads() > 1) ? 2 : 1; //memory overhead for multiway mergesort
77 #else
78  return 1; //no overhead
79 #endif
80 }
81 
82 inline void check_sort_settings()
83 {
84 #if STXXL_PARALLEL && defined(STXXL_PARALLEL_MODE) && !defined(STXXL_NO_WARN_OMP_NESTED)
85  static bool did_warn = false;
86  if (!did_warn) {
87  if (__gnu_parallel::_Settings::get().sort_algorithm != __gnu_parallel::MWMS) {
88  if (omp_get_max_threads() <= 2) {
89  did_warn = true; // no problem with at most 2 threads, no need to check again
90  }
91  else if (!omp_get_nested()) {
92  STXXL_ERRMSG("Inefficient settings detected. To get full potential from your CPU it is recommended to set OMP_NESTED=TRUE in the environment.");
93  did_warn = true;
94  }
95  }
96  }
97 #else
98  // nothing to check
99 #endif
100 }
101 
102 inline bool do_parallel_merge()
103 {
104 #if STXXL_PARALLEL_MULTIWAY_MERGE && defined(STXXL_PARALLEL_MODE)
105  return !stxxl::SETTINGS::native_merge && omp_get_max_threads() >= 1;
106 #else
107  return false;
108 #endif
109 }
110 
111 //! this namespace provides parallel or sequential algorithms depending on the
112 //! compilation settings. it should be used by all components, where
113 //! parallelism is optional.
114 namespace potentially_parallel {
115 
116 #if STXXL_WITH_GNU_PARALLEL
117 
120 
121 #elif STXXL_PARALLEL
122 
123 using std::sort;
124 using std::random_shuffle;
125 
126 #else
127 
128 using std::sort;
129 using std::random_shuffle;
130 
131 #endif
132 
133 /*! Multi-way merging dispatcher.
134  * \param seqs_begin Begin iterator of iterator pair input sequence.
135  * \param seqs_end End iterator of iterator pair input sequence.
136  * \param target Begin iterator out output sequence.
137  * \param comp Comparator.
138  * \param length Maximum length to merge.
139  * \return End iterator of output sequence.
140  */
141 template <typename RandomAccessIteratorPairIterator,
142  typename RandomAccessIterator3, typename DiffType, typename Comparator>
143 RandomAccessIterator3
144 multiway_merge(RandomAccessIteratorPairIterator seqs_begin,
145  RandomAccessIteratorPairIterator seqs_end,
146  RandomAccessIterator3 target, DiffType length,
147  Comparator comp)
148 {
149 #if STXXL_PARALLEL
151  seqs_begin, seqs_end, target, length, comp);
152 #else
153  return stxxl::parallel::sequential_multiway_merge<false, false>(
154  seqs_begin, seqs_end, target, length, comp);
155 #endif
156 }
157 
158 /*! Multi-way merging dispatcher.
159  * \param seqs_begin Begin iterator of iterator pair input sequence.
160  * \param seqs_end End iterator of iterator pair input sequence.
161  * \param target Begin iterator out output sequence.
162  * \param comp Comparator.
163  * \param length Maximum length to merge.
164  * \return End iterator of output sequence.
165  */
166 template <typename RandomAccessIteratorPairIterator,
167  typename RandomAccessIterator3, typename DiffType, typename Comparator>
168 RandomAccessIterator3
169 multiway_merge_stable(RandomAccessIteratorPairIterator seqs_begin,
170  RandomAccessIteratorPairIterator seqs_end,
171  RandomAccessIterator3 target, DiffType length,
172  Comparator comp)
173 {
174 #if STXXL_PARALLEL
176  seqs_begin, seqs_end, target, length, comp);
177 #else
178  return stxxl::parallel::sequential_multiway_merge<true, false>(
179  seqs_begin, seqs_end, target, length, comp);
180 #endif
181 }
182 
183 /*! Multi-way merging front-end.
184  * \param seqs_begin Begin iterator of iterator pair input sequence.
185  * \param seqs_end End iterator of iterator pair input sequence.
186  * \param target Begin iterator out output sequence.
187  * \param comp Comparator.
188  * \param length Maximum length to merge.
189  * \return End iterator of output sequence.
190  * \pre For each \c i, \c seqs_begin[i].second must be the end marker of the sequence, but also reference the one more sentinel element.
191  */
192 template <typename RandomAccessIteratorPairIterator,
193  typename RandomAccessIterator3, typename DiffType, typename Comparator>
194 RandomAccessIterator3
195 multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin,
196  RandomAccessIteratorPairIterator seqs_end,
197  RandomAccessIterator3 target, DiffType length,
198  Comparator comp)
199 {
200 #if STXXL_PARALLEL
202  seqs_begin, seqs_end, target, length, comp);
203 #else
204  return stxxl::parallel::sequential_multiway_merge<false, true>(
205  seqs_begin, seqs_end, target, length, comp);
206 #endif
207 }
208 
209 /*! Multi-way merging front-end.
210  * \param seqs_begin Begin iterator of iterator pair input sequence.
211  * \param seqs_end End iterator of iterator pair input sequence.
212  * \param target Begin iterator out output sequence.
213  * \param comp Comparator.
214  * \param length Maximum length to merge.
215  * \return End iterator of output sequence.
216  * \pre For each \c i, \c seqs_begin[i].second must be the end marker of the sequence, but also reference the one more sentinel element.
217  */
218 template <typename RandomAccessIteratorPairIterator,
219  typename RandomAccessIterator3, typename DiffType, typename Comparator>
220 RandomAccessIterator3
221 multiway_merge_stable_sentinels(RandomAccessIteratorPairIterator seqs_begin,
222  RandomAccessIteratorPairIterator seqs_end,
223  RandomAccessIterator3 target, DiffType length,
224  Comparator comp)
225 {
226 #if STXXL_PARALLEL
228  seqs_begin, seqs_end, target, length, comp);
229 #else
230  return stxxl::parallel::sequential_multiway_merge<true, true>(
231  seqs_begin, seqs_end, target, length, comp);
232 #endif
233 }
234 
235 } // namespace potentially_parallel
236 
238 
239 #endif // !STXXL_PARALLEL_HEADER
240 // vim: et:ts=4:sw=4
RandomAccessIterator3 multiway_merge_stable_sentinels(RandomAccessIteratorPairIterator seqs_begin, RandomAccessIteratorPairIterator seqs_end, RandomAccessIterator3 target, DiffType length, Comparator comp)
Multi-way merging front-end.
Definition: parallel.h:221
unsigned sort_memory_usage_factor()
Definition: parallel.h:73
void sort(ExtIterator first, ExtIterator last, StrictWeakOrdering cmp, unsigned_type M)
Sort records comparison-based, see stxxl::sort -- Sorting Comparison-Based.
Definition: sort.h:676
RandomAccessIterator3 multiway_merge(RandomAccessIteratorPairIterator seqs_begin, RandomAccessIteratorPairIterator seqs_end, RandomAccessIterator3 target, DiffType length, Comparator comp)
Multi-way merging dispatcher.
Definition: parallel.h:144
void check_sort_settings()
Definition: parallel.h:82
static bool native_merge
Definition: settings.h:29
RandomAccessIterator3 multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin, RandomAccessIteratorPairIterator seqs_end, RandomAccessIterator3 target, DiffType length, Comparator comp)
Multi-way merging front-end.
Definition: parallel.h:195
void random_shuffle(ExtIterator first, ExtIterator last, RandomNumberGenerator &rand, unsigned_type M, AllocStrategy AS=STXXL_DEFAULT_ALLOC_STRATEGY())
External equivalent of std::random_shuffle.
RandomAccessIterator3 multiway_merge_stable(RandomAccessIteratorPairIterator seqs_begin, RandomAccessIteratorPairIterator seqs_end, RandomAccessIterator3 target, DiffType length, Comparator comp)
Multi-way merging dispatcher.
Definition: parallel.h:169
#define STXXL_BEGIN_NAMESPACE
Definition: namespace.h:16
Provides a static class to store runtime tuning parameters.
#define STXXL_ERRMSG(x)
Definition: verbose.h:94
bool do_parallel_merge()
Definition: parallel.h:102
#define STXXL_END_NAMESPACE
Definition: namespace.h:17