cycle_count.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. // cycle_count.cpp ----------------------------------------------------------//
  2. // Copyright 2008 Howard Hinnant
  3. // Copyright 2008 Beman Dawes
  4. // Copyright 2009 Vicente J. Botet Escriba
  5. // Distributed under the Boost Software License, Version 1.0.
  6. // See http://www.boost.org/LICENSE_1_0.txt
  7. /*
  8. This code was extracted by Vicente J. Botet Escriba from Beman Dawes time2_demo.cpp which
  9. was derived by Beman Dawes from Howard Hinnant's time2_demo prototype.
  10. Many thanks to Howard for making his code available under the Boost license.
  11. The original code was modified to conform to Boost conventions and to section
  12. 20.9 Time utilities [time] of the C++ committee's working paper N2798.
  13. See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf.
  14. time2_demo contained this comment:
  15. Much thanks to Andrei Alexandrescu,
  16. Walter Brown,
  17. Peter Dimov,
  18. Jeff Garland,
  19. Terry Golubiewski,
  20. Daniel Krugler,
  21. Anthony Williams.
  22. */
  23. #include <boost/chrono/chrono.hpp>
  24. #include <boost/type_traits.hpp>
  25. #include <iostream>
  26. using namespace boost::chrono;
  27. template <long long speed>
  28. struct cycle_count
  29. {
  30. typedef typename boost::ratio_multiply<boost::ratio<speed>, boost::mega>::type frequency; // Mhz
  31. typedef typename boost::ratio_divide<boost::ratio<1>, frequency>::type period;
  32. typedef long long rep;
  33. typedef boost::chrono::duration<rep, period> duration;
  34. typedef boost::chrono::time_point<cycle_count> time_point;
  35. static time_point now()
  36. {
  37. static long long tick = 0;
  38. // return exact cycle count
  39. return time_point(duration(++tick)); // fake access to clock cycle count
  40. }
  41. };
  42. template <long long speed>
  43. struct approx_cycle_count
  44. {
  45. static const long long frequency = speed * 1000000; // MHz
  46. typedef nanoseconds duration;
  47. typedef duration::rep rep;
  48. typedef duration::period period;
  49. static const long long nanosec_per_sec = period::den;
  50. typedef boost::chrono::time_point<approx_cycle_count> time_point;
  51. static time_point now()
  52. {
  53. static long long tick = 0;
  54. // return cycle count as an approximate number of nanoseconds
  55. // compute as if nanoseconds is only duration in the std::lib
  56. return time_point(duration(++tick * nanosec_per_sec / frequency));
  57. }
  58. };
  59. void cycle_count_delay()
  60. {
  61. {
  62. typedef cycle_count<400> clock;
  63. std::cout << "\nSimulated " << clock::frequency::num / boost::mega::num << "MHz clock which has a tick period of "
  64. << duration<double, boost::nano>(clock::duration(1)).count() << " nanoseconds\n";
  65. nanoseconds delayns(500);
  66. clock::duration delay = duration_cast<clock::duration>(delayns);
  67. std::cout << "delay = " << delayns.count() << " nanoseconds which is " << delay.count() << " cycles\n";
  68. clock::time_point start = clock::now();
  69. clock::time_point stop = start + delay;
  70. while (clock::now() < stop) // no multiplies or divides in this loop
  71. ;
  72. clock::time_point end = clock::now();
  73. clock::duration elapsed = end - start;
  74. std::cout << "paused " << elapsed.count() << " cycles ";
  75. std::cout << "which is " << duration_cast<nanoseconds>(elapsed).count() << " nanoseconds\n";
  76. }
  77. {
  78. typedef approx_cycle_count<400> clock;
  79. std::cout << "\nSimulated " << clock::frequency / 1000000 << "MHz clock modeled with nanoseconds\n";
  80. clock::duration delay = nanoseconds(500);
  81. std::cout << "delay = " << delay.count() << " nanoseconds\n";
  82. clock::time_point start = clock::now();
  83. clock::time_point stop = start + delay;
  84. while (clock::now() < stop) // 1 multiplication and 1 division in this loop
  85. ;
  86. clock::time_point end = clock::now();
  87. clock::duration elapsed = end - start;
  88. std::cout << "paused " << elapsed.count() << " nanoseconds\n";
  89. }
  90. {
  91. typedef cycle_count<1500> clock;
  92. std::cout << "\nSimulated " << clock::frequency::num / boost::mega::num << "MHz clock which has a tick period of "
  93. << duration<double, boost::nano>(clock::duration(1)).count() << " nanoseconds\n";
  94. nanoseconds delayns(500);
  95. clock::duration delay = duration_cast<clock::duration>(delayns);
  96. std::cout << "delay = " << delayns.count() << " nanoseconds which is " << delay.count() << " cycles\n";
  97. clock::time_point start = clock::now();
  98. clock::time_point stop = start + delay;
  99. while (clock::now() < stop) // no multiplies or divides in this loop
  100. ;
  101. clock::time_point end = clock::now();
  102. clock::duration elapsed = end - start;
  103. std::cout << "paused " << elapsed.count() << " cycles ";
  104. std::cout << "which is " << duration_cast<nanoseconds>(elapsed).count() << " nanoseconds\n";
  105. }
  106. {
  107. typedef approx_cycle_count<1500> clock;
  108. std::cout << "\nSimulated " << clock::frequency / 1000000 << "MHz clock modeled with nanoseconds\n";
  109. clock::duration delay = nanoseconds(500);
  110. std::cout << "delay = " << delay.count() << " nanoseconds\n";
  111. clock::time_point start = clock::now();
  112. clock::time_point stop = start + delay;
  113. while (clock::now() < stop) // 1 multiplication and 1 division in this loop
  114. ;
  115. clock::time_point end = clock::now();
  116. clock::duration elapsed = end - start;
  117. std::cout << "paused " << elapsed.count() << " nanoseconds\n";
  118. }
  119. }
  120. int main()
  121. {
  122. cycle_count_delay();
  123. return 0;
  124. }