diff options
Diffstat (limited to 'src/boost/libs/endian/test/loop_time_test.cpp')
-rw-r--r-- | src/boost/libs/endian/test/loop_time_test.cpp | 315 |
1 files changed, 315 insertions, 0 deletions
diff --git a/src/boost/libs/endian/test/loop_time_test.cpp b/src/boost/libs/endian/test/loop_time_test.cpp new file mode 100644 index 00000000..82f33ea6 --- /dev/null +++ b/src/boost/libs/endian/test/loop_time_test.cpp @@ -0,0 +1,315 @@ +// loop_time_test.cpp ----------------------------------------------------------------// + +// Copyright Beman Dawes 2013 + +// Distributed under the Boost Software License, Version 1.0. +// http://www.boost.org/LICENSE_1_0.txt + +//--------------------------------------------------------------------------------------// + +//#define BOOST_ENDIAN_NO_INTRINSICS + +#include <boost/endian/detail/disable_warnings.hpp> + +#include <boost/endian/conversion.hpp> +#include <boost/endian/arithmetic.hpp> +#include <boost/cstdint.hpp> +#include <boost/timer/timer.hpp> +#include <iostream> +#include <cstdlib> +#include <string> +#include <boost/detail/lightweight_main.hpp> + +#ifdef _MSC_VER +# pragma warning (push) +# pragma warning (disable : 4459) +#endif +#include <boost/lexical_cast.hpp> +#ifdef _MSC_VER +# pragma warning (pop) +#endif + +using namespace boost; +using namespace boost::endian; + +using std::cout; +using std::endl; + +namespace +{ + typedef boost::timer::nanosecond_type nanosecond_t; + std::string command_args; + uint64_t n; // number of test cases to run + int places = 2; // decimal places for times + bool verbose (false); + bool time_aligned (true); + bool time_unaligned (true); + bool time_16(true); + bool time_32(true); + bool time_64(true); + + void process_command_line(int argc, char * argv[]) + { + for (int a = 0; a < argc; ++a) + { + command_args += argv[a]; + if (a != argc-1) + command_args += ' '; + } + + // cout << command_args << '\n';; + + if (argc >=2) +#ifndef _MSC_VER + n = atoll(argv[1]); +#else + n = _atoi64(argv[1]); +#endif + + for (; argc > 2; ++argv, --argc) + { + if ( *(argv[2]+1) == 'p' ) + places = atoi( argv[2]+2 ); + else if (*(argv[2] + 1) == 'v') + verbose = true; + else if (*(argv[2] + 1) == 'a') + time_unaligned = false; + else if (*(argv[2] + 1) == 'u') + time_aligned = false; + else if (*(argv[2] + 1) == '1') + time_32 = time_64 = false; + else if (*(argv[2] + 1) == '3') + time_16 = time_64 = false; + else if (*(argv[2] + 1) == '6') + time_16 = time_32 = false; + else + { + cout << "Error - unknown option: " << argv[2] << "\n\n"; + argc = -1; + break; + } + } + + if (argc < 2) + { + cout << "Usage: loop_time_test n [Options]\n" + " The argument n specifies the number of test cases to run\n" + " Options:\n" + " -v Verbose messages\n" + " -p# Decimal places for times; default -p" << places << "\n" + " -a Aligned tests only\n" + " -u Unaligned tests only\n" + " -16 16-bit tests only\n" + " -32 32-bit tests only\n" + " -64 64-bit tests only\n" + ; + return std::exit(1); + } + } + + std::string with_digit_separator(int64_t x) + { + std::string s = boost::lexical_cast<std::string>(x); + std::string s2; + + for (std::string::size_type i = 0; i < s.size(); ++i) + { + if (i && ((s.size()-i) % 3) == 0) + s2 += '\''; + s2 += s[i]; + } + return s2; + } + +//--------------------------------------------------------------------------------------// + + template <class T, class EndianT> + void time() + { + T total = 0; + { + // cout << "*************Endian integer approach...\n"; + EndianT x(0); + boost::timer::cpu_timer t; + for (uint64_t i = 0; i < n; ++i) + { + x += static_cast<T>(i); + } + t.stop(); + total += x; + cout << "<td align=\"right\">" << t.format(places, "%t") << " s</td>"; + } + { +// cout << "***************Endian conversion approach...\n"; + T x(0); + boost::timer::cpu_timer t; + native_to_big_inplace(x); + for (uint64_t i = 0; i < n; ++i) + { + x += static_cast<T>(i); + } + big_to_native_inplace(x); + t.stop(); + native_to_big_inplace(x); + if (x != total) + throw std::logic_error("integer approach total != conversion approach total"); + cout << "<td align=\"right\">" << t.format(places, "%t") << " s</td>"; + } + } + + + void test_big_align_int16() + { + cout << "<tr><td>16-bit aligned big endian</td>"; + time<int16_t, big_int16_at>(); + cout << "</tr>\n"; + } + + void test_little_align_int16() + { + cout << "<tr><td>16-bit aligned little endian</td>"; + time<int16_t, little_int16_at>(); + cout << "</tr>\n"; + } + + void test_big_int16() + { + cout << "<tr><td>16-bit unaligned big endian</td>"; + time<int16_t, big_int16_t>(); + cout << "</tr>\n"; + } + + void test_little_int16() + { + cout << "<tr><td>16-bit unaligned little endian</td>"; + time<int16_t, little_int16_t>(); + cout << "</tr>\n"; + } + + void test_big_align_int32() + { + cout << "<tr><td>32-bit aligned big endian</td>"; + time<int32_t, big_int32_at>(); + cout << "</tr>\n"; + } + + void test_little_align_int32() + { + cout << "<tr><td>32-bit aligned little endian</td>"; + time<int32_t, little_int32_at>(); + cout << "</tr>\n"; + } + + void test_big_int32() + { + cout << "<tr><td>32-bit unaligned big endian</td>"; + time<int32_t, big_int32_t>(); + cout << "</tr>\n"; + } + + void test_little_int32() + { + cout << "<tr><td>32-bit unaligned little endian</td>"; + time<int32_t, little_int32_t>(); + cout << "</tr>\n"; + } + + void test_big_align_int64() + { + cout << "<tr><td>64-bit aligned big endian</td>"; + time<int64_t, big_int64_at>(); + cout << "</tr>\n"; + } + + void test_little_align_int64() + { + cout << "<tr><td>64-bit aligned little endian</td>"; + time<int64_t, little_int64_at>(); + cout << "</tr>\n"; + } + + void test_big_int64() + { + cout << "<tr><td>64-bit unaligned big endian</td>"; + time<int64_t, big_int64_t>(); + cout << "</tr>\n"; + } + + void test_little_int64() + { + cout << "<tr><td>64-bit unaligned little endian</td>"; + time<int64_t, little_int64_t>(); + cout << "</tr>\n"; + } + +} // unnamed namespace + +//--------------------------------------------------------------------------------------// + +int cpp_main(int argc, char* argv[]) +{ + process_command_line(argc, argv); + + cout + << "<html>\n<head>\n<title>Endian Loop Time Test</title>\n</head>\n<body>\n" + << "<!-- boost-no-inspect -->\n" + << "<div align=\"center\"> <center>\n" + << "<table border=\"1\" cellpadding=\"5\" cellspacing=\"0\"" + << "style=\"border-collapse: collapse\" bordercolor=\"#111111\">\n" + << "<tr><td colspan=\"6\" align=\"center\"><b>" + << BOOST_COMPILER << "</b></td></tr>\n" + << "<tr><td colspan=\"6\" align=\"center\"><b>" + << " Iterations: " << with_digit_separator(n) + << ", Intrinsics: " BOOST_ENDIAN_INTRINSIC_MSG + << "</b></td></tr>\n" + << "<tr><td><b>Test Case</b></td>\n" + "<td align=\"center\"><b>Endian<br>arithmetic<br>type</b></td>\n" + "<td align=\"center\"><b>Endian<br>conversion<br>function</b></td>\n" + "</tr>\n" + ; + + if (time_aligned) + { + if (time_16) + { + test_big_align_int16(); + test_little_align_int16(); + } + if (time_32) + { + test_big_align_int32(); + test_little_align_int32(); + } + if (time_64) + { + test_big_align_int64(); + test_little_align_int64(); + } + } + + if (time_unaligned) + { + if (time_16) + { + test_big_int16(); + test_little_int16(); + } + if (time_32) + { + test_big_int32(); + test_little_int32(); + } + if (time_64) + { + test_big_int64(); + test_little_int64(); + } + } + + cout << "\n</div> </center>\n" + << "\n</table>\n</body>\n</html>\n"; + + return 0; +} + +#include <boost/endian/detail/disable_warnings_pop.hpp> |