[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lmi-commits] [lmi] master 8e64944 4/4: Change timer class's internal ti
From: |
Greg Chicares |
Subject: |
[lmi-commits] [lmi] master 8e64944 4/4: Change timer class's internal time type |
Date: |
Mon, 28 May 2018 20:45:40 -0400 (EDT) |
branch: master
commit 8e649447064939f32467d865978c9941a3d54a6c
Author: Gregory W. Chicares <address@hidden>
Commit: Gregory W. Chicares <address@hidden>
Change timer class's internal time type
Rationale: see (removed) excerpt from glibc documentation.
---
timer.cpp | 50 +++++++++++++++++++++++++++-----------------------
timer.hpp | 51 ++++++++++++++-------------------------------------
timer_test.cpp | 4 ++--
3 files changed, 43 insertions(+), 62 deletions(-)
diff --git a/timer.cpp b/timer.cpp
index 33d40af..6182a47 100644
--- a/timer.cpp
+++ b/timer.cpp
@@ -23,7 +23,9 @@
#include "timer.hpp"
-#if defined LMI_MSW
+#if defined LMI_POSIX
+# include <sys/time.h> // gettimeofday()
+#elif defined LMI_MSW
// TRICKY !! There being no standard way to ascertain whether
// <windows.h> has been included, we resort to this hack:
# if defined STDCALL || defined WM_COMMAND
@@ -37,14 +39,18 @@
// increase compile times for small programs, and because it requires
// ms extensions and defines many macros.
# if !defined LMI_MS_HEADER_INCLUDED
- // These declarations would be erroneous if the ms headers were
- // included. It's necessary to guard against that explicitly,
- // because those headers might be implicitly included by a pch
- // mechanism.
- extern "C" int __stdcall QueryPerformanceCounter(elapsed_t*);
- extern "C" int __stdcall QueryPerformanceFrequency(elapsed_t*);
+# include <cstdint>
+ typedef std::uint64_t msw_elapsed_t;
+ // These declarations would be erroneous if the ms headers were
+ // included. It's necessary to guard against that explicitly,
+ // because those headers might be implicitly included by a pch
+ // mechanism.
+ extern "C" int __stdcall QueryPerformanceCounter (msw_elapsed_t*);
+ extern "C" int __stdcall QueryPerformanceFrequency(msw_elapsed_t*);
# endif // !defined LMI_MS_HEADER_INCLUDED
-#endif // defined LMI_MSW
+#else // Unknown platform.
+# include <ctime> // clock()
+#endif // Unknown platform.
/// Suspend execution for a given number of seconds.
@@ -128,8 +134,6 @@ std::string Timer::elapsed_msec_str() const
/// - Timer must have been stopped; throws if it is still running.
/// - frequency_ must be nonzero (guaranteed by ctor), so that
/// dividing by it is safe.
-///
-/// The static_casts are necessary in case elapsed_t is integral.
double Timer::elapsed_seconds() const
{
@@ -140,27 +144,27 @@ double Timer::elapsed_seconds() const
);
}
- return static_cast<double>(elapsed_time_) /
static_cast<double>(frequency_);
+ return elapsed_time_ / frequency_;
}
/// Ascertain timer frequency in ticks per second.
-elapsed_t Timer::calibrate()
+double Timer::calibrate()
{
#if defined LMI_POSIX
- return 1000000;
+ return 1000000.0;
#elif defined LMI_MSW
# if defined LMI_MS_HEADER_INCLUDED
LARGE_INTEGER z;
QueryPerformanceFrequency(&z);
- return z.QuadPart;
+ return static_cast<double>(z.QuadPart);
# else // !defined LMI_MS_HEADER_INCLUDED
- elapsed_t z;
+ msw_elapsed_t z;
QueryPerformanceFrequency(&z);
- return z;
+ return static_cast<double>(z);
# endif // !defined LMI_MS_HEADER_INCLUDED
#else // Unknown platform.
- return CLOCKS_PER_SEC;
+ return static_cast<double>(CLOCKS_PER_SEC);
#endif // Unknown platform.
}
@@ -181,24 +185,24 @@ void Timer::start()
/// Ticks elapsed since timer started.
-elapsed_t Timer::inspect() const
+double Timer::inspect() const
{
#if defined LMI_POSIX
timeval x;
gettimeofday(&x, nullptr);
- return elapsed_t(1000000) * x.tv_sec + x.tv_usec;
+ return x.tv_usec + 1000000.0 * x.tv_sec;
#elif defined LMI_MSW
# if defined LMI_MS_HEADER_INCLUDED
LARGE_INTEGER z;
QueryPerformanceCounter(&z);
- return z.QuadPart;
+ return static_cast<double>(z.QuadPart);
# else // !defined LMI_MS_HEADER_INCLUDED
- elapsed_t z;
+ msw_elapsed_t z;
QueryPerformanceCounter(&z);
- return z;
+ return static_cast<double>(z);
# endif // !defined LMI_MS_HEADER_INCLUDED
#else // Unknown platform.
- return std::clock();
+ return static_cast<double>(std::clock());
#endif // Unknown platform.
}
diff --git a/timer.hpp b/timer.hpp
index 9261995..ab3cd27 100644
--- a/timer.hpp
+++ b/timer.hpp
@@ -26,20 +26,6 @@
#include "so_attributes.hpp"
-#if defined LMI_POSIX
-# include <sys/time.h> // gettimeofday()
- typedef double elapsed_t;
-#elif defined LMI_MSW
- // Compilers for this platform use various types for its high-
- // resolution timer, but they use the same platform API, so
- // it's sufficient to use the same 64-bit integer type for all.
-# include <cstdint>
- typedef std::uint64_t elapsed_t;
-#else // Unknown platform.
-# include <ctime>
- typedef std::clock_t elapsed_t;
-#endif // Unknown platform.
-
#include <iomanip>
#include <ios>
#include <ostream>
@@ -57,15 +43,6 @@ void lmi_sleep(unsigned int seconds);
/// and that latency is a significant concern. This class uses a high-
/// resolution timer if available; it's a sharp tool that lets you
/// make your own decision about that rationale.
-///
-/// SOMEDAY !! Following the glibc guidance below, replace elapsed_t
-/// with double in the interface and the implementation.
-///
-///
http://www.gnu.org/software/libc/manual/html_node/Processor-And-CPU-Time.html
-/// "clock_t and ... CLOCKS_PER_SEC can be either integer or floating-point
-/// types. Casting CPU time values to double ... makes sure that operations
-/// such as arithmetic and printing work properly and consistently no matter
-/// what the underlying representation is."
class LMI_SO Timer
{
@@ -76,8 +53,8 @@ class LMI_SO Timer
Timer();
~Timer() = default;
- Timer& restart();
- Timer& stop();
+ Timer& restart();
+ Timer& stop();
static std::string elapsed_msec_str(double seconds);
std::string elapsed_msec_str() const;
@@ -87,16 +64,16 @@ class LMI_SO Timer
Timer(Timer const&) = delete;
Timer& operator=(Timer const&) = delete;
- elapsed_t calibrate();
- void start();
+ double calibrate();
+ void start();
- elapsed_t inspect() const;
+ double inspect() const;
- elapsed_t elapsed_time_;
- elapsed_t frequency_;
- bool is_running_;
- elapsed_t time_when_started_;
- elapsed_t time_when_stopped_;
+ double elapsed_time_;
+ double frequency_;
+ bool is_running_;
+ double time_when_started_;
+ double time_when_stopped_;
};
/// Time an operation over an actively-adjusted number of repetitions.
@@ -173,7 +150,7 @@ AliquotTimer<F>::AliquotTimer(F f, double max_seconds)
,max_seconds_(max_seconds)
{
Timer timer;
- if(max_seconds_ * static_cast<double>(timer.frequency_) < 1.0)
+ if(max_seconds_ * timer.frequency_ < 1.0)
{
std::ostringstream oss;
oss
@@ -213,9 +190,9 @@ AliquotTimer<F>& AliquotTimer<F>::operator()()
}
Timer timer;
- double const dbl_freq = static_cast<double>(timer.frequency_);
+ double const dbl_freq = timer.frequency_;
double const limit = max_seconds_ * dbl_freq;
- double const start_time = static_cast<double>(timer.time_when_started_);
+ double const start_time = timer.time_when_started_;
double const expiry_min = start_time + 0.01 * limit;
double const expiry_max = start_time + limit;
double now = start_time;
@@ -226,7 +203,7 @@ AliquotTimer<F>& AliquotTimer<F>::operator()()
{
f_();
previous = now;
- now = static_cast<double>(timer.inspect());
+ now = timer.inspect();
if(now - previous < minimum)
{
minimum = now - previous;
diff --git a/timer_test.cpp b/timer_test.cpp
index e94fb51..729c82e 100644
--- a/timer_test.cpp
+++ b/timer_test.cpp
@@ -27,7 +27,7 @@
#include "miscellany.hpp"
#include "test_tools.hpp"
-#include <cmath>
+#include <cmath> // log10()
#include <functional> // bind()
inline void do_nothing()
@@ -64,7 +64,7 @@ struct TimerTest
void TimerTest::WaitTenMsec()
{
Timer timer;
- double limit = 0.01 * static_cast<double>(timer.frequency_);
+ double limit = 0.01 * timer.frequency_;
for(;timer.inspect() - timer.time_when_started_ <= limit;) {}
}