Skip to content

Commit

Permalink
consolidate timer functions
Browse files Browse the repository at this point in the history
  • Loading branch information
EricWF committed Sep 2, 2016
1 parent ebae4a7 commit fb608df
Show file tree
Hide file tree
Showing 10 changed files with 76 additions and 350 deletions.
8 changes: 3 additions & 5 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,18 @@ endif()

# Define the source files
set(SOURCE_FILES "benchmark.cc" "colorprint.cc" "commandlineflags.cc"
"console_reporter.cc" "cpu_thread_time.cc" "csv_reporter.cc"
"console_reporter.cc" "csv_reporter.cc"
"json_reporter.cc" "reporter.cc" "sleep.cc"
"string_util.cc" "sysinfo.cc" "walltime.cc" "complexity.cc")
"string_util.cc" "sysinfo.cc" "complexity.cc" "timers.cc")
# Add headers to the list of source files. cmake does not require this,
# but IDEs such as Visual Studio need this to add the headers
# to the generated project.
set(_d "${PROJECT_SOURCE_DIR}/include/benchmark")
list(APPEND SOURCE_FILES "${_d}/benchmark.h" "${_d}/benchmark_api.h"
"${_d}/macros.h" "${_d}/reporter.h" "arraysize.h" "check.h"
"colorprint.h" "commandlineflags.h" "complexity.h"
"cpu_thread_time.h"
"cycleclock.h" "internal_macros.h" "log.h" "mutex.h"
"re.h" "sleep.h" "stat.h" "string_util.h" "sysinfo.h"
"walltime.h")
"re.h" "sleep.h" "stat.h" "string_util.h" "sysinfo.h" "timers.h")
unset(_d)

# Determine the correct regular expression engine to use
Expand Down
14 changes: 3 additions & 11 deletions src/benchmark.cc
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,13 @@
#include "check.h"
#include "commandlineflags.h"
#include "complexity.h"
#include "cpu_thread_time.h"
#include "log.h"
#include "mutex.h"
#include "re.h"
#include "stat.h"
#include "string_util.h"
#include "sysinfo.h"
#include "walltime.h"
#include "timers.h"

DEFINE_bool(benchmark_list_tests, false,
"Print a list of benchmarks. This option overrides all other "
Expand Down Expand Up @@ -184,16 +183,15 @@ class ThreadTimer {
// Called by each thread
void StartTimer() {
running_ = true;
start_real_time_ = walltime::ChronoClockNow();
start_real_time_ = ChronoClockNow();
start_cpu_time_ = ThreadCPUUsage();
}

// Called by each thread
void StopTimer() {
CHECK(running_);

running_ = false;
real_time_used_ += walltime::ChronoClockNow() - start_real_time_;
real_time_used_ += ChronoClockNow() - start_real_time_;
cpu_time_used_ += ThreadCPUUsage() - start_cpu_time_;
}

Expand Down Expand Up @@ -1155,12 +1153,6 @@ int InitializeStreams() {
void Initialize(int* argc, char** argv) {
internal::ParseCommandLineFlags(argc, argv);
internal::LogLevel() = FLAGS_v;
// TODO remove this. It prints some output the first time it is called.
// We don't want to have this ouput printed during benchmarking.
ProcessCPUUsage();
// The first call to walltime::Now initialized it. Call it once to
// prevent the initialization from happening in a benchmark.
walltime::Now();
}

} // end namespace benchmark
2 changes: 1 addition & 1 deletion src/console_reporter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
#include "commandlineflags.h"
#include "internal_macros.h"
#include "string_util.h"
#include "walltime.h"
#include "timers.h"

namespace benchmark {

Expand Down
10 changes: 0 additions & 10 deletions src/cpu_thread_time.h

This file was deleted.

2 changes: 1 addition & 1 deletion src/csv_reporter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
#include <vector>

#include "string_util.h"
#include "walltime.h"
#include "timers.h"

// File format reference: http://edoceo.com/utilitas/csv-file-format.

Expand Down
2 changes: 1 addition & 1 deletion src/json_reporter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
#include <vector>

#include "string_util.h"
#include "walltime.h"
#include "timers.h"

namespace benchmark {

Expand Down
2 changes: 1 addition & 1 deletion src/reporter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
// limitations under the License.

#include "benchmark/reporter.h"
#include "walltime.h"
#include "timers.h"

#include <cstdlib>

Expand Down
120 changes: 54 additions & 66 deletions src/cpu_thread_time.cc → src/timers.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cpu_thread_time.h"
#include "timers.h"
#include "internal_macros.h"

#ifdef BENCHMARK_OS_WINDOWS
Expand Down Expand Up @@ -51,7 +51,6 @@

namespace benchmark {
namespace {
std::mutex cputimens_mutex;

#if defined(BENCHMARK_OS_WINDOWS)
double MakeTime(FILETIME const& kernel_time, FILETIME const& user_time) {
Expand Down Expand Up @@ -86,61 +85,44 @@ double MakeTime(thread_basic_info_data_t const& info) {

} // end namespace

// getrusage() based implementation of MyCPUUsage
static double ProcessCPURUsage() {
double ProcessCPUUsage() {
#if defined(_POSIX_CPUTIME)
struct timespec spec;
if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &spec) == 0) {
return MakeTime(spec);
}
return 0.0;
#elif !defined(BENCHMARK_OS_WINDOWS)
struct rusage ru;
if (getrusage(RUSAGE_SELF, &ru) == 0) {
return MakeTime(ru);
}
return 0.0;
#else
#elif defined(BENCHMARK_OS_WINDOWS)
HANDLE proc = GetCurrentProcess();
FILETIME creation_time;
FILETIME exit_time;
FILETIME kernel_time;
FILETIME user_time;
GetProcessTimes(proc, &creation_time, &exit_time, &kernel_time, &user_time);
return MakeTime(kernel_time, user_time);
#endif // OS_WINDOWS
#else
struct rusage ru;
if (getrusage(RUSAGE_SELF, &ru) == 0) {
return MakeTime(ru);
}
return 0.0;
#endif
}

double ChildrenCPUUsage() {
#ifndef BENCHMARK_OS_WINDOWS
static bool MyCPUUsageCPUTimeNsLocked(double* cputime) {
static int cputime_fd = -1;
if (cputime_fd == -1) {
cputime_fd = open("/proc/self/cputime_ns", O_RDONLY);
if (cputime_fd < 0) {
cputime_fd = -1;
return false;
}
}
char buff[64];
memset(buff, 0, sizeof(buff));
if (pread(cputime_fd, buff, sizeof(buff) - 1, 0) <= 0) {
close(cputime_fd);
cputime_fd = -1;
return false;
}
unsigned long long result = strtoull(buff, nullptr, 0);
if (result == (std::numeric_limits<unsigned long long>::max)()) {
close(cputime_fd);
cputime_fd = -1;
return false;
struct rusage ru;
if (getrusage(RUSAGE_CHILDREN, &ru) == 0) {
return MakeTime(ru);
} else {
return 0.0;
}
*cputime = static_cast<double>(result) / 1e9;
return true;
#else
// TODO: Not sure what this even means on Windows
return 0.0;
#endif // BENCHMARK_OS_WINDOWS
}

#endif // OS_WINDOWS


double ThreadCPUUsage() {
#if defined(_POSIX_THREAD_CPUTIME)
struct timespec ts;
Expand All @@ -165,37 +147,43 @@ double ThreadCPUUsage() {
#endif
}

double ProcessCPUUsage() {
#ifndef BENCHMARK_OS_WINDOWS
{
std::lock_guard<std::mutex> l(cputimens_mutex);
static bool use_cputime_ns = true;
if (use_cputime_ns) {
double value;
if (MyCPUUsageCPUTimeNsLocked(&value)) {
return value;
}
// Once MyCPUUsageCPUTimeNsLocked fails once fall back to getrusage().
VLOG(1) << "Reading /proc/self/cputime_ns failed. Using getrusage().\n";
use_cputime_ns = false;
}
}
#endif // OS_WINDOWS
return ProcessCPURUsage();
}
namespace {

double ChildrenCPUUsage() {
#ifndef BENCHMARK_OS_WINDOWS
struct rusage ru;
if (getrusage(RUSAGE_CHILDREN, &ru) == 0) {
return MakeTime(ru);
std::string DateTimeString(bool local) {
typedef std::chrono::system_clock Clock;
std::time_t now = Clock::to_time_t(Clock::now());
const std::size_t kStorageSize = 128;
char storage[kStorageSize];
std::size_t written;

if (local) {
#if defined(BENCHMARK_OS_WINDOWS)
written = std::strftime(storage, sizeof(storage), "%x %X", ::localtime(&now));
#else
std::tm timeinfo;
std::memset(&timeinfo, 0, sizeof(std::tm));
::localtime_r(&now, &timeinfo);
written = std::strftime(storage, sizeof(storage), "%F %T", &timeinfo);
#endif
} else {
return 0.0;
}
#if defined(BENCHMARK_OS_WINDOWS)
written = std::strftime(storage, sizeof(storage), "%x %X", ::gmtime(&now));
#else
// TODO: Not sure what this even means on Windows
return 0.0;
#endif // OS_WINDOWS
std::tm timeinfo;
std::memset(&timeinfo, 0, sizeof(std::tm));
::gmtime_r(&now, &timeinfo);
written = std::strftime(storage, sizeof(storage), "%F %T", &timeinfo);
#endif
}
CHECK(written < kStorageSize);
((void)written); // prevent unused variable in optimized mode.
return std::string(storage);
}

} // end namespace

std::string LocalDateTimeString() {
return DateTimeString(true);
}

} // end namespace benchmark
22 changes: 12 additions & 10 deletions src/walltime.h → src/timers.h
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
#ifndef BENCHMARK_WALLTIME_H_
#define BENCHMARK_WALLTIME_H_

#include "internal_macros.h"
#ifndef BENCHMARK_TIMERS_H
#define BENCHMARK_TIMERS_H

#include <chrono>
#include <string>

namespace benchmark {
typedef double WallTime;

namespace walltime {
// Return the CPU usage of the current process
double ProcessCPUUsage();

// Return the CPU usage of the children of the current process
double ChildrenCPUUsage();

// Return the CPU usage of the current thread
double ThreadCPUUsage();


#if defined(HAVE_STEADY_CLOCK)
template <bool HighResIsSteady = std::chrono::high_resolution_clock::is_steady>
Expand Down Expand Up @@ -38,11 +43,8 @@ inline double ChronoClockNow() {
return FpSeconds(ClockType::now().time_since_epoch()).count();
}

WallTime Now();
} // end namespace walltime

std::string LocalDateTimeString();

} // end namespace benchmark

#endif // BENCHMARK_WALLTIME_H_
#endif // BENCHMARK_TIMERS_H
Loading

0 comments on commit fb608df

Please sign in to comment.