]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/endian/test/loop_time_test.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / endian / test / loop_time_test.cpp
1 // loop_time_test.cpp ----------------------------------------------------------------//
2
3 // Copyright Beman Dawes 2013
4
5 // Distributed under the Boost Software License, Version 1.0.
6 // http://www.boost.org/LICENSE_1_0.txt
7
8 //--------------------------------------------------------------------------------------//
9
10 //#define BOOST_ENDIAN_NO_INTRINSICS
11 //#define BOOST_ENDIAN_LOG
12
13 #include <boost/endian/detail/disable_warnings.hpp>
14
15 #include <boost/endian/conversion.hpp>
16 #include <boost/endian/arithmetic.hpp>
17 #include <boost/cstdint.hpp>
18 #include <boost/timer/timer.hpp>
19 #include <iostream>
20 #include <cstdlib>
21 #include <string>
22 #include <boost/detail/lightweight_main.hpp>
23
24 #ifdef _MSC_VER
25 # pragma warning (push)
26 # pragma warning (disable : 4459)
27 #endif
28 #include <boost/lexical_cast.hpp>
29 #ifdef _MSC_VER
30 # pragma warning (pop)
31 #endif
32
33 using namespace boost;
34 using namespace boost::endian;
35
36 using std::cout;
37 using std::endl;
38
39 namespace
40 {
41 typedef boost::timer::nanosecond_type nanosecond_t;
42 std::string command_args;
43 uint64_t n; // number of test cases to run
44 int places = 2; // decimal places for times
45 bool verbose (false);
46 bool time_aligned (true);
47 bool time_unaligned (true);
48 bool time_16(true);
49 bool time_32(true);
50 bool time_64(true);
51
52 void process_command_line(int argc, char * argv[])
53 {
54 for (int a = 0; a < argc; ++a)
55 {
56 command_args += argv[a];
57 if (a != argc-1)
58 command_args += ' ';
59 }
60
61 // cout << command_args << '\n';;
62
63 if (argc >=2)
64 #ifndef _MSC_VER
65 n = atoll(argv[1]);
66 #else
67 n = _atoi64(argv[1]);
68 #endif
69
70 for (; argc > 2; ++argv, --argc)
71 {
72 if ( *(argv[2]+1) == 'p' )
73 places = atoi( argv[2]+2 );
74 else if (*(argv[2] + 1) == 'v')
75 verbose = true;
76 else if (*(argv[2] + 1) == 'a')
77 time_unaligned = false;
78 else if (*(argv[2] + 1) == 'u')
79 time_aligned = false;
80 else if (*(argv[2] + 1) == '1')
81 time_32 = time_64 = false;
82 else if (*(argv[2] + 1) == '3')
83 time_16 = time_64 = false;
84 else if (*(argv[2] + 1) == '6')
85 time_16 = time_32 = false;
86 else
87 {
88 cout << "Error - unknown option: " << argv[2] << "\n\n";
89 argc = -1;
90 break;
91 }
92 }
93
94 if (argc < 2)
95 {
96 cout << "Usage: loop_time_test n [Options]\n"
97 " The argument n specifies the number of test cases to run\n"
98 " Options:\n"
99 " -v Verbose messages\n"
100 " -p# Decimal places for times; default -p" << places << "\n"
101 " -a Aligned tests only\n"
102 " -u Unaligned tests only\n"
103 " -16 16-bit tests only\n"
104 " -32 32-bit tests only\n"
105 " -64 64-bit tests only\n"
106 ;
107 return std::exit(1);
108 }
109 }
110
111 std::string with_digit_separator(int64_t x)
112 {
113 std::string s = boost::lexical_cast<std::string>(x);
114 std::string s2;
115
116 for (std::string::size_type i = 0; i < s.size(); ++i)
117 {
118 if (i && ((s.size()-i) % 3) == 0)
119 s2 += '\'';
120 s2 += s[i];
121 }
122 return s2;
123 }
124
125 //--------------------------------------------------------------------------------------//
126
127 template <class T, class EndianT>
128 void time()
129 {
130 T total = 0;
131 {
132 // cout << "*************Endian integer approach...\n";
133 EndianT x(0);
134 boost::timer::cpu_timer t;
135 for (uint64_t i = 0; i < n; ++i)
136 {
137 x += static_cast<T>(i);
138 }
139 t.stop();
140 total += x;
141 cout << "<td align=\"right\">" << t.format(places, "%t") << " s</td>";
142 }
143 {
144 // cout << "***************Endian conversion approach...\n";
145 T x(0);
146 boost::timer::cpu_timer t;
147 native_to_big_inplace(x);
148 for (uint64_t i = 0; i < n; ++i)
149 {
150 x += static_cast<T>(i);
151 }
152 big_to_native_inplace(x);
153 t.stop();
154 native_to_big_inplace(x);
155 if (x != total)
156 throw std::logic_error("integer approach total != conversion approach total");
157 cout << "<td align=\"right\">" << t.format(places, "%t") << " s</td>";
158 }
159 }
160
161
162 void test_big_align_int16()
163 {
164 cout << "<tr><td>16-bit aligned big endian</td>";
165 time<int16_t, big_int16_at>();
166 cout << "</tr>\n";
167 }
168
169 void test_little_align_int16()
170 {
171 cout << "<tr><td>16-bit aligned little endian</td>";
172 time<int16_t, little_int16_at>();
173 cout << "</tr>\n";
174 }
175
176 void test_big_int16()
177 {
178 cout << "<tr><td>16-bit unaligned big endian</td>";
179 time<int16_t, big_int16_t>();
180 cout << "</tr>\n";
181 }
182
183 void test_little_int16()
184 {
185 cout << "<tr><td>16-bit unaligned little endian</td>";
186 time<int16_t, little_int16_t>();
187 cout << "</tr>\n";
188 }
189
190 void test_big_align_int32()
191 {
192 cout << "<tr><td>32-bit aligned big endian</td>";
193 time<int32_t, big_int32_at>();
194 cout << "</tr>\n";
195 }
196
197 void test_little_align_int32()
198 {
199 cout << "<tr><td>32-bit aligned little endian</td>";
200 time<int32_t, little_int32_at>();
201 cout << "</tr>\n";
202 }
203
204 void test_big_int32()
205 {
206 cout << "<tr><td>32-bit unaligned big endian</td>";
207 time<int32_t, big_int32_t>();
208 cout << "</tr>\n";
209 }
210
211 void test_little_int32()
212 {
213 cout << "<tr><td>32-bit unaligned little endian</td>";
214 time<int32_t, little_int32_t>();
215 cout << "</tr>\n";
216 }
217
218 void test_big_align_int64()
219 {
220 cout << "<tr><td>64-bit aligned big endian</td>";
221 time<int64_t, big_int64_at>();
222 cout << "</tr>\n";
223 }
224
225 void test_little_align_int64()
226 {
227 cout << "<tr><td>64-bit aligned little endian</td>";
228 time<int64_t, little_int64_at>();
229 cout << "</tr>\n";
230 }
231
232 void test_big_int64()
233 {
234 cout << "<tr><td>64-bit unaligned big endian</td>";
235 time<int64_t, big_int64_t>();
236 cout << "</tr>\n";
237 }
238
239 void test_little_int64()
240 {
241 cout << "<tr><td>64-bit unaligned little endian</td>";
242 time<int64_t, little_int64_t>();
243 cout << "</tr>\n";
244 }
245
246 } // unnamed namespace
247
248 //--------------------------------------------------------------------------------------//
249
250 int cpp_main(int argc, char* argv[])
251 {
252 process_command_line(argc, argv);
253
254 cout
255 << "<html>\n<head>\n<title>Endian Loop Time Test</title>\n</head>\n<body>\n"
256 << "<!-- boost-no-inspect -->\n"
257 << "<div align=\"center\"> <center>\n"
258 << "<table border=\"1\" cellpadding=\"5\" cellspacing=\"0\""
259 << "style=\"border-collapse: collapse\" bordercolor=\"#111111\">\n"
260 << "<tr><td colspan=\"6\" align=\"center\"><b>"
261 << BOOST_COMPILER << "</b></td></tr>\n"
262 << "<tr><td colspan=\"6\" align=\"center\"><b>"
263 << " Iterations: " << with_digit_separator(n)
264 << ", Intrinsics: " BOOST_ENDIAN_INTRINSIC_MSG
265 << "</b></td></tr>\n"
266 << "<tr><td><b>Test Case</b></td>\n"
267 "<td align=\"center\"><b>Endian<br>arithmetic<br>type</b></td>\n"
268 "<td align=\"center\"><b>Endian<br>conversion<br>function</b></td>\n"
269 "</tr>\n"
270 ;
271
272 if (time_aligned)
273 {
274 if (time_16)
275 {
276 test_big_align_int16();
277 test_little_align_int16();
278 }
279 if (time_32)
280 {
281 test_big_align_int32();
282 test_little_align_int32();
283 }
284 if (time_64)
285 {
286 test_big_align_int64();
287 test_little_align_int64();
288 }
289 }
290
291 if (time_unaligned)
292 {
293 if (time_16)
294 {
295 test_big_int16();
296 test_little_int16();
297 }
298 if (time_32)
299 {
300 test_big_int32();
301 test_little_int32();
302 }
303 if (time_64)
304 {
305 test_big_int64();
306 test_little_int64();
307 }
308 }
309
310 cout << "\n</div> </center>\n"
311 << "\n</table>\n</body>\n</html>\n";
312
313 return 0;
314 }
315
316 #include <boost/endian/detail/disable_warnings_pop.hpp>