Subversion Repositories Games.Chess Giants

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
99 pmbaty 1
/*
2
    Texel - A UCI chess engine.
3
    Copyright (C) 2013  Peter Ă–sterlund, peterosterlund2@gmail.com
4
 
5
    This program is free software: you can redistribute it and/or modify
6
    it under the terms of the GNU General Public License as published by
7
    the Free Software Foundation, either version 3 of the License, or
8
    (at your option) any later version.
9
 
10
    This program is distributed in the hope that it will be useful,
11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
    GNU General Public License for more details.
14
 
15
    You should have received a copy of the GNU General Public License
16
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
*/
18
 
19
/*
20
 * timeUtil.hpp
21
 *
22
 *  Created on: Sep 20, 2013
23
 *      Author: petero
24
 */
25
 
26
#ifndef TIMEUTIL_HPP_
27
#define TIMEUTIL_HPP_
28
 
29
#include "util.hpp"
30
 
31
#include <array>
32
#include <cmath>
33
#include <cassert>
34
 
35
 
36
/** Return current wall clock time in milliseconds, starting at some arbitrary point in time. */
37
S64 currentTimeMillis();
38
 
39
/** Return current wall clock time in seconds, starting at some arbitrary point in time. */
40
double currentTime();
41
 
42
 
43
 
44
/** Class that measures average CPU utilization. */
45
class UtilizationTimer {
46
public:
47
    /** Constructor. All times start at zero. */
48
    UtilizationTimer();
49
 
50
    /** Reset times to zero. */
51
    void reset();
52
 
53
    /** Set the current CPU efficiency factor to p.
54
     * A negative p indicates the CPU is idle. */
55
    void setPUseful(double p);
56
 
57
    /** Return elapsed time size last reset, the amount of useful time spent,
58
     * and the amount of time the CPU has been idle. */
59
    void getStats(double& elapsed, double& useful, double& sleep);
60
 
61
private:
62
    /** Update tElapsed, tUseful, tSleep and increase t0 to current time. */
63
    void update();
64
 
65
    double t0;          // Time stand for last update()
66
    double pUseful;     // Current CPU efficiency factor
67
 
68
    double tElapsed;    // Total elapsed time since reset()
69
    double tUseful;     // Total spent useful time
70
    double tSleep;      // total idle time.
71
};
72
 
73
/** Class that tracks statistics for a set of samples. */
74
class SampleStatistics {
75
public:
76
    /** Constructor. */
77
    SampleStatistics();
78
 
79
    /** Remove all samples. */
80
    void reset();
81
 
82
    /** Add a sample. */
83
    void addSample(double value);
84
 
85
    /** Return number of samples. */
86
    int numSamples() const;
87
    /** Return average sample value. */
88
    double avg() const;
89
    /** Return standard deviation of samples. */
90
    double std() const;
91
 
92
    /** Add other to *this. */
93
    SampleStatistics& operator+=(const SampleStatistics& other);
94
 
95
private:
96
    int nSamples;
97
    double sum;
98
    double sqSum;
99
};
100
 
101
/** Gather statistics about time samples. */
102
class TimeSampleStatistics {
103
public:
104
    /** Constructor. */
105
    TimeSampleStatistics();
106
 
107
    /** Start timer. */
108
    void start();
109
 
110
    /** Stop timer and add elapsed time as a sample. */
111
    void stop();
112
 
113
    /** Remove all time samples. */
114
    void reset();
115
 
116
    /** Return true if timer is currently running. */
117
    bool isStarted() const;
118
 
119
    /** Return number of time samples. */
120
    int numSamples() const;
121
    /** Return average sample time. */
122
    double avg() const;
123
    /** Return standard deviation of time samples. */
124
    double std() const;
125
 
126
    /** Print to "os", time values displayed in nanoseconds. */
127
    void printNs(std::ostream& os) const;
128
 
129
private:
130
    double t0;
131
    bool started;
132
    SampleStatistics stats;
133
};
134
 
135
/** A fixed size vector of TimeSampleStatistics objects. */
136
template <int N>
137
class TimeSampleStatisticsVector {
138
private:
139
    std::array<TimeSampleStatistics, N> vec;
140
 
141
public:
142
    TimeSampleStatistics& operator[](int i);
143
 
144
    using iterator = typename std::array<TimeSampleStatistics, N>::iterator;
145
    iterator begin();
146
    iterator end();
147
};
148
 
149
/** Utility function to add a time sample to a TimeSampleStatistics object.
150
 * The sample value is equal to the amount of time this object is in scope. */
151
class ScopedTimeSample {
152
public:
153
    ScopedTimeSample(TimeSampleStatistics& tStat);
154
    ~ScopedTimeSample();
155
    ScopedTimeSample(ScopedTimeSample&) = delete;
156
    ScopedTimeSample& operator=(const ScopedTimeSample&) = delete;
157
private:
158
    TimeSampleStatistics& timeStat;
159
};
160
 
161
 
162
inline
163
UtilizationTimer::UtilizationTimer() {
164
    reset();
165
}
166
 
167
inline void
168
UtilizationTimer::reset() {
169
    t0 = currentTime();
170
    pUseful = -1;
171
    tElapsed = 0;
172
    tUseful = 0;
173
    tSleep = 0;
174
}
175
 
176
inline void
177
UtilizationTimer::setPUseful(double p) {
178
    update();
179
    pUseful = p;
180
}
181
 
182
inline void
183
UtilizationTimer::getStats(double& elapsed, double& useful, double& sleep) {
184
    update();
185
    elapsed = tElapsed;
186
    useful = tUseful;
187
    sleep = tSleep;
188
}
189
 
190
inline void
191
UtilizationTimer::update() {
192
    double tNow = currentTime();
193
    double dt = tNow - t0;
194
    tElapsed += dt;
195
    if (pUseful >= 0)
196
        tUseful += dt * pUseful;
197
    else
198
        tSleep += dt;
199
    t0 = tNow;
200
}
201
 
202
 
203
inline
204
SampleStatistics::SampleStatistics() {
205
    reset();
206
}
207
 
208
inline void
209
SampleStatistics::reset() {
210
    nSamples = 0;
211
    sum = 0.0;
212
    sqSum = 0.0;
213
}
214
 
215
inline void
216
SampleStatistics::addSample(double value) {
217
    nSamples++;
218
    sum += value;
219
    sqSum += value * value;
220
}
221
 
222
inline int
223
SampleStatistics::numSamples() const {
224
    return nSamples;
225
}
226
 
227
inline double
228
SampleStatistics::avg() const {
229
    return nSamples > 0 ? sum / nSamples : 0;
230
}
231
 
232
inline double
233
SampleStatistics::std() const {
234
    if (nSamples < 2)
235
        return 0;
236
    return ::sqrt((sqSum - sum*sum / nSamples) / (nSamples - 1));
237
}
238
 
239
inline void
240
TimeSampleStatistics::printNs(std::ostream& os) const {
241
    os << numSamples()
242
       << ' ' << static_cast<int>(avg() * 1e9)
243
       << ' ' << static_cast<int>(std() * 1e9);
244
}
245
 
246
 
247
inline
248
TimeSampleStatistics::TimeSampleStatistics() {
249
    reset();
250
}
251
 
252
inline void
253
TimeSampleStatistics::start() {
254
    t0 = currentTime();
255
    started = true;
256
}
257
 
258
inline void
259
TimeSampleStatistics::stop() {
260
    double now = currentTime();
261
    stats.addSample(now - t0);
262
    started = false;
263
}
264
 
265
inline void
266
TimeSampleStatistics::reset() {
267
    stats.reset();
268
    started = false;
269
}
270
 
271
inline bool
272
TimeSampleStatistics::isStarted() const {
273
    return started;
274
}
275
 
276
inline int
277
TimeSampleStatistics::numSamples() const {
278
    return stats.numSamples();
279
}
280
 
281
inline double
282
TimeSampleStatistics::avg() const {
283
    return stats.avg();
284
}
285
 
286
inline double
287
TimeSampleStatistics::std() const {
288
    return stats.std();
289
}
290
 
291
template <int N>
292
inline TimeSampleStatistics&
293
TimeSampleStatisticsVector<N>::operator[](int i) {
294
    return vec[i];
295
}
296
 
297
template <int N>
298
inline typename TimeSampleStatisticsVector<N>::iterator
299
TimeSampleStatisticsVector<N>::begin() {
300
    return vec.begin();
301
}
302
 
303
template <int N>
304
inline typename TimeSampleStatisticsVector<N>::iterator
305
TimeSampleStatisticsVector<N>::end() {
306
    return vec.end();
307
}
308
 
309
 
310
inline
311
ScopedTimeSample::ScopedTimeSample(TimeSampleStatistics& tStat)
312
  : timeStat(tStat) {
313
    assert(!timeStat.isStarted());
314
    timeStat.start();
315
}
316
 
317
inline
318
ScopedTimeSample::~ScopedTimeSample() {
319
    assert(timeStat.isStarted());
320
    timeStat.stop();
321
}
322
 
323
 
324
#endif /* TIMEUTIL_HPP_ */