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 | /* |
11 | This code was extracted by Vicente J. Botet Escriba from Beman Dawes time2_demo.cpp which |
12 | was derived by Beman Dawes from Howard Hinnant's time2_demo prototype. |
13 | Many thanks to Howard for making his code available under the Boost license. |
14 | The original code was modified to conform to Boost conventions and to section |
15 | 20.9 Time utilities [time] of the C++ committee's working paper N2798. |
16 | See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf. |
17 | |
18 | time2_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 | |
34 | using namespace boost::chrono; |
35 | |
36 | |
37 | template <long long speed> |
38 | struct 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 | |
54 | template <long long speed> |
55 | struct 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 | |
73 | void 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 | |
135 | int main() |
136 | { |
137 | cycle_count_delay(); |
138 | return 0; |
139 | } |
140 | |
141 | |