-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathParallelSort.cpp
90 lines (60 loc) · 1.75 KB
/
ParallelSort.cpp
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include <iostream>
#include <vector>
#include <cmath>
#include <limits>
#include <queue>
#include <thread>
#include <functional>
#include <algorithm>
// convert gcc to c0xx
#define thread_local __thread;
typedef std::thread Thread;
typedef std::vector<std::thread> ThreadGroup;
typedef std::mutex Mutex;
// typedef std::lock_guard<std::mutex> Lock;
typedef std::unique_lock<std::mutex> Lock;
typedef std::condition_variable Condition;
#include "future.h"
template<typename F>
std::unique_future<typename std::result_of<F()>::type> spawn_task(F f) {
typedef typename std::result_of<F()>::type result_type;
std::packaged_task<result_type()> task(std::move(f));
std::unique_future<result_type> res(task.get_future());
std::thread t(std::move(task));
t.detach();
return res;
}
size_t SORT_THRESHOLD = 100000;
/* re-entrant function
* Mattson el al. 5.29 page 170
*/
template<typename Iter, typename Compare>
void parallel_sort(Iter b, Iter e, Compare c) {
size_t n = std::distance(b,e);
// final exit
if (n< SORT_THRESHOLD) return std::sort(b,e,c);
// Divide
Iter pivot = b +n/2;
// Conquer
// fork first half
//Thread forked(parallel_sort<Iter,Compare>,b,pivot,c);
auto res = spawn_task(std::bind(parallel_sort<Iter,Compare>,b,pivot,c));
// serial version
// parallel_sort(b, e,c);
// process locally second half
parallel_sort(pivot,e,c);
// wait for the other half
// forked.join();
res.wait();
// merge...
std::inplace_merge(b,pivot,e);
}
int main() {
size_t SIZE = 10000000;
std::vector<int> v(SIZE);
std::generate(v.begin(),v.end(),std::rand);
parallel_sort(v.begin(),v.end(), std::less<int>());
for (int i=1; i<SIZE; ++i)
if (v[i]<v[i-1]) std::cout << "error at " << i << std::endl;
return 0;
}