#ifndef ZTIMER_H_
#define ZTIMER_H_
#include "common.h"
namespace FastPForLib {
#ifdef _WIN32
#define NOMINMAX
#define WINDOWS_LEAN_AND_MEAN
#include <windows.h>
struct qpc_clock {
typedef std::chrono::nanoseconds duration;
typedef duration::rep rep;
typedef duration::period period;
typedef std::chrono::time_point<qpc_clock, duration> time_point;
static time_point now() {
static bool isInited = false;
static LARGE_INTEGER frequency = {{0, 0}};
if (!isInited) {
if (QueryPerformanceFrequency(&frequency) == 0) {
throw std::logic_error("QueryPerformanceCounter not supported: " +
std::to_string(GetLastError()));
}
isInited = true;
}
LARGE_INTEGER counter;
QueryPerformanceCounter(&counter);
return time_point(duration(static_cast<rep>((double)counter.QuadPart /
frequency.QuadPart *
period::den / period::num)));
}
};
#endif
class WallClockTimer {
public:
#ifdef _WIN32
typedef qpc_clock clock;
#else
typedef std::chrono::high_resolution_clock clock;
#endif
std::chrono::time_point<clock> t1, t2;
WallClockTimer() : t1(), t2() {
t1 = clock::now();
t2 = t1;
}
void reset() {
t1 = clock::now();
t2 = t1;
}
uint64_t elapsed() {
std::chrono::microseconds delta =
std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1);
return delta.count();
}
uint64_t split() {
t2 = clock::now();
return elapsed();
}
};
#ifndef _WIN32
class CPUTimer {
public:
struct rusage t1, t2;
CPUTimer() : t1(), t2() {
getrusage(RUSAGE_SELF, &t1);
t2 = t1;
}
void reset() {
getrusage(RUSAGE_SELF, &t1);
t2 = t1;
}
uint64_t elapsed() { return totalelapsed(); }
uint64_t totalelapsed() { return userelapsed() + systemelapsed(); }
uint64_t userelapsed() {
return ((t2.ru_utime.tv_sec - t1.ru_utime.tv_sec) * 1000ULL * 1000ULL) +
((t2.ru_utime.tv_usec - t1.ru_utime.tv_usec));
}
uint64_t systemelapsed() {
return ((t2.ru_stime.tv_sec - t1.ru_stime.tv_sec) * 1000ULL * 1000ULL) +
((t2.ru_stime.tv_usec - t1.ru_stime.tv_usec));
}
uint64_t split() {
getrusage(RUSAGE_SELF, &t2);
return elapsed();
}
};
#endif
}
#endif