libjmmcg
release_579_6_g8cffd
A C++ library containing an eclectic mix of useful, advanced components.
CPUTicker.hpp
Go to the documentation of this file.
1
/******************************************************************************
2
** Copyright © 2002 by J.M.McGuiness, coder@hussar.me.uk
3
**
4
** This library is free software; you can redistribute it and/or
5
** modify it under the terms of the GNU Lesser General Public
6
** License as published by the Free Software Foundation; either
7
** version 2.1 of the License, or (at your option) any later version.
8
**
9
** This library is distributed in the hope that it will be useful,
10
** but WITHOUT ANY WARRANTY; without even the implied warranty of
11
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
** Lesser General Public License for more details.
13
**
14
** You should have received a copy of the GNU Lesser General Public
15
** License along with this library; if not, write to the Free Software
16
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
*/
18
// TITLE:
19
// High-Resolution Counter Class.
20
//
21
// DESCRIPTION:
22
// This file declares a class the wraps the Pentium-specific time stamp counter.
23
// This counter has a resolution in terms of PCLKS (processor clocks) so it can
24
// be used for direct instruction timings.
25
//
26
// 1. The constructor can be time-expensive. It will throw an exception if the
27
// RDTSC instruction is not present.
28
// 2. The GetAndCalcCPUFrequency() function is also time-expensive, as this
29
// function dynamically re-calculates the CPU's core frequency.
30
// 3. Conversion from unsigned __int64 to double is not implemented in
31
// the MSVC++ v5.0 compiler, hence the GetTickCountUS() and GetTickCountS()
32
// operators. Also this is the reason for the operator-() function.
33
//
34
// This class has been tested to work on Pentium processors (at least P60's to
35
// P233 MMX's), Pentium Pro's and Pentium II's. It also works on AMD K6-233's.
36
//
37
// VERSION HISTORY:
38
// 26/3/96 1.0 Created.
39
// 16/7/97 2.0 Modified by P.J.Naughter, please see the source file for comments.
40
// Modified then by J.M.McGuiness.
41
// 22/10/97 3.0 Modified by J.M.McGuiness, made calling conventions explicitly to __fastcall.
42
// Please see the source file for more comments.
43
// 1/12/97 3.1 Modified to compile with MSVC++ v4.x and to ensure certain functions and structures are defined.
44
// 2/2/98 3.2 Updated the contact e-mail addresses.
45
// 12/5/99 3.21 Minor improvements to the interface functions.
46
// 25/2/2004 Removed MFC-isms, exception specifications and pointless comments.
47
48
// The MSVC++ v4.x compiler doesn't support the ANSI C++ data type "bool".
49
// Versions 5.0 and greater do.
50
#
if
_MSC_VER
<
1100
51
typedef
BOOL
bool
;
52
#
endif
53
54
#
include
"../OnNT.hpp"
55
56
namespace
jmmcg
{
namespace
NTUtils
{
57
58
class
win_exception;
59
60
class
AFX_EXT_CLASS
CPUTicker
{
61
public
:
62
typedef
win_exception
exception_type
;
63
64
class
CPUCountFn
{
65
public
:
66
__stdcall
CPUCountFn
(
void
)
noexcept
(
true
)
67
:
GetCPUCount
(
OnNT
() ?
new
GetCPUCountFnNT
() :
new
GetCPUCountFn9X
()) {
68
}
69
__stdcall
~
CPUCountFn
(
void
)
noexcept
(
true
) {
70
}
71
72
unsigned
__int64
__fastcall
GetCount
(
void
)
const
noexcept
(
true
) {
73
return
(*
GetCPUCount
)();
74
}
75
76
private
:
77
struct
GetCPUCountFnNT
{
78
virtual
unsigned
__int64
__fastcall
operator
()(
void
)
const
noexcept
(
true
);
79
};
80
struct
GetCPUCountFn9X
:
public
GetCPUCountFnNT
{
81
unsigned
__int64
__fastcall
operator
()(
void
)
const
noexcept
(
true
);
82
};
83
84
const
std
::
auto_ptr
<
GetCPUCountFnNT
>
GetCPUCount
;
85
86
__stdcall
CPUCountFn
(
const
CPUCountFn
&)
noexcept
(
true
);
87
CPUCountFn
&
operator
=(
const
CPUCountFn
&)
noexcept
(
true
);
88
};
89
90
__stdcall
CPUTicker
(
void
);
91
__stdcall
CPUTicker
(
const
CPUTicker
&)
noexcept
(
true
);
92
__stdcall
~
CPUTicker
(
void
);
93
94
CPUTicker
&
__fastcall
operator
=(
const
CPUTicker
&)
noexcept
(
true
);
95
96
// Perform the actual measurement.
97
void
__fastcall
GetCPUCount
(
void
)
noexcept
(
true
);
98
99
// Accessors to the actual measured value.
100
double
__fastcall
GetTickCountAsSeconds
(
void
)
const
{
101
return
static_cast
<
double
>(
GetTickCountS
())/
freq
;
102
}
103
unsigned
__int64
__fastcall
GetTickCountUS
(
void
)
const
noexcept
(
true
) {
104
return
TickCount
;
105
}
106
signed
__int64
__fastcall
GetTickCountS
(
void
)
const
;
107
108
/**
109
The following function will work out the processor clock frequency to a
110
specified accuracy determined by the target average deviation required.
111
Note that the worst average deviation of the result is less than 5MHz for
112
a mean frequency of 90MHz. So basically the target average deviation is
113
supplied only if you want a more accurate result, it won't let you get a
114
worse one. (Units are Hz.)
115
116
(The average deviation is a better and more robust measure than it's cousin
117
the standard deviation of a quantity. The item determined by each is
118
essentially similar. See "Numerical Recipies", W.Press et al for more
119
details.)
120
121
This function will run for a maximum of 20 seconds before giving up on
122
trying to improve the average deviation, with the average deviation
123
actually achieved replacing the supplied target value. Use "max_loops" to
124
change this. To improve the value the function converges to increase
125
"interval" (which is in units of ms, default value=1000ms).
126
*/
127
const
bool
__fastcall
GetAndCalcCPUFrequency
(
double
&
frequency
,
double
&
target_ave_dev
,
const
unsigned
long
interval
= 1000,
const
unsigned
int
max_loops
=20);
128
void
__fastcall
GetCPUFrequency
(
double
&
frequency
,
double
&
target_ave_dev
)
const
noexcept
(
true
) {
129
frequency
=
freq
;
130
target_ave_dev
=
deviation
;
131
}
132
133
CPUTicker
__fastcall
operator
-(
const
CPUTicker
&)
const
;
134
135
private
:
136
const
CPUCountFn
counter
;
137
unsigned
__int64
TickCount
;
138
139
// Note: deviation and frequency are undefined until calculated,
140
// as we have no idea what they should be.
141
double
deviation
;
142
double
freq
;
143
144
static
bool
__fastcall
HasRDTSC
(
void
)
noexcept
(
true
);
145
static
bool
__fastcall
InterruptsOK
(
void
)
noexcept
(
true
);
146
};
147
148
} }
experimental
NT-based
NTSpecific
CPUTicker
CPUTicker.hpp
Generated on Tue May 11 2021 17:21:34 for libjmmcg by
1.9.2