IMPALA-4631: don't use floating point operations for time unit conversions

This was leading to the PlanFragmentExecutor::Close() DCHECK because
with floating point we can have c * a + c * b > c * (a + b).  Also note
this is much more likely to happen when using the MONOTONIC_COARSE since
that will result in the nested scoped timers ending up starting/stopping
at exactly the same time.  Additionally, the new code is faster.

Change-Id: I7237f579b201f5bd3930f66e9c2c8d700c37ffeb
Reviewed-on: http://gerrit.cloudera.org:8080/5434
Reviewed-by: Dan Hecht <dhecht@cloudera.com>
Tested-by: Jim Apple <jbapple-impala@apache.org>
This commit is contained in:
Dan Hecht
2016-12-08 15:29:47 -08:00
parent d6eb1b107d
commit 54194af6ef
4 changed files with 16 additions and 24 deletions

View File

@@ -166,18 +166,6 @@ bool WallTime_Parse_Timezone(const char* time_spec,
return true; return true;
} }
WallTime WallTime_Now() {
#if defined(__APPLE__)
mach_timespec_t ts;
walltime_internal::GetCurrentTime(&ts);
return ts.tv_sec + ts.tv_nsec / static_cast<double>(1e9);
#else
timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
return ts.tv_sec + ts.tv_nsec / static_cast<double>(1e9);
#endif // defined(__APPLE__)
}
void StringAppendStrftime(string* dst, void StringAppendStrftime(string* dst,
const char* format, const char* format,
time_t when, time_t when,

View File

@@ -30,6 +30,12 @@ using std::string;
#include "common/logging.h" #include "common/logging.h"
#include "gutil/integral_types.h" #include "gutil/integral_types.h"
#define NANOS_PER_SEC 1000000000ll
#define NANOS_PER_MICRO 1000ll
#define MICROS_PER_SEC 1000000ll
#define MICROS_PER_MILLI 1000ll
#define MILLIS_PER_SEC 1000ll
typedef double WallTime; typedef double WallTime;
// Append result to a supplied string. // Append result to a supplied string.
@@ -52,9 +58,6 @@ bool WallTime_Parse_Timezone(const char* time_spec,
bool local, bool local,
WallTime* result); WallTime* result);
// Return current time in seconds as a WallTime.
WallTime WallTime_Now();
typedef int64 MicrosecondsInt64; typedef int64 MicrosecondsInt64;
typedef int64 NanosecondsInt64; typedef int64 NanosecondsInt64;
@@ -76,7 +79,7 @@ inline void GetCurrentTime(mach_timespec_t* ts) {
inline MicrosecondsInt64 GetCurrentTimeMicros() { inline MicrosecondsInt64 GetCurrentTimeMicros() {
mach_timespec_t ts; mach_timespec_t ts;
GetCurrentTime(&ts); GetCurrentTime(&ts);
return ts.tv_sec * 1e6 + ts.tv_nsec / 1e3; return ts.tv_sec * MICROS_PER_SEC + ts.tv_nsec / NANOS_PER_MICRO;
} }
inline int64_t GetMonoTimeNanos() { inline int64_t GetMonoTimeNanos() {
@@ -91,7 +94,7 @@ inline int64_t GetMonoTimeNanos() {
} }
inline MicrosecondsInt64 GetMonoTimeMicros() { inline MicrosecondsInt64 GetMonoTimeMicros() {
return GetMonoTimeNanos() / 1e3; return GetMonoTimeNanos() / NANOS_PER_MICRO;
} }
inline MicrosecondsInt64 GetThreadCpuTimeMicros() { inline MicrosecondsInt64 GetThreadCpuTimeMicros() {
@@ -117,7 +120,8 @@ inline MicrosecondsInt64 GetThreadCpuTimeMicros() {
return 0; return 0;
} }
return thread_info_data.user_time.seconds * 1e6 + thread_info_data.user_time.microseconds; return thread_info_data.user_time.seconds * MICROS_PER_SEC +
thread_info_data.user_time.microseconds;
} }
#else #else
@@ -125,13 +129,13 @@ inline MicrosecondsInt64 GetThreadCpuTimeMicros() {
inline MicrosecondsInt64 GetClockTimeMicros(clockid_t clock) { inline MicrosecondsInt64 GetClockTimeMicros(clockid_t clock) {
timespec ts; timespec ts;
clock_gettime(clock, &ts); clock_gettime(clock, &ts);
return ts.tv_sec * 1e6 + ts.tv_nsec / 1e3; return ts.tv_sec * MICROS_PER_SEC + ts.tv_nsec / NANOS_PER_MICRO;
} }
inline NanosecondsInt64 GetClockTimeNanos(clockid_t clock) { inline NanosecondsInt64 GetClockTimeNanos(clockid_t clock) {
timespec ts; timespec ts;
clock_gettime(clock, &ts); clock_gettime(clock, &ts);
return ts.tv_sec * 1e9 + ts.tv_nsec; return ts.tv_sec * NANOS_PER_SEC + ts.tv_nsec;
} }
#endif // defined(__APPLE__) #endif // defined(__APPLE__)

View File

@@ -170,7 +170,7 @@ class MonotonicStopWatch {
// Now() can be called frequently (IMPALA-2407). // Now() can be called frequently (IMPALA-2407).
timespec ts; timespec ts;
clock_gettime(OsInfo::fast_clock(), &ts); clock_gettime(OsInfo::fast_clock(), &ts);
return ts.tv_sec * 1e9 + ts.tv_nsec; return ts.tv_sec * NANOS_PER_SEC + ts.tv_nsec;
#endif #endif
} }

View File

@@ -39,11 +39,11 @@ inline int64_t MonotonicMicros() { // 63 bits ~= 5K years uptime
} }
inline int64_t MonotonicMillis() { inline int64_t MonotonicMillis() {
return GetMonoTimeMicros() / 1e3; return GetMonoTimeMicros() / MICROS_PER_MILLI;
} }
inline int64_t MonotonicSeconds() { inline int64_t MonotonicSeconds() {
return GetMonoTimeMicros() / 1e6; return GetMonoTimeMicros() / MICROS_PER_SEC;
} }
@@ -52,7 +52,7 @@ inline int64_t MonotonicSeconds() {
/// a cluster. For more accurate timings on the local host use the monotonic functions /// a cluster. For more accurate timings on the local host use the monotonic functions
/// above. /// above.
inline int64_t UnixMillis() { inline int64_t UnixMillis() {
return GetCurrentTimeMicros() / 1e3; return GetCurrentTimeMicros() / MICROS_PER_MILLI;
} }
/// Sleeps the current thread for at least duration_ms milliseconds. /// Sleeps the current thread for at least duration_ms milliseconds.