[mlpack-svn] r15222 - mlpack/trunk/src/mlpack/core/util
fastlab-svn at coffeetalk-1.cc.gatech.edu
fastlab-svn at coffeetalk-1.cc.gatech.edu
Tue Jun 11 12:43:56 EDT 2013
Author: marcus
Date: 2013-06-11 12:43:56 -0400 (Tue, 11 Jun 2013)
New Revision: 15222
Modified:
mlpack/trunk/src/mlpack/core/util/timers.cpp
mlpack/trunk/src/mlpack/core/util/timers.hpp
Log:
Update the timer class, to get stable time values with more accuracy for the common operating systems.
Modified: mlpack/trunk/src/mlpack/core/util/timers.cpp
===================================================================
--- mlpack/trunk/src/mlpack/core/util/timers.cpp 2013-06-11 16:31:08 UTC (rev 15221)
+++ mlpack/trunk/src/mlpack/core/util/timers.cpp 2013-06-11 16:43:56 UTC (rev 15222)
@@ -1,6 +1,7 @@
/**
* @file timers.cpp
* @author Matthew Amidon
+ * @author Marcus Edel
*
* Implementation of timers.
*/
@@ -117,30 +118,111 @@
Log::Info << std::endl;
}
+void Timers::GetTime(timeval* tv)
+{
+#if defined(__MACH__) && defined(__APPLE__)
+
+ static mach_timebase_info_data_t info;
+
+ // If this is the first time we've run, get the timebase.
+ // We can use denom == 0 to indicate that sTimebaseInfo is
+ // uninitialised.
+ if (info.denom == 0) {
+ (void) mach_timebase_info(&info);
+ }
+
+ // Hope that the multiplication doesn't overflow.
+ uint64_t nsecs = mach_absolute_time() * info.numer / info.denom;
+ tv->tv_sec = nsecs / 1e9;
+ tv->tv_usec = (nsecs / 1e3) - (tv->tv_sec * 1e6);
+
+#elif defined(_POSIX_VERSION)
+#if defined(_POSIX_TIMERS) && (_POSIX_TIMERS > 0)
+
+ // Get the right clock_id.
+#if defined(CLOCK_MONOTONIC_PRECISE)
+ static const clockid_t id = CLOCK_MONOTONIC_PRECISE;
+#elif defined(CLOCK_MONOTONIC_RAW)
+ static const clockid_t id = CLOCK_MONOTONIC_RAW;
+#elif defined(CLOCK_MONOTONIC)
+ static const clockid_t id = CLOCK_MONOTONIC;
+#elif defined(CLOCK_REALTIME)
+ static const clockid_t id = CLOCK_REALTIME;
+#else
+ static const clockid_t id = ((clockid_t) - 1);
+#endif // CLOCK
+
+ struct timespec ts;
+
+ // Returns the current value tp for the specified clock_id.
+ if (clock_gettime(id, &ts) != -1 && id != ((clockid_t) - 1))
+ {
+ tv->tv_sec = ts.tv_sec;
+ tv->tv_usec = ts.tv_nsec / 1e3;
+ }
+
+ // Fallback for the clock_gettime function.
+ gettimeofday(tv, NULL);
+
+#endif // _POSIX_TIMERS
+#elif defined(_WIN32)
+
+ static double frequency = 0.0;
+ static LARGE_INTEGER offset;
+
+ // If this is the first time we've run, get the frequency.
+ // We use frequency == 0.0 to indicate that
+ // QueryPerformanceFrequency is uninitialised.
+ if (frequency == 0.0)
+ {
+ LARGE_INTEGER pF;
+ if (!QueryPerformanceFrequency(&pF))
+ {
+ // Fallback for the QueryPerformanceCounter function.
+ FileTimeToTimeVal(tv);
+ }
+ else
+ {
+ QueryPerformanceCounter(&offset);
+ frequency = (double)pF.QuadPart / 1000000.0;
+ }
+ }
+
+ if (frequency != 0.0)
+ {
+ LARGE_INTEGER pC;
+ // Get the current performance-counter value.
+ QueryPerformanceCounter(&pC);
+
+ pC.QuadPart -= offset.QuadPart;
+ double microseconds = (double)pC.QuadPart / frequency;
+ pC.QuadPart = microseconds;
+ tv->tv_sec = (long)pC.QuadPart / 1000000;
+ tv->tv_usec = (long)(pC.QuadPart % 1000000);
+ }
+
+#endif
+}
+
void Timers::StartTimer(const std::string& timerName)
{
timeval tmp;
-
tmp.tv_sec = 0;
tmp.tv_usec = 0;
-#ifndef _WIN32
- gettimeofday(&tmp, NULL);
-#else
- FileTimeToTimeVal(&tmp);
-#endif
-
+ GetTime(&tmp);
+
// Check to see if the timer already exists. If it does, we'll subtract the
- // old value.
+ // old value.
if (timers.count(timerName) == 1)
{
timeval tmpDelta;
-
+
timersub(&tmp, &timers[timerName], &tmpDelta);
-
+
tmp = tmpDelta;
}
-
+
timers[timerName] = tmp;
}
@@ -166,12 +248,9 @@
void Timers::StopTimer(const std::string& timerName)
{
timeval delta, b, a = timers[timerName];
+
+ GetTime(&b);
-#ifndef _WIN32
- gettimeofday(&b, NULL);
-#else
- FileTimeToTimeVal(&b);
-#endif
// Calculate the delta time.
timersub(&b, &a, &delta);
timers[timerName] = delta;
Modified: mlpack/trunk/src/mlpack/core/util/timers.hpp
===================================================================
--- mlpack/trunk/src/mlpack/core/util/timers.hpp 2013-06-11 16:31:08 UTC (rev 15221)
+++ mlpack/trunk/src/mlpack/core/util/timers.hpp 2013-06-11 16:43:56 UTC (rev 15222)
@@ -1,6 +1,7 @@
/**
* @file timers.hpp
* @author Matthew Amidon
+ * @author Marcus Edel
*
* Timers for MLPACK.
*/
@@ -10,18 +11,42 @@
#include <map>
#include <string>
-#ifndef _WIN32
- #include <sys/time.h> //linux
-#else
- #include <winsock.h> //timeval on windows
- #include <windows.h> //GetSystemTimeAsFileTime on windows
-//gettimeofday has no equivalent will need to write extra code for that.
+#if defined(__unix__) || defined(__unix)
+ #include <time.h> // clock_gettime()
+ #include <sys/time.h> // timeval, gettimeofday()
+ #include <unistd.h> // flags like _POSIX_VERSION
+#elif defined(__MACH__) && defined(__APPLE__)
+ #include <mach/mach_time.h> // mach_timebase_info,
+ // mach_absolute_time()
+
+ // TEMPORARY
+ #include <time.h> // clock_gettime()
+ #include <sys/time.h> // timeval, gettimeofday()
+ #include <unistd.h> // flags like _POSIX_VERSION
+#elif defined(_WIN32)
+ #include <windows.h> //GetSystemTimeAsFileTime(),
+ // QueryPerformanceFrequency(),
+ // QueryPerformanceCounter()
+ #include <winsock.h> //timeval on windows
+
+ // uint64_t isn't defined on every windows.
+ #if !defined(HAVE_UINT64_T)
+ #if SIZEOF_UNSIGNED_LONG == 8
+ typedef unsigned long uint64_t;
+ #else
+ typedef unsigned long long uint64_t;
+ #endif // SIZEOF_UNSIGNED_LONG
+ #endif // HAVE_UINT64_T
+
+ //gettimeofday has no equivalent will need to write extra code for that.
#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
#else
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
- #endif
-#endif //_WIN32
+ #endif // _MSC_VER, _MSC_EXTENSIONS
+#else
+ #error "unknown OS"
+#endif
namespace mlpack {
@@ -110,6 +135,7 @@
std::map<std::string, timeval> timers;
void FileTimeToTimeVal(timeval* tv);
+ void GetTime(timeval* tv);
};
}; // namespace mlpack
More information about the mlpack-svn
mailing list