-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbenchmark.cpp
More file actions
124 lines (94 loc) · 3.13 KB
/
benchmark.cpp
File metadata and controls
124 lines (94 loc) · 3.13 KB
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
114
115
116
117
118
119
120
121
122
123
124
//
// Created by admin on 2022/4/7.
//
#include "ThreadPool.h"
#include <assert.h>
#include <atomic>
#include <future>
#include <chrono>
// benchmark
using namespace std;
using LL = long long;
// M: 单生产者生产个数
constexpr int N = 1e8, M = 50;
atomic<int> finish(0);
// 消费者和生产者个数
constexpr int workers = 8, producers = 8;
constexpr int ALL = M * producers;
vector<future<LL>> futu[producers];
vector<promise<LL>> prom[producers];
vector<LL> resultThreadPool[producers];
vector<future<LL>> futuOneThread(ALL);
vector<promise<LL>> promOneThread(ALL);
vector<LL> resultOnThread;
vector<thread> produceThread;
void func(promise<LL>& p) {
LL res = 0LL;
for (int i = 1; i <= N; i ++ )
res += i;
p.set_value(res);
}
void prod(int i, ThreadPool& threadPool) {
// 多生产者, 添加到任务队列中
for (int j = 0; j < M; j ++ ) {
futu[i][j] = prom[i][j].get_future();
threadPool.addTask(func, ref(prom[i][j]));
}
// 生产者完成数 + 1
finish.fetch_add(1);
}
void threadPoolRun() {
std::chrono::time_point<std::chrono::system_clock> start_time = std::chrono::system_clock::now();
for (int i = 0; i < producers; i ++ ) {
prom[i].resize(M);
futu[i].resize(M);
}
ThreadPool threadPool(workers, 20);
threadPool.start();
produceThread.resize(producers);
// 多生产者模式
for (int i = 0; i < producers; i ++ )
produceThread[i] = thread(prod, i, ref(threadPool));
// CAS 判断是否生产完毕
int cnt = producers;
while (!finish.compare_exchange_weak(cnt, cnt)) {
// 当finish != cnt时, cnt 会被置成 finish的当前值, 因此每次需要重置cnt
cnt = producers;
}
// 结束线程池
threadPool.stop();
// 回收生产者线程
for (auto& t : produceThread)
t.join();
for (int i = 0; i < producers; i ++ ) {
for (auto& f : futu[i]) {
LL cur = f.get();
resultThreadPool[i].push_back(cur);
}
}
for (int i = 0; i < producers; i ++ )
for (int j = 0; j < resultThreadPool[i].size(); j ++ )
assert(resultThreadPool[i][0] == resultThreadPool[i][j]);
std::chrono::time_point<std::chrono::system_clock> end_time = std::chrono::system_clock::now();
std::chrono::milliseconds time = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time);
cout << "\n ThreadPool cost time = " << time.count() << " ms\n";
}
void oneThreadRun() {
std::chrono::time_point<std::chrono::system_clock> start_time = std::chrono::system_clock::now();
for (int i = 0; i < ALL; i ++ ) {
futuOneThread[i] = promOneThread[i].get_future();
func(ref(promOneThread[i]));
LL cur = futuOneThread[i].get();
resultOnThread.push_back(cur);
}
for (int i = 0; i < ALL; i ++ )
assert(resultOnThread[0] == resultOnThread[i]);
std::chrono::time_point<std::chrono::system_clock> end_time = std::chrono::system_clock::now();
std::chrono::milliseconds time = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time);
cout << "\n oneThreadRun cost time = " << time.count() << " ms\n";
}
int main() {
oneThreadRun();
threadPoolRun();
return 0;
}