forked from taskflow/taskflow
-
Notifications
You must be signed in to change notification settings - Fork 0
/
reduce.cpp
113 lines (93 loc) · 2.98 KB
/
reduce.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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// This example demonstrates how to use 'reduce' method.
#include <taskflow/taskflow.hpp>
#include <chrono>
#include <limits.h>
struct Data {
int a {::rand()};
int b {::rand()};
int transform() const {
return a*a + 2*a*b + b*b;
}
};
// Procedure: reduce
// This procedure demonstrates
void reduce() {
std::cout << "Benchmark: reduce" << std::endl;
std::vector<int> data;
for(int i=0; i<40000000; ++i) {
data.push_back(::rand());
}
// sequential method
auto sbeg = std::chrono::steady_clock::now();
auto smin = std::numeric_limits<int>::max();
for(auto& d : data) {
smin = std::min(smin, d);
}
auto send = std::chrono::steady_clock::now();
std::cout << "[sequential] reduce: "
<< std::chrono::duration_cast<std::chrono::milliseconds>(send - sbeg).count()
<< " ms\n";
// taskflow
auto tbeg = std::chrono::steady_clock::now();
tf::Taskflow tf;
auto tmin = std::numeric_limits<int>::max();
tf.reduce(data.begin(), data.end(), tmin, [] (const auto& l, const auto& r) {
return std::min(l, r);
});
tf::Executor().run(tf).get();
auto tend = std::chrono::steady_clock::now();
std::cout << "[taskflow] reduce: "
<< std::chrono::duration_cast<std::chrono::milliseconds>(tend - tbeg).count()
<< " ms\n";
// assertion
assert(tmin == smin);
}
// Procedure: transform_reduce
void transform_reduce() {
std::cout << "Benchmark: transform_reduce" << std::endl;
std::vector<Data> data(40000000);
// sequential method
auto sbeg = std::chrono::steady_clock::now();
auto smin = std::numeric_limits<int>::max();
for(auto& d : data) {
smin = std::min(smin, d.transform());
}
auto send = std::chrono::steady_clock::now();
std::cout << "[sequential] transform_reduce "
<< std::chrono::duration_cast<std::chrono::milliseconds>(send - sbeg).count()
<< " ms\n";
// taskflow
auto tbeg = std::chrono::steady_clock::now();
tf::Taskflow tf;
auto tmin = std::numeric_limits<int>::max();
tf.transform_reduce(data.begin(), data.end(), tmin,
[] (int l, int r) { return std::min(l, r); },
[] (const Data& d) { return d.transform(); }
);
tf::Executor().run(tf).get();
auto tend = std::chrono::steady_clock::now();
std::cout << "[taskflow] transform_reduce "
<< std::chrono::duration_cast<std::chrono::milliseconds>(tend - tbeg).count()
<< " ms\n";
// assertion
assert(tmin == smin);
}
// ------------------------------------------------------------------------------------------------
// Function: main
int main(int argc, char* argv[]) {
if(argc != 2) {
std::cerr << "usage: ./reduce [reduce|transform_reduce]" << std::endl;
std::exit(EXIT_FAILURE);
}
if(std::string_view method(argv[1]); method == "reduce") {
reduce();
}
else if(method == "transform_reduce") {
transform_reduce();
}
else {
std::cerr << "invalid method " << method.data() << std::endl;
std::exit(EXIT_FAILURE);
}
return 0;
}