123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315 |
- // 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>
|