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

source code of boost/libs/chrono/example/cycle_count.cpp