-
Notifications
You must be signed in to change notification settings - Fork 2
/
Utils.hpp
106 lines (91 loc) · 2.58 KB
/
Utils.hpp
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
#pragma once
#include <tbb/tbb.h>
namespace Pvl {
struct Noncopyable {
Noncopyable() = default;
Noncopyable(const Noncopyable&) = delete;
Noncopyable(Noncopyable&&) = delete;
Noncopyable& operator=(const Noncopyable&) = delete;
Noncopyable& operator=(Noncopyable&&) = delete;
};
struct ParallelTag {};
struct SequentialTag {};
template <typename Tag>
struct ParallelFor;
template <>
struct ParallelFor<SequentialTag> {
template <typename Index, typename Func>
void operator()(Index n1, Index n2, const Func& func) {
for (Index n = n1; n < n2; ++n) {
func(n);
}
}
};
template <>
struct ParallelFor<ParallelTag> {
template <typename Index, typename Func>
void operator()(Index n1, Index n2, const Func& func) {
tbb::parallel_for(n1, n2, func);
}
};
template <typename Tag>
struct ParallelForEach;
template <>
struct ParallelForEach<SequentialTag> {
template <typename Iter, typename Func>
void operator()(Iter from, Iter to, const Func& func) {
for (Iter iter = from; iter != to; ++iter) {
func(*iter);
}
}
template <typename Range, typename Func>
void operator()(const Range& range, const Func& func) {
for (auto&& value : range) {
func(value);
}
}
};
template <>
struct ParallelForEach<ParallelTag> {
template <typename Iter, typename Func>
void operator()(Iter from, Iter to, const Func& func) {
tbb::parallel_for_each(from, to, func);
}
template <typename Range, typename Func>
void operator()(const Range& range, const Func& func) {
tbb::parallel_for_each(range, func);
}
};
template <typename Progress>
class ProgressMeter {
Progress func_;
tbb::atomic<int> counter_;
int target_;
int step_;
int next_;
tbb::tbb_thread::id callingThreadId_;
public:
ProgressMeter(int target, Progress&& func)
: func_(std::move(func))
, counter_(0) {
step_ = std::max(target / 100, 10);
next_ = step_;
target_ = target;
callingThreadId_ = tbb::this_tbb_thread::get_id();
}
bool inc() {
counter_++;
if (tbb::this_tbb_thread::get_id() == callingThreadId_ && counter_ > next_) {
float value = float(counter_) / target_ * 100;
next_ += step_;
return func_(value);
} else {
return false;
}
}
};
template <typename Progress>
ProgressMeter<Progress> makeProgressMeter(int target, Progress&& func) {
return ProgressMeter<Progress>(target, std::move(func));
}
} // namespace Pvl