libstdc++: multiway_mergesort.h Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32#ifndef _GLIBCXX_PARALLEL_MULTIWAY_MERGESORT_H
33#define _GLIBCXX_PARALLEL_MULTIWAY_MERGESORT_H 1
34
36
41
43{
44
45 template<typename _DifferenceTp>
47 {
48 typedef _DifferenceTp _DifferenceType;
49
50
52
53
55 };
56
57
58
59
60 template<typename _RAIter>
62 {
64 typedef typename _TraitsType::value_type _ValueType;
65 typedef typename _TraitsType::difference_type _DifferenceType;
66
67
69
70
72
73
75
76
78
79
81
82
84
85
87 };
88
89
90
91
92
93
94
95 template<typename _RAIter, typename _DifferenceTp>
96 void
98 _DifferenceTp __num_samples)
99 {
101 typedef typename _TraitsType::value_type _ValueType;
102 typedef _DifferenceTp _DifferenceType;
103
105
106 _DifferenceType* __es = new _DifferenceType[__num_samples + 2];
107
109 __num_samples + 1, __es);
110
111 for (_DifferenceType __i = 0; __i < __num_samples; ++__i)
112 ::new(&(__sd->_M_samples[__iam * __num_samples + __i]))
114 + __es[__i + 1]]);
115
116 delete[] __es;
117 }
118
119
120 template<bool __exact, typename _RAIter,
121 typename _Compare, typename _SortingPlacesIterator>
123 { };
124
125
126 template<typename _RAIter, typename _Compare,
127 typename _SortingPlacesIterator>
129 {
130 void
133 _Compare& __comp,
134 const typename
136 __num_samples) const
137 {
138# pragma omp barrier
139
141 _SortingPlacesIterator> >
144 __seqs[__s] = std::make_pair(__sd->_M_temporary[__s],
148
150
151
152 if (__iam < __sd->_M_num_threads - 1)
155 __comp);
156
158 {
159
161 __sd->_M_pieces[__iam][__seq]._M_end
162 = __offsets[__seq] - __seqs[__seq].first;
163 else
164
165 __sd->_M_pieces[__iam][__seq]._M_end =
167 }
168
169# pragma omp barrier
170
172 {
173
174 if (__iam > 0)
175 __sd->_M_pieces[__iam][__seq]._M_begin =
176 __sd->_M_pieces[__iam - 1][__seq]._M_end;
177 else
178
179 __sd->_M_pieces[__iam][__seq]._M_begin = 0;
180 }
181 }
182 };
183
184
185 template<typename _RAIter, typename _Compare,
186 typename _SortingPlacesIterator>
188 {
189 void
192 _Compare& __comp,
193 const typename
195 __num_samples) const
196 {
198 typedef typename _TraitsType::value_type _ValueType;
199 typedef typename _TraitsType::difference_type _DifferenceType;
200
202
203# pragma omp barrier
204
205# pragma omp single
206 __gnu_sequential::sort(__sd->_M_samples,
209 __comp);
210
211# pragma omp barrier
212
214 {
215
216 if (__num_samples * __iam > 0)
217 __sd->_M_pieces[__iam][__s]._M_begin =
222 __sd->_M_samples[__num_samples * __iam],
223 __comp)
225 else
226
227 __sd->_M_pieces[__iam][__s]._M_begin = 0;
228
229 if ((__num_samples * (__iam + 1)) <
231 __sd->_M_pieces[__iam][__s]._M_end =
236 __sd->_M_samples[__num_samples * (__iam + 1)],
237 __comp)
239 else
240
243 }
244 }
245 };
246
247 template<bool __stable, typename _RAIter, typename _Compare>
248 struct __possibly_stable_sort
249 { };
250
251 template<typename _RAIter, typename _Compare>
252 struct __possibly_stable_sort<true, _RAIter, _Compare>
253 {
254 void operator()(const _RAIter& __begin,
255 const _RAIter& __end, _Compare& __comp) const
256 { __gnu_sequential::stable_sort(__begin, __end, __comp); }
257 };
258
259 template<typename _RAIter, typename _Compare>
260 struct __possibly_stable_sort<false, _RAIter, _Compare>
261 {
262 void operator()(const _RAIter __begin,
263 const _RAIter __end, _Compare& __comp) const
264 { __gnu_sequential::sort(__begin, __end, __comp); }
265 };
266
267 template<bool __stable, typename _Seq_RAIter,
268 typename _RAIter, typename _Compare,
269 typename _DiffType>
270 struct __possibly_stable_multiway_merge
271 { };
272
273 template<typename _Seq_RAIter, typename _RAIter,
274 typename _Compare, typename _DiffType>
275 struct __possibly_stable_multiway_merge<true, _Seq_RAIter,
276 _RAIter, _Compare, _DiffType>
277 {
278 void operator()(const _Seq_RAIter& __seqs_begin,
279 const _Seq_RAIter& __seqs_end,
280 const _RAIter& __target,
281 _Compare& __comp,
282 _DiffType __length_am) const
283 { stable_multiway_merge(__seqs_begin, __seqs_end, __target,
284 __length_am, __comp, sequential_tag()); }
285 };
286
287 template<typename _Seq_RAIter, typename _RAIter,
288 typename _Compare, typename _DiffType>
289 struct __possibly_stable_multiway_merge<false, _Seq_RAIter,
290 _RAIter, _Compare, _DiffType>
291 {
292 void operator()(const _Seq_RAIter& __seqs_begin,
293 const _Seq_RAIter& __seqs_end,
294 const _RAIter& __target,
295 _Compare& __comp,
296 _DiffType __length_am) const
297 { multiway_merge(__seqs_begin, __seqs_end, __target, __length_am,
298 __comp, sequential_tag()); }
299 };
300
301
302
303
304
305 template<bool __stable, bool __exact, typename _RAIter,
306 typename _Compare>
307 void
309 _Compare& __comp)
310 {
312 typedef typename _TraitsType::value_type _ValueType;
313 typedef typename _TraitsType::difference_type _DifferenceType;
314
316
317
318 _DifferenceType __length_local =
320
321
322
323 typedef _ValueType* _SortingPlacesIterator;
324
326 static_cast<_ValueType*>(::operator new(sizeof(_ValueType)
327 * (__length_local + 1)));
328
329
332 + __length_local,
334
335 __possibly_stable_sort<__stable, _SortingPlacesIterator, _Compare>()
338 __comp);
339
340
341
342
343
344
345 _DifferenceType __num_samples =
348 (__iam, __sd, __comp, __num_samples);
349
350
351 _DifferenceType __offset = 0, __length_am = 0;
353 {
354 __length_am += (__sd->_M_pieces[__iam][__s]._M_end
355 - __sd->_M_pieces[__iam][__s]._M_begin);
356 __offset += __sd->_M_pieces[__iam][__s]._M_begin;
357 }
358
361 _SeqVector;
363
365 {
366 __seqs[__s] =
368 + __sd->_M_pieces[__iam][__s]._M_begin,
370 + __sd->_M_pieces[__iam][__s]._M_end);
371 }
372
373 __possibly_stable_multiway_merge<
374 __stable, typename _SeqVector::iterator,
375 _RAIter, _Compare, _DifferenceType>()(__seqs.begin(), __seqs.end(),
376 __sd->_M_source + __offset, __comp,
377 __length_am);
378
379# pragma omp barrier
380
381 for (_DifferenceType __i = 0; __i < __length_local; ++__i)
382 __sd->_M_temporary[__iam][__i].~_ValueType();
383 ::operator delete(__sd->_M_temporary[__iam]);
384 }
385
386
387
388
389
390
391
392 template<bool __stable, bool __exact, typename _RAIter,
393 typename _Compare>
394 void
396 _Compare __comp,
398 {
400
402 typedef typename _TraitsType::value_type _ValueType;
403 typedef typename _TraitsType::difference_type _DifferenceType;
404
405 _DifferenceType __n = __end - __begin;
406
407 if (__n <= 1)
408 return;
409
410
411 if (__num_threads > __n)
412 __num_threads = static_cast<_ThreadIndex>(__n);
413
414
416 _DifferenceType* __starts;
417 _DifferenceType __size;
418
419# pragma omp parallel num_threads(__num_threads)
420 {
421 __num_threads = omp_get_num_threads();
422
423# pragma omp single
424 {
427
428 __sd._M_temporary = new _ValueType*[__num_threads];
429
430 if (!__exact)
431 {
432 __size =
434 * __num_threads;
435 __sd._M_samples = static_cast<_ValueType*>
436 (::operator new(__size * sizeof(_ValueType)));
437 }
438 else
440
441 __sd._M_offsets = new _DifferenceType[__num_threads - 1];
444 for (_ThreadIndex __s = 0; __s < __num_threads; ++__s)
445 __sd._M_pieces[__s].resize(__num_threads);
446 __starts = __sd._M_starts = new _DifferenceType[__num_threads + 1];
447
448 _DifferenceType __chunk_length = __n / __num_threads;
449 _DifferenceType __split = __n % __num_threads;
450 _DifferenceType __pos = 0;
451 for (_ThreadIndex __i = 0; __i < __num_threads; ++__i)
452 {
453 __starts[__i] = __pos;
454 __pos += ((__i < __split)
455 ? (__chunk_length + 1) : __chunk_length);
456 }
457 __starts[__num_threads] = __pos;
458 }
459
460
461 parallel_sort_mwms_pu<__stable, __exact>(&__sd, __comp);
462 }
463
464 delete[] __starts;
466
467 if (!__exact)
468 {
469 for (_DifferenceType __i = 0; __i < __size; ++__i)
472 }
473
476 }
477
478}
479
480#endif
Includes the original header files concerned with iterators except for stream iterators....
#define _GLIBCXX_CALL(__n)
Macro to produce log message when entering a function.
Implementation of sequential and parallel multiway merge.
End-user include file. Provides advanced settings and tuning options. This file is a GNU parallel ext...
_ForwardIterator uninitialized_copy(_InputIterator __first, _InputIterator __last, _ForwardIterator __result)
Copies the range [first,last) into result.
GNU parallel code for public use.
uint16_t _ThreadIndex
Unsigned integer to index a thread number. The maximum thread number (for each processor) must fit in...
_RAIterOut multiway_merge(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, __gnu_parallel::sequential_tag)
Multiway Merge Frontend.
void __determine_samples(_PMWMSSortingData< _RAIter > *__sd, _DifferenceTp __num_samples)
Select _M_samples from a sequence.
void parallel_sort_mwms_pu(_PMWMSSortingData< _RAIter > *__sd, _Compare &__comp)
PMWMS code executed by each thread.
_OutputIterator __equally_split(_DifferenceType __n, _ThreadIndex __num_threads, _OutputIterator __s)
function to split a sequence into parts of almost equal size.
void multiseq_partition(_RanSeqs __begin_seqs, _RanSeqs __end_seqs, _RankType __rank, _RankIterator __begin_offsets, _Compare __comp=std::less< typename std::iterator_traits< typename std::iterator_traits< _RanSeqs >::value_type::first_type >::value_type >())
Splits several sorted sequences at a certain global __rank, resulting in a splitting point for each s...
void parallel_sort_mwms(_RAIter __begin, _RAIter __end, _Compare __comp, _ThreadIndex __num_threads)
PMWMS main call.
Traits class for iterators.
Struct holding two objects of arbitrary type.
A standard container which offers fixed time access to individual elements in any order.
constexpr iterator begin() noexcept
_DifferenceType _M_begin
Begin of subsequence.
_DifferenceType _M_end
End of subsequence.
Data accessed by all threads.
_DifferenceType * _M_offsets
Offsets to add to the found positions.
_ValueType * _M_samples
Samples.
_RAIter _M_source
Input __begin.
_DifferenceType * _M_starts
Start indices, per thread.
std::vector< _Piece< _DifferenceType > > * _M_pieces
Pieces of data to merge [thread][__sequence].
_ThreadIndex _M_num_threads
Number of threads involved.
_ValueType ** _M_temporary
Storage in which to sort.
unsigned int sort_mwms_oversampling
Oversampling factor for parallel std::sort (MWMS).
static const _Settings & get()
Get the global settings.