Fix public issue #30: Stop using gettimeofday() altogether on Win32,

as MSVC doesn't include it. Replace with QueryPerformanceCounter(),
which is monotonic and probably reasonably high-resolution.
(Some machines have traditionally had bugs in QPC, but they should
be relatively rare these days, and there's really no much better
alternative that I know of.)

R=csilvers
DELTA=74  (55 added, 19 deleted, 0 changed)


Revision created by MOE tool push_codebase.
MOE_MIGRATION=1556


git-svn-id: https://snappy.googlecode.com/svn/trunk@31 03e5f5b5-db94-4691-08a0-1a8bf15f6143
This commit is contained in:
snappy.mirrorbot@gmail.com 2011-04-26 12:34:55 +00:00
parent 3d8e71df8d
commit 84d9f64202
2 changed files with 45 additions and 9 deletions

View File

@ -74,21 +74,22 @@ void ResetBenchmarkTiming() {
benchmark_cpu_time_us = 0; benchmark_cpu_time_us = 0;
} }
struct timeval benchmark_start_real;
#ifdef WIN32 #ifdef WIN32
LARGE_INTEGER benchmark_start_real;
FILETIME benchmark_start_cpu; FILETIME benchmark_start_cpu;
#else // WIN32 #else // WIN32
struct timeval benchmark_start_real;
struct rusage benchmark_start_cpu; struct rusage benchmark_start_cpu;
#endif // WIN32 #endif // WIN32
void StartBenchmarkTiming() { void StartBenchmarkTiming() {
gettimeofday(&benchmark_start_real, NULL);
#ifdef WIN32 #ifdef WIN32
QueryPerformanceCounter(&benchmark_start_real);
FILETIME dummy; FILETIME dummy;
CHECK(GetProcessTimes( CHECK(GetProcessTimes(
GetCurrentProcess(), &dummy, &dummy, &dummy, &benchmark_start_cpu)); GetCurrentProcess(), &dummy, &dummy, &dummy, &benchmark_start_cpu));
#else #else
gettimeofday(&benchmark_start_real, NULL);
if (getrusage(RUSAGE_SELF, &benchmark_start_cpu) == -1) { if (getrusage(RUSAGE_SELF, &benchmark_start_cpu) == -1) {
perror("getrusage(RUSAGE_SELF)"); perror("getrusage(RUSAGE_SELF)");
exit(1); exit(1);
@ -101,14 +102,18 @@ void StopBenchmarkTiming() {
if (!benchmark_running) { if (!benchmark_running) {
return; return;
} }
struct timeval benchmark_stop_real;
gettimeofday(&benchmark_stop_real, NULL);
benchmark_real_time_us +=
1000000 * (benchmark_stop_real.tv_sec - benchmark_start_real.tv_sec);
benchmark_real_time_us +=
(benchmark_stop_real.tv_usec - benchmark_start_real.tv_usec);
#ifdef WIN32 #ifdef WIN32
LARGE_INTEGER benchmark_stop_real;
LARGE_INTEGER benchmark_frequency;
QueryPerformanceCounter(&benchmark_stop_real);
QueryPerformanceFrequency(&benchmark_frequency);
double elapsed_real = static_cast<double>(
benchmark_stop_real.QuadPart - benchmark_start_real.QuadPart) /
benchmark_frequency.QuadPart;
benchmark_real_time_us += elapsed_real * 1e6 + 0.5;
FILETIME benchmark_stop_cpu, dummy; FILETIME benchmark_stop_cpu, dummy;
CHECK(GetProcessTimes( CHECK(GetProcessTimes(
GetCurrentProcess(), &dummy, &dummy, &dummy, &benchmark_stop_cpu)); GetCurrentProcess(), &dummy, &dummy, &dummy, &benchmark_stop_cpu));
@ -124,6 +129,13 @@ void StopBenchmarkTiming() {
benchmark_cpu_time_us += benchmark_cpu_time_us +=
(stop_ulargeint.QuadPart - start_ulargeint.QuadPart + 5) / 10; (stop_ulargeint.QuadPart - start_ulargeint.QuadPart + 5) / 10;
#else // WIN32 #else // WIN32
struct timeval benchmark_stop_real;
gettimeofday(&benchmark_stop_real, NULL);
benchmark_real_time_us +=
1000000 * (benchmark_stop_real.tv_sec - benchmark_start_real.tv_sec);
benchmark_real_time_us +=
(benchmark_stop_real.tv_usec - benchmark_start_real.tv_usec);
struct rusage benchmark_stop_cpu; struct rusage benchmark_stop_cpu;
if (getrusage(RUSAGE_SELF, &benchmark_stop_cpu) == -1) { if (getrusage(RUSAGE_SELF, &benchmark_stop_cpu) == -1) {
perror("getrusage(RUSAGE_SELF)"); perror("getrusage(RUSAGE_SELF)");

View File

@ -46,6 +46,11 @@
#include <sys/time.h> #include <sys/time.h>
#ifdef HAVE_WINDOWS_H
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif
#include <string> #include <string>
#ifdef HAVE_GTEST #ifdef HAVE_GTEST
@ -241,15 +246,30 @@ class CycleTimer {
CycleTimer() : real_time_us_(0) {} CycleTimer() : real_time_us_(0) {}
void Start() { void Start() {
#ifdef WIN32
QueryPerformanceCounter(&start_);
#else
gettimeofday(&start_, NULL); gettimeofday(&start_, NULL);
#endif
} }
void Stop() { void Stop() {
#ifdef WIN32
LARGE_INTEGER stop;
LARGE_INTEGER frequency;
QueryPerformanceCounter(&stop);
QueryPerformanceFrequency(&frequency);
double elapsed = static_cast<double>(stop.QuadPart - start_.QuadPart) /
frequency.QuadPart;
real_time_us_ += elapsed * 1e6 + 0.5;
#else
struct timeval stop; struct timeval stop;
gettimeofday(&stop, NULL); gettimeofday(&stop, NULL);
real_time_us_ += 1000000 * (stop.tv_sec - start_.tv_sec); real_time_us_ += 1000000 * (stop.tv_sec - start_.tv_sec);
real_time_us_ += (stop.tv_usec - start_.tv_usec); real_time_us_ += (stop.tv_usec - start_.tv_usec);
#endif
} }
double Get() { double Get() {
@ -258,7 +278,11 @@ class CycleTimer {
private: private:
int64 real_time_us_; int64 real_time_us_;
#ifdef WIN32
LARGE_INTEGER start_;
#else
struct timeval start_; struct timeval start_;
#endif
}; };
// Minimalistic microbenchmark framework. // Minimalistic microbenchmark framework.