forked from owent/libcopp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
sample_benchmark_coroutine_malloc.cpp
146 lines (118 loc) · 3.94 KB
/
sample_benchmark_coroutine_malloc.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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/*
* sample_stress_test_coroutine_malloc.cpp
*
* Created on: 2014年5月15日
* Author: owent
*
* Released under the MIT license
*/
#include <cstdio>
#include <cstring>
#include <inttypes.h>
#include <stdint.h>
#include <ctime>
#include <cstdlib>
// include manager header file
#include <libcopp/coroutine/coroutine_context_container.h>
#define CALC_MS_CLOCK(x) static_cast<int>((x) / (CLOCKS_PER_SEC / 1000))
#define CALC_NS_AVG_CLOCK(x, y) (1000000LL * static_cast<long long>((x) / (CLOCKS_PER_SEC / 1000)) / (y?y:1))
int switch_count = 100;
typedef copp::detail::coroutine_context_container<
copp::detail::coroutine_context_base,
copp::allocator::stack_allocator_malloc
> my_cotoutine_t;
// define a coroutine runner
class my_runner : public copp::detail::coroutine_runnable_base
{
public:
int operator()() {
// ... your code here ...
int count = switch_count; // 每个协程N次切换
my_cotoutine_t* addr = copp::this_coroutine::get<my_cotoutine_t>();
while (count -- > 0)
addr->yield();
return 1;
}
};
int MAX_COROUTINE_NUMBER = 100000; // 协程数量
my_cotoutine_t* co_arr = NULL;
my_runner* runner = NULL;
int main(int argc, char* argv[]) {
if (argc > 1) {
MAX_COROUTINE_NUMBER = atoi(argv[1]);
}
if (argc > 2) {
switch_count = atoi(argv[2]);
}
size_t stack_size = 16 * 1024;
if (argc > 3) {
stack_size = atoi(argv[3]) * 1024;
}
time_t begin_time = time(NULL);
clock_t begin_clock = clock();
// create coroutines
co_arr = new my_cotoutine_t[MAX_COROUTINE_NUMBER];
runner = new my_runner[MAX_COROUTINE_NUMBER];
time_t end_time = time(NULL);
clock_t end_clock = clock();
printf("allocate %d coroutine, cost time: %d s, clock time: %d ms, avg: %lld ns\n",
MAX_COROUTINE_NUMBER,
static_cast<int>(end_time - begin_time),
CALC_MS_CLOCK(end_clock - begin_clock),
CALC_NS_AVG_CLOCK(end_clock - begin_clock, MAX_COROUTINE_NUMBER)
);
// create a runner
// bind runner to coroutine object
for (int i = 0; i < MAX_COROUTINE_NUMBER; ++ i) {
co_arr[i].create(&runner[i], stack_size);
}
end_time = time(NULL);
end_clock = clock();
printf("create %d coroutine, cost time: %d s, clock time: %d ms, avg: %lld ns\n",
MAX_COROUTINE_NUMBER,
static_cast<int>(end_time - begin_time),
CALC_MS_CLOCK(end_clock - begin_clock),
CALC_NS_AVG_CLOCK(end_clock - begin_clock, MAX_COROUTINE_NUMBER)
);
begin_time = end_time;
begin_clock = end_clock;
// start a coroutine
for (int i = 0; i < MAX_COROUTINE_NUMBER; ++ i) {
co_arr[i].start();
}
// yield & resume from runner
bool continue_flag = true;
long long real_switch_times = static_cast<long long>(0);
while (continue_flag) {
continue_flag = false;
for (int i = 0; i < MAX_COROUTINE_NUMBER; ++ i) {
if (false == co_arr[i].is_finished()){
continue_flag = true;
++ real_switch_times;
co_arr[i].resume();
}
}
}
end_time = time(NULL);
end_clock = clock();
printf("switch %d coroutine contest %lld times, cost time: %d s, clock time: %d ms, avg: %lld ns\n",
MAX_COROUTINE_NUMBER,
real_switch_times,
static_cast<int>(end_time - begin_time),
CALC_MS_CLOCK(end_clock - begin_clock),
CALC_NS_AVG_CLOCK(end_clock - begin_clock, real_switch_times)
);
begin_time = end_time;
begin_clock = end_clock;
delete []co_arr;
delete []runner;
end_time = time(NULL);
end_clock = clock();
printf("remove %d coroutine, cost time: %d s, clock time: %d ms, avg: %lld ns\n",
MAX_COROUTINE_NUMBER,
static_cast<int>(end_time - begin_time),
CALC_MS_CLOCK(end_clock - begin_clock),
CALC_NS_AVG_CLOCK(end_clock - begin_clock, MAX_COROUTINE_NUMBER)
);
return 0;
}