Skip to content

Commit 5bd5c21

Browse files
updated example/threadpool.cpp
1 parent b94414c commit 5bd5c21

2 files changed

Lines changed: 192 additions & 131 deletions

File tree

example/threadpool.cpp

Lines changed: 100 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -8,79 +8,135 @@
88
#include <chrono>
99
#include <random>
1010

11-
// Procedure: benchmark_empty_jobs
12-
void benchmark_empty_jobs() {
11+
const int thread_num = 4;
12+
const int task_num = 16;
1313

14-
std::cout << "Benchmarking threadpool throughput on empty jobs ...\n";
14+
// ----------------------------------------------------------------------------
1515

16-
unsigned thread_num = 4;
17-
unsigned int task_num = 10000000;
16+
// Procedure: linear_insertions
17+
template <typename T>
18+
auto linear_insertions() {
19+
20+
auto beg = std::chrono::high_resolution_clock::now();
1821

19-
auto start = std::chrono::high_resolution_clock::now();
22+
T threadpool(thread_num);
2023

21-
tf::ProactiveThreadpool proactive(thread_num);
22-
for(size_t i=0; i<task_num; i++){
23-
proactive.silent_async([](){});
24+
std::atomic<size_t> sum {0};
25+
26+
std::function<void(int)> insert;
27+
std::promise<void> promise;
28+
auto future = promise.get_future();
29+
30+
insert = [&threadpool, &insert, &sum, &promise] (int i) {
31+
if(i > 0) {
32+
threadpool.silent_async([i=i-1, &insert] () {
33+
insert(i);
34+
});
35+
}
36+
else {
37+
if(++sum; sum == thread_num) {
38+
promise.set_value();
39+
}
40+
}
41+
};
42+
43+
for(size_t i=0; i<thread_num; i++){
44+
insert(task_num / thread_num);
2445
}
25-
proactive.shutdown();
46+
47+
// synchronize until all tasks finish
48+
threadpool.shutdown();
49+
50+
//future.get();
51+
//assert(sum == thread_num);
2652

2753
auto end = std::chrono::high_resolution_clock::now();
28-
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
29-
std::cout << "ProactiveThreadpool elapsed time: " << elapsed.count() << " ms\n";
3054

31-
start = std::chrono::high_resolution_clock::now();
55+
return std::chrono::duration_cast<std::chrono::milliseconds>(end - beg).count();
56+
}
57+
58+
// Procedure: benchmark_linear_insertions
59+
void benchmark_linear_insertions() {
60+
61+
std::cout << "==== Linear Insertions ====\n";
62+
63+
//std::cout << "Proactive threadpool takes: "
64+
// << linear_insertions<tf::ProactiveThreadpool>() << " ms\n";
65+
66+
std::cout << "Simple threadpool takes: "
67+
<< linear_insertions<tf::SimpleThreadpool>() << " ms\n";
68+
}
69+
70+
// ----------------------------------------------------------------------------
71+
72+
// Function: empty_jobs
73+
template <typename T>
74+
auto empty_jobs() {
75+
76+
auto beg = std::chrono::high_resolution_clock::now();
77+
78+
T threadpool(thread_num);
3279

33-
tf::SimpleThreadpool simple(thread_num);
3480
for(size_t i=0; i<task_num; i++){
35-
simple.silent_async([](){});
81+
threadpool.silent_async([](){});
3682
}
37-
simple.shutdown();
83+
84+
threadpool.shutdown();
3885

39-
end = std::chrono::high_resolution_clock::now();
40-
elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
41-
std::cout << "SimpleThreadpool elapsed time: " << elapsed.count() << " ms\n";
86+
auto end = std::chrono::high_resolution_clock::now();
87+
88+
return std::chrono::duration_cast<std::chrono::milliseconds>(end - beg).count();
4289
}
4390

44-
// Procedure: benchmark_atomic_add
45-
void benchmark_atomic_add() {
91+
// Procedure: benchmark_empty_jobs
92+
void benchmark_empty_jobs() {
93+
std::cout << "==== Empty Jobs ====\n";
4694

47-
std::cout << "Benchmarking threadpool throughput on atomic add ...\n";
48-
49-
unsigned thread_num = 4;
50-
unsigned int task_num = 10000000;
95+
std::cout << "Proactive threadpool takes: "
96+
<< empty_jobs<tf::ProactiveThreadpool>() << " ms\n";
97+
98+
std::cout << "Simple threadpool takes: "
99+
<< empty_jobs<tf::SimpleThreadpool>() << " ms\n";
100+
}
101+
102+
// ----------------------------------------------------------------------------
103+
104+
// Function: atomic_add
105+
template <typename T>
106+
auto atomic_add() {
51107

52108
std::atomic<int> counter(0);
53-
auto start = std::chrono::high_resolution_clock::now();
109+
auto beg = std::chrono::high_resolution_clock::now();
54110

55-
tf::ProactiveThreadpool proactive(thread_num);
111+
T threadpool(thread_num);
56112
for(size_t i=0; i<task_num; i++){
57-
proactive.silent_async([&counter](){ counter++; });
113+
threadpool.silent_async([&counter](){ counter++; });
58114
}
59-
proactive.shutdown();
115+
threadpool.shutdown();
116+
117+
assert(counter == task_num);
60118

61119
auto end = std::chrono::high_resolution_clock::now();
62-
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
63-
std::cout << "ProactiveThreadpool elapsed time: " << elapsed.count() << " ms\n";
120+
return std::chrono::duration_cast<std::chrono::milliseconds>(end - beg).count();
121+
}
64122

65-
counter = 0;
66-
start = std::chrono::high_resolution_clock::now();
67-
tf::SimpleThreadpool simple(thread_num);
123+
// Procedure: benchmark_atomic_add
124+
void benchmark_atomic_add() {
125+
std::cout << "==== Atomic Add ====\n";
68126

69-
for(size_t i=0; i<task_num; i++){
70-
simple.silent_async([&counter](){ counter++; });
71-
}
72-
simple.shutdown();
73-
74-
end = std::chrono::high_resolution_clock::now();
75-
elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
76-
std::cout << "SimpleThreadpool elapsed time: " << elapsed.count() << " ms\n";
127+
std::cout << "Proactive threadpool takes: "
128+
<< atomic_add<tf::ProactiveThreadpool>() << " ms\n";
129+
130+
std::cout << "Simple threadpool takes: "
131+
<< atomic_add<tf::SimpleThreadpool>() << " ms\n";
77132
}
78133

79134
// Function: main
80135
int main(int argc, char* argv[]) {
81136

82-
benchmark_empty_jobs();
83-
benchmark_atomic_add();
137+
benchmark_linear_insertions();
138+
//benchmark_empty_jobs();
139+
//benchmark_atomic_add();
84140

85141
return 0;
86142
}

0 commit comments

Comments
 (0)