1 // loop_time_test.cpp ----------------------------------------------------------------//
3 // Copyright Beman Dawes 2013
5 // Distributed under the Boost Software License, Version 1.0.
6 // http://www.boost.org/LICENSE_1_0.txt
8 //--------------------------------------------------------------------------------------//
10 //#define BOOST_ENDIAN_NO_INTRINSICS
11 //#define BOOST_ENDIAN_LOG
13 #include <boost/endian/detail/disable_warnings.hpp>
15 #include <boost/endian/conversion.hpp>
16 #include <boost/endian/arithmetic.hpp>
17 #include <boost/cstdint.hpp>
18 #include <boost/timer/timer.hpp>
22 #include <boost/detail/lightweight_main.hpp>
25 # pragma warning (push)
26 # pragma warning (disable : 4459)
28 #include <boost/lexical_cast.hpp>
30 # pragma warning (pop)
33 using namespace boost
;
34 using namespace boost::endian
;
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
46 bool time_aligned (true);
47 bool time_unaligned (true);
52 void process_command_line(int argc
, char * argv
[])
54 for (int a
= 0; a
< argc
; ++a
)
56 command_args
+= argv
[a
];
61 // cout << command_args << '\n';;
70 for (; argc
> 2; ++argv
, --argc
)
72 if ( *(argv
[2]+1) == 'p' )
73 places
= atoi( argv
[2]+2 );
74 else if (*(argv
[2] + 1) == 'v')
76 else if (*(argv
[2] + 1) == 'a')
77 time_unaligned
= false;
78 else if (*(argv
[2] + 1) == 'u')
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;
88 cout
<< "Error - unknown option: " << argv
[2] << "\n\n";
96 cout
<< "Usage: loop_time_test n [Options]\n"
97 " The argument n specifies the number of test cases to run\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"
111 std::string
with_digit_separator(int64_t x
)
113 std::string s
= boost::lexical_cast
<std::string
>(x
);
116 for (std::string::size_type i
= 0; i
< s
.size(); ++i
)
118 if (i
&& ((s
.size()-i
) % 3) == 0)
125 //--------------------------------------------------------------------------------------//
127 template <class T
, class EndianT
>
132 // cout << "*************Endian integer approach...\n";
134 boost::timer::cpu_timer t
;
135 for (uint64_t i
= 0; i
< n
; ++i
)
137 x
+= static_cast<T
>(i
);
141 cout
<< "<td align=\"right\">" << t
.format(places
, "%t") << " s</td>";
144 // cout << "***************Endian conversion approach...\n";
146 boost::timer::cpu_timer t
;
147 native_to_big_inplace(x
);
148 for (uint64_t i
= 0; i
< n
; ++i
)
150 x
+= static_cast<T
>(i
);
152 big_to_native_inplace(x
);
154 native_to_big_inplace(x
);
156 throw std::logic_error("integer approach total != conversion approach total");
157 cout
<< "<td align=\"right\">" << t
.format(places
, "%t") << " s</td>";
162 void test_big_align_int16()
164 cout
<< "<tr><td>16-bit aligned big endian</td>";
165 time
<int16_t, big_int16_at
>();
169 void test_little_align_int16()
171 cout
<< "<tr><td>16-bit aligned little endian</td>";
172 time
<int16_t, little_int16_at
>();
176 void test_big_int16()
178 cout
<< "<tr><td>16-bit unaligned big endian</td>";
179 time
<int16_t, big_int16_t
>();
183 void test_little_int16()
185 cout
<< "<tr><td>16-bit unaligned little endian</td>";
186 time
<int16_t, little_int16_t
>();
190 void test_big_align_int32()
192 cout
<< "<tr><td>32-bit aligned big endian</td>";
193 time
<int32_t, big_int32_at
>();
197 void test_little_align_int32()
199 cout
<< "<tr><td>32-bit aligned little endian</td>";
200 time
<int32_t, little_int32_at
>();
204 void test_big_int32()
206 cout
<< "<tr><td>32-bit unaligned big endian</td>";
207 time
<int32_t, big_int32_t
>();
211 void test_little_int32()
213 cout
<< "<tr><td>32-bit unaligned little endian</td>";
214 time
<int32_t, little_int32_t
>();
218 void test_big_align_int64()
220 cout
<< "<tr><td>64-bit aligned big endian</td>";
221 time
<int64_t, big_int64_at
>();
225 void test_little_align_int64()
227 cout
<< "<tr><td>64-bit aligned little endian</td>";
228 time
<int64_t, little_int64_at
>();
232 void test_big_int64()
234 cout
<< "<tr><td>64-bit unaligned big endian</td>";
235 time
<int64_t, big_int64_t
>();
239 void test_little_int64()
241 cout
<< "<tr><td>64-bit unaligned little endian</td>";
242 time
<int64_t, little_int64_t
>();
246 } // unnamed namespace
248 //--------------------------------------------------------------------------------------//
250 int cpp_main(int argc
, char* argv
[])
252 process_command_line(argc
, argv
);
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"
276 test_big_align_int16();
277 test_little_align_int16();
281 test_big_align_int32();
282 test_little_align_int32();
286 test_big_align_int64();
287 test_little_align_int64();
310 cout
<< "\n</div> </center>\n"
311 << "\n</table>\n</body>\n</html>\n";
316 #include <boost/endian/detail/disable_warnings_pop.hpp>