STXXL  1.4.0
 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  *
9  * Distributed under the Boost Software License, Version 1.0.
10  * (See accompanying file LICENSE_1_0.txt or copy at
11  * http://www.boost.org/LICENSE_1_0.txt)
12  **************************************************************************/
13 
14 #ifndef STXXL_PARALLEL_HEADER
15 #define STXXL_PARALLEL_HEADER
16 
17 #include <stxxl/bits/config.h>
18 
19 #undef STXXL_PARALLEL
20 #undef STXXL_PARALLEL_MODE
21 
22 #if defined(_GLIBCXX_PARALLEL) || STXXL_PARALLEL_MODE_EXPLICIT
23 #define STXXL_PARALLEL_MODE
24 #endif
25 
26 #if defined(STXXL_PARALLEL_MODE)
27 #define STXXL_PARALLEL 1
28 #else
29 #define STXXL_PARALLEL 0
30 #endif
31 
32 #include <cassert>
33 
34 #ifdef STXXL_PARALLEL_MODE
35  #include <omp.h>
36 #endif
37 
38 #if STXXL_PARALLEL
39  #include <algorithm>
40 #endif
41 
42 #include <stxxl/bits/namespace.h>
44 #include <stxxl/bits/verbose.h>
45 
46 
47 #if defined(_GLIBCXX_PARALLEL)
48 //use _STXXL_FORCE_SEQUENTIAL to tag calls which are not worthwhile parallelizing
49 #define _STXXL_FORCE_SEQUENTIAL , __gnu_parallel::sequential_tag()
50 #else
51 #define _STXXL_FORCE_SEQUENTIAL
52 #endif
53 
54 #if 0
55 // sorting triggers is done sequentially
56 #define _STXXL_SORT_TRIGGER_FORCE_SEQUENTIAL _STXXL_FORCE_SEQUENTIAL
57 #else
58 // sorting triggers may be parallelized
59 #define _STXXL_SORT_TRIGGER_FORCE_SEQUENTIAL
60 #endif
61 
62 #if !STXXL_PARALLEL
63 #undef STXXL_PARALLEL_MULTIWAY_MERGE
64 #define STXXL_PARALLEL_MULTIWAY_MERGE 0
65 #endif
66 
67 #if defined(STXXL_PARALLEL_MODE) && ((__GNUC__ * 10000 + __GNUC_MINOR__ * 100) < 40400)
68 #undef STXXL_PARALLEL_MULTIWAY_MERGE
69 #define STXXL_PARALLEL_MULTIWAY_MERGE 0
70 #endif
71 
72 #if !defined(STXXL_PARALLEL_MULTIWAY_MERGE)
73 #define STXXL_PARALLEL_MULTIWAY_MERGE 1
74 #endif
75 
76 #if !defined(STXXL_NOT_CONSIDER_SORT_MEMORY_OVERHEAD)
77 #define STXXL_NOT_CONSIDER_SORT_MEMORY_OVERHEAD 0
78 #endif
79 
80 #if STXXL_PARALLEL_MODE_EXPLICIT
81 #include <parallel/algorithm>
82 #else
83 #include <algorithm>
84 #endif
85 
86 
88 
89 inline unsigned sort_memory_usage_factor()
90 {
91 #if STXXL_PARALLEL && !STXXL_NOT_CONSIDER_SORT_MEMORY_OVERHEAD && defined(STXXL_PARALLEL_MODE)
92  return (__gnu_parallel::_Settings::get().sort_algorithm == __gnu_parallel::MWMS && omp_get_max_threads() > 1) ? 2 : 1; //memory overhead for multiway mergesort
93 #else
94  return 1; //no overhead
95 #endif
96 }
97 
98 inline void check_sort_settings()
99 {
100 #if STXXL_PARALLEL && defined(STXXL_PARALLEL_MODE) && !defined(STXXL_NO_WARN_OMP_NESTED)
101  static bool did_warn = false;
102  if (!did_warn) {
103  if (__gnu_parallel::_Settings::get().sort_algorithm != __gnu_parallel::MWMS) {
104  if (omp_get_max_threads() <= 2) {
105  did_warn = true; // no problem with at most 2 threads, no need to check again
106  } else if (!omp_get_nested()) {
107  STXXL_ERRMSG("Inefficient settings detected. To get full potential from your CPU it is recommended to set OMP_NESTED=TRUE in the environment.");
108  did_warn = true;
109  }
110  }
111  }
112 #else
113  // nothing to check
114 #endif
115 }
116 
117 inline bool do_parallel_merge()
118 {
119 #if STXXL_PARALLEL_MULTIWAY_MERGE && defined(STXXL_PARALLEL_MODE)
120  return !stxxl::SETTINGS::native_merge && omp_get_max_threads() >= 1;
121 #else
122  return false;
123 #endif
124 }
125 
126 
127 namespace potentially_parallel {
128 
129 #if STXXL_PARALLEL_MODE_EXPLICIT
132 #else
133 using std::sort;
134 using std::random_shuffle;
135 #endif
136 
137 } // namespace potentially_parallel
138 
139 namespace parallel {
140 
141 #if STXXL_PARALLEL
142 
143 /*! Multi-way merging dispatcher.
144  * @param seqs_begin Begin iterator of iterator pair input sequence.
145  * @param seqs_end End iterator of iterator pair input sequence.
146  * @param target Begin iterator out output sequence.
147  * @param comp Comparator.
148  * @param length Maximum length to merge.
149  * @return End iterator of output sequence.
150  */
151 template <typename RandomAccessIteratorPairIterator,
152  typename RandomAccessIterator3, typename DiffType, typename Comparator>
153 RandomAccessIterator3
154 multiway_merge(RandomAccessIteratorPairIterator seqs_begin,
155  RandomAccessIteratorPairIterator seqs_end,
156  RandomAccessIterator3 target,
157  Comparator comp,
158  DiffType length)
159 {
160 #if defined(STXXL_PARALLEL_MODE) && ((__GNUC__ * 10000 + __GNUC_MINOR__ * 100) >= 40400)
161  return __gnu_parallel::multiway_merge(seqs_begin, seqs_end, target, length, comp);
162 #elif defined(STXXL_PARALLEL_MODE)
163  return __gnu_parallel::multiway_merge(seqs_begin, seqs_end, target, comp, length);
164 #else
165 #error "no implementation found for multiway_merge()"
166 #endif
167 }
168 
169 /*! Multi-way merging front-end.
170  * @param seqs_begin Begin iterator of iterator pair input sequence.
171  * @param seqs_end End iterator of iterator pair input sequence.
172  * @param target Begin iterator out output sequence.
173  * @param comp Comparator.
174  * @param length Maximum length to merge.
175  * @return End iterator of output sequence.
176  * @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.
177  */
178 template <typename RandomAccessIteratorPairIterator,
179  typename RandomAccessIterator3, typename DiffType, typename Comparator>
180 RandomAccessIterator3
181 multiway_merge_sentinel(RandomAccessIteratorPairIterator seqs_begin,
182  RandomAccessIteratorPairIterator seqs_end,
183  RandomAccessIterator3 target,
184  Comparator comp,
185  DiffType length)
186 {
187 #if defined(STXXL_PARALLEL_MODE) && ((__GNUC__ * 10000 + __GNUC_MINOR__ * 100) >= 40400)
188  return __gnu_parallel::multiway_merge_sentinels(seqs_begin, seqs_end, target, length, comp);
189 #elif defined(STXXL_PARALLEL_MODE)
190  return __gnu_parallel::multiway_merge_sentinels(seqs_begin, seqs_end, target, comp, length);
191 #else
192 #error "no implementation found for multiway_merge_sentinel()"
193 #endif
194 }
195 
196 #endif
197 
198 } // namespace parallel
199 
201 
202 #endif // !STXXL_PARALLEL_HEADER
203 // vim: et:ts=4:sw=4
unsigned sort_memory_usage_factor()
Definition: parallel.h:89
void random_shuffle(ExtIterator_ first, ExtIterator_ last, RandomNumberGenerator_ &rand, unsigned_type M, AllocStrategy_ AS=STXXL_DEFAULT_ALLOC_STRATEGY())
External equivalent of std::random_shuffle.
void sort(ExtIterator first, ExtIterator last, StrictWeakOrdering cmp, unsigned_type M)
Sort records comparison-based, see stxxl::sort -- Sorting Comparison-Based.
Definition: sort.h:673
void check_sort_settings()
Definition: parallel.h:98
#define STXXL_BEGIN_NAMESPACE
Definition: namespace.h:16
Provides a static class to store runtime tuning parameters.
#define STXXL_ERRMSG(x)
Definition: verbose.h:79
bool do_parallel_merge()
Definition: parallel.h:117
#define STXXL_END_NAMESPACE
Definition: namespace.h:17
static bool native_merge
Definition: settings.h:30