1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
|
// 2009 © Václav Šmilauer <eudoxos@arcig.cz>
#pragma once
#include <time.h>
namespace yade { // Cannot have #include directive inside.
struct TimingInfo {
typedef unsigned long long delta;
long nExec;
delta nsec;
TimingInfo()
: nExec(0)
, nsec(0)
{
}
static delta getNow(bool evenIfDisabled = false)
{
if (!enabled && !evenIfDisabled) return 0L;
#ifdef __APPLE__
std::cerr << "ERROR: Time profiling (TimingInfo) not implemented on Apples." << std::endl;
return 0L;
#else
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return delta(1e9 * ts.tv_sec + ts.tv_nsec);
#endif
}
static bool enabled;
};
/* Create TimingDeltas object, then every call to checkpoint() will add
* (or use existing) TimingInfo to data. It increases its nExec by 1
* and nsec by time elapsed since construction or last checkpoint.
*/
class TimingDeltas {
TimingInfo::delta last;
size_t i;
public:
vector<TimingInfo> data;
vector<string> labels;
TimingDeltas()
: i(0)
{
}
void start()
{
if (!TimingInfo::enabled) return;
i = 0;
last = TimingInfo::getNow();
}
void checkpoint(const string& label)
{
if (!TimingInfo::enabled) return;
if (data.size() <= i) {
data.resize(i + 1);
labels.resize(i + 1);
labels[i] = label;
}
TimingInfo::delta now = TimingInfo::getNow();
data[i].nExec += 1;
data[i].nsec += now - last;
last = now;
i++;
}
void reset()
{
data.clear();
labels.clear();
}
// python access
boost::python::list pyData()
{
boost::python::list ret;
for (size_t i2 = 0; i2 < data.size(); i2++) {
ret.append(boost::python::make_tuple(labels[i2], data[i2].nsec, data[i2].nExec));
}
return ret;
}
};
} // namespace yade
|