]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/coroutine2/performance/performance_switch.cpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / coroutine2 / performance / performance_switch.cpp
1
2 // Copyright Oliver Kowalke 2014.
3 // Distributed under the Boost Software License, Version 1.0.
4 // (See accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
6
7 #include <cstdlib>
8 #include <iostream>
9 #include <stdexcept>
10 #include <string>
11
12 #include <boost/chrono.hpp>
13 #include <boost/coroutine2/all.hpp>
14 #include <boost/cstdint.hpp>
15 #include <boost/program_options.hpp>
16
17 #include "bind_processor.hpp"
18 #include "clock.hpp"
19 #include "cycle.hpp"
20
21 boost::uint64_t jobs = 1000;
22
23 struct X
24 {
25 std::string str;
26
27 X( std::string const& str_) :
28 str( str_)
29 {}
30 };
31
32 const X x("abc");
33
34 void fn_void( boost::coroutines2::coroutine< void >::push_type & c)
35 { while ( true) c(); }
36
37 void fn_int( boost::coroutines2::coroutine< int >::push_type & c)
38 { while ( true) c( 7); }
39
40 void fn_x( boost::coroutines2::coroutine< X >::push_type & c)
41 {
42 while ( true) c( x);
43 }
44
45 duration_type measure_time_void( duration_type overhead)
46 {
47 boost::coroutines2::coroutine< void >::pull_type c( fn_void);
48
49 time_point_type start( clock_type::now() );
50 for ( std::size_t i = 0; i < jobs; ++i) {
51 c();
52 }
53 duration_type total = clock_type::now() - start;
54 total -= overhead_clock(); // overhead of measurement
55 total /= jobs; // loops
56 total /= 2; // 2x jump_fcontext
57
58 return total;
59 }
60
61 duration_type measure_time_int( duration_type overhead)
62 {
63 boost::coroutines2::coroutine< int >::pull_type c( fn_int);
64
65 time_point_type start( clock_type::now() );
66 for ( std::size_t i = 0; i < jobs; ++i) {
67 c();
68 }
69 duration_type total = clock_type::now() - start;
70 total -= overhead_clock(); // overhead of measurement
71 total /= jobs; // loops
72 total /= 2; // 2x jump_fcontext
73
74 return total;
75 }
76
77 duration_type measure_time_x( duration_type overhead)
78 {
79 boost::coroutines2::coroutine< X >::pull_type c( fn_x);
80
81 time_point_type start( clock_type::now() );
82 for ( std::size_t i = 0; i < jobs; ++i) {
83 c();
84 }
85 duration_type total = clock_type::now() - start;
86 total -= overhead_clock(); // overhead of measurement
87 total /= jobs; // loops
88 total /= 2; // 2x jump_fcontext
89
90 return total;
91 }
92
93 # ifdef BOOST_CONTEXT_CYCLE
94 cycle_type measure_cycles_void( cycle_type overhead)
95 {
96 boost::coroutines2::coroutine< void >::pull_type c( fn_void);
97
98 cycle_type start( cycles() );
99 for ( std::size_t i = 0; i < jobs; ++i) {
100 c();
101 }
102 cycle_type total = cycles() - start;
103 total -= overhead; // overhead of measurement
104 total /= jobs; // loops
105 total /= 2; // 2x jump_fcontext
106
107 return total;
108 }
109
110 cycle_type measure_cycles_int( cycle_type overhead)
111 {
112 boost::coroutines2::coroutine< int >::pull_type c( fn_int);
113
114 cycle_type start( cycles() );
115 for ( std::size_t i = 0; i < jobs; ++i) {
116 c();
117 }
118 cycle_type total = cycles() - start;
119 total -= overhead; // overhead of measurement
120 total /= jobs; // loops
121 total /= 2; // 2x jump_fcontext
122
123 return total;
124 }
125
126 cycle_type measure_cycles_x( cycle_type overhead)
127 {
128 boost::coroutines2::coroutine< X >::pull_type c( fn_x);
129
130 cycle_type start( cycles() );
131 for ( std::size_t i = 0; i < jobs; ++i) {
132 c();
133 }
134 cycle_type total = cycles() - start;
135 total -= overhead; // overhead of measurement
136 total /= jobs; // loops
137 total /= 2; // 2x jump_fcontext
138
139 return total;
140 }
141 # endif
142
143 int main( int argc, char * argv[])
144 {
145 try
146 {
147 bool bind = false;
148 boost::program_options::options_description desc("allowed options");
149 desc.add_options()
150 ("help", "help message")
151 ("bind,b", boost::program_options::value< bool >( & bind), "bind thread to CPU")
152 ("jobs,j", boost::program_options::value< boost::uint64_t >( & jobs), "jobs to run");
153
154 boost::program_options::variables_map vm;
155 boost::program_options::store(
156 boost::program_options::parse_command_line(
157 argc,
158 argv,
159 desc),
160 vm);
161 boost::program_options::notify( vm);
162
163 if ( vm.count("help") ) {
164 std::cout << desc << std::endl;
165 return EXIT_SUCCESS;
166 }
167
168 if ( bind) bind_to_processor( 0);
169
170 duration_type overhead_c = overhead_clock();
171 boost::uint64_t res = measure_time_void( overhead_c).count();
172 std::cout << "void: average of " << res << " nano seconds" << std::endl;
173 res = measure_time_int( overhead_c).count();
174 std::cout << "int: average of " << res << " nano seconds" << std::endl;
175 res = measure_time_x( overhead_c).count();
176 std::cout << "X: average of " << res << " nano seconds" << std::endl;
177 #ifdef BOOST_CONTEXT_CYCLE
178 cycle_type overhead_y = overhead_cycle();
179 res = measure_cycles_void( overhead_y);
180 std::cout << "void: average of " << res << " cpu cycles" << std::endl;
181 res = measure_cycles_int( overhead_y);
182 std::cout << "int: average of " << res << " cpu cycles" << std::endl;
183 res = measure_cycles_x( overhead_y);
184 std::cout << "X: average of " << res << " cpu cycles" << std::endl;
185 #endif
186
187 return EXIT_SUCCESS;
188 }
189 catch ( std::exception const& e)
190 { std::cerr << "exception: " << e.what() << std::endl; }
191 catch (...)
192 { std::cerr << "unhandled exception" << std::endl; }
193 return EXIT_FAILURE;
194 }