run_timer_test.cpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. // boost run_timer_test.cpp -----------------------------------------------------//
  2. // Copyright Beman Dawes 2006, 2008
  3. // Copyright 2009 Vicente J. Botet Escriba
  4. // Distributed under the Boost Software License, Version 1.0.
  5. // See http://www.boost.org/LICENSE_1_0.txt
  6. // See http://www.boost.org/libs/chrono for documentation.
  7. #include <boost/chrono/process_times.hpp>
  8. #include <boost/chrono/timer.hpp>
  9. #include <cstdlib> // for atol()
  10. #include <iostream>
  11. #include <sstream>
  12. #include <locale>
  13. #include <ctime>
  14. #include <cmath> // for sqrt(), used to burn time
  15. using boost::chrono::run_timer;
  16. using boost::system::error_code;
  17. #include <boost/detail/lightweight_test.hpp>
  18. //#define BOOST_TEST(expr) if (!(expr)) std::cout << "*****ERROR*****\n"
  19. #define CHECK_REPORT(Timer,String_Stream,R,U,S,Expected_String) \
  20. check_report(Timer, String_Stream, R, U, S, Expected_String, __LINE__)
  21. namespace
  22. {
  23. typedef boost::chrono::nanoseconds ns;
  24. bool check_report( run_timer & tmr, std::stringstream & ss,
  25. run_timer::duration r, run_timer::duration u, run_timer::duration s,
  26. const std::string & expected, int line )
  27. {
  28. tmr.test_report(r,u,s);
  29. bool result(true);
  30. if ( ss.str() != expected )
  31. {
  32. std::cout << "run_timer_test.cpp(" << line << ") : error: actual output \""
  33. << ss.str() << "\" != expected \"" << expected << "\"\n";
  34. result = false;
  35. }
  36. return result;
  37. }
  38. void run_timer_constructor_overload_test()
  39. {
  40. // exercise each supported combination of constructor arguments
  41. std::ostream & os = std::cout;
  42. const int pl = 9;
  43. boost::system::error_code ec;
  44. run_timer t1;
  45. run_timer t2( os );
  46. run_timer t3( ec );
  47. run_timer t4( os, ec );
  48. run_timer t5( pl );
  49. run_timer t6( os, pl );
  50. run_timer t7( pl, ec );
  51. run_timer t8( os, pl, ec );
  52. run_timer t9( "t9, default places, r %r, c %c, p %p, u %u, s %s\n" );
  53. run_timer t10( os, "t10, default places, r %r, c %c, p %p, u %u, s %s\n" );
  54. run_timer t11( "t11, default places, r %r, c %c, p %p, u %u, s %s\n", ec );
  55. run_timer t12( os, "t12, default places, r %r, c %c, p %p, u %u, s %s\n", ec );
  56. run_timer t13( pl, "t13, explicitly code places, r %r, c %c, p %p, u %u, s %s\n" );
  57. run_timer t14( "t14, explicitly code places, r %r, c %c, p %p, u %u, s %s\n", pl );
  58. run_timer t15( os, pl, "t15, explicitly code places, r %r, c %c, p %p, u %u, s %s\n" );
  59. run_timer t16( os, "t16, explicitly code places, r %r, c %c, p %p, u %u, s %s\n", pl );
  60. run_timer t17( pl, "t17, explicitly code places, r %r, c %c, p %p, u %u, s %s\n", ec );
  61. run_timer t18( "t18, explicitly code places, r %r, c %c, p %p, u %u, s %s\n", pl, ec );
  62. run_timer t19( os, pl, "t19, explicitly code places, r %r, c %c, p %p, u %u, s %s\n", ec );
  63. run_timer t20( os, "t20, explicitly code places, r %r, c %c, p %p, u %u, s %s\n", pl, ec );
  64. std::cout << "Burn some time so run_timers have something to report...";
  65. boost::chrono::timer<boost::chrono::high_resolution_clock> t;
  66. while ( t.elapsed() < boost::chrono::seconds(1) ) {}
  67. std::cout << "\n";
  68. std::cout << run_timer::default_places() << " default places\n";
  69. std::cout << pl << " explicitly coded places\n";
  70. }
  71. // accuracy test
  72. void accuracy_test( int argc, char * argv[] )
  73. {
  74. long timeout_in_secs = 1;
  75. if ( argc > 1 ) timeout_in_secs = std::atol( argv[1] );
  76. std::cout << "accuracy test for " << timeout_in_secs << " second(s)...";
  77. std::clock_t timeout_in_clock_t = std::clock();
  78. timeout_in_clock_t += (timeout_in_secs * CLOCKS_PER_SEC);
  79. boost::chrono::system_timer sys;
  80. #ifdef BOOST_CHRONO_HAS_CLOCK_STEADY
  81. boost::chrono::steady_timer mono;
  82. #endif
  83. boost::chrono::high_resolution_timer hires;
  84. boost::chrono::process_timer process;
  85. std::clock_t now;
  86. do
  87. {
  88. now = std::clock();
  89. } while ( now < timeout_in_clock_t );
  90. boost::chrono::system_timer::duration sys_dur = sys.elapsed();
  91. #ifdef BOOST_CHRONO_HAS_CLOCK_STEADY
  92. boost::chrono::steady_timer::duration mono_dur = mono.elapsed();
  93. #endif
  94. boost::chrono::high_resolution_timer::duration hires_dur = hires.elapsed();
  95. boost::chrono::process_times times;
  96. process.elapsed( times );
  97. std::cout << std::endl;
  98. ns timeout_in_nanoseconds( static_cast<long long>(timeout_in_secs) * 1000000000LL );
  99. // Allow 20% leeway. Particularly on Linux, there seems to be a large discrepancy
  100. // between std::clock() and higher resolution clocks.
  101. ns maximum_delta ( static_cast<long long>(timeout_in_nanoseconds.count() * 0.20 ) );
  102. std::cout << timeout_in_nanoseconds.count() << " timeout_in_nanoseconds\n";
  103. std::cout << maximum_delta.count() << " maximum_delta\n";
  104. std::cout << sys_dur.count() << " sys_dur\n";
  105. BOOST_TEST( sys_dur > timeout_in_nanoseconds - maximum_delta
  106. && sys_dur < timeout_in_nanoseconds + maximum_delta );
  107. #ifdef BOOST_CHRONO_HAS_CLOCK_STEADY
  108. std::cout << mono_dur.count() << " mono_dur\n";
  109. BOOST_TEST( mono_dur > timeout_in_nanoseconds - maximum_delta
  110. && mono_dur < timeout_in_nanoseconds + maximum_delta );
  111. #endif
  112. std::cout << hires_dur.count() << " hires_dur\n";
  113. BOOST_TEST( hires_dur > timeout_in_nanoseconds - maximum_delta
  114. && hires_dur < timeout_in_nanoseconds + maximum_delta );
  115. std::cout << times.real.count() << " times.real\n";
  116. BOOST_TEST( times.real > timeout_in_nanoseconds - maximum_delta
  117. && times.real < timeout_in_nanoseconds + maximum_delta );
  118. }
  119. // report test
  120. void report_test()
  121. {
  122. {
  123. std::stringstream ss;
  124. run_timer t(ss);
  125. BOOST_TEST( CHECK_REPORT(t, ss, ns(0), ns(0), ns(0),
  126. "\nreal 0.000s, cpu 0.000s (0.0%), user 0.000s, system 0.000s\n" ) );
  127. }
  128. {
  129. std::stringstream ss;
  130. run_timer t(ss);
  131. BOOST_TEST( CHECK_REPORT(t, ss, ns(3000000000LL), ns(2000000000LL), ns(1000000000LL),
  132. "\nreal 3.000s, cpu 3.000s (100.0%), user 2.000s, system 1.000s\n" ) );
  133. }
  134. {
  135. std::stringstream ss;
  136. run_timer t( ss, "9 places: r %r, c %c, p %p, u %u, s %s", 9 );
  137. BOOST_TEST( CHECK_REPORT(t, ss, ns(3000000003LL), ns(2000000002LL), ns(1000000001LL),
  138. "9 places: "
  139. "r 3.000000003, c 3.000000003, p 100.0, u 2.000000002, s 1.000000001" ) );
  140. }
  141. }
  142. // process_timer_test
  143. void process_timer_test()
  144. {
  145. std::cout << "process_timer_test..." << std::flush;
  146. boost::chrono::process_timer t;
  147. double res=0; // avoids optimization
  148. for (long i = 0; i < 10000000L; ++i)
  149. {
  150. res+=std::sqrt( static_cast<double>(i) ); // avoids optimization
  151. }
  152. boost::chrono::process_times times;
  153. times.real = times.system = times.user = ns(0);
  154. BOOST_TEST( times.real == ns(0) );
  155. BOOST_TEST( times.user == ns(0) );
  156. BOOST_TEST( times.system == ns(0) );
  157. t.elapsed( times );
  158. std::cout << "\n";
  159. std::cout << times.real.count() << " times.real\n";
  160. std::cout << times.user.count() << " times.user\n";
  161. std::cout << times.system.count() << " times.system\n";
  162. std::cout << (times.user+times.system).count() << " times.user+system\n";
  163. BOOST_TEST( times.real > ns(1) );
  164. BOOST_TEST( times.user+times.system > ns(1) );
  165. std::cout << "complete " << res << std::endl;
  166. }
  167. }
  168. int main( int argc, char * argv[] )
  169. {
  170. std::locale loc( "" ); // test with appropriate locale
  171. std::cout.imbue( loc );
  172. accuracy_test( argc, argv );
  173. run_timer_constructor_overload_test();
  174. process_timer_test();
  175. report_test();
  176. return boost::report_errors();
  177. }