diff options
author | Sridhar Periyasamy <sridhper@microsoft.com> | 2015-07-24 14:20:46 -0700 |
---|---|---|
committer | Sridhar Periyasamy <sridhper@microsoft.com> | 2015-07-24 14:20:46 -0700 |
commit | cd3e4610a193168a0d1a3a9da81a9b071c4e9de3 (patch) | |
tree | 9116e027daee2931455aa965f5d616466ab46f59 | |
parent | 6bfb7c3a0fb232b2bad704e9a29d82fcf3369777 (diff) | |
download | coreclr-cd3e4610a193168a0d1a3a9da81a9b071c4e9de3.tar.gz coreclr-cd3e4610a193168a0d1a3a9da81a9b071c4e9de3.tar.bz2 coreclr-cd3e4610a193168a0d1a3a9da81a9b071c4e9de3.zip |
Replace the usage of MACH monotonic function 'clock_get_time' with 'mach_absolute_time' in GetTickCount64.
Monotonic clock function 'clock_get_time' was causing perf regression in 'Environment.TickCount'. So replacing it with 'mach_absolute_time' which gives considerable performance gains. Here are the perf numbers
Using 'clock_get_time' (without caching host ports) - Average time 2.86 microseconds.
Using 'clock_get_time' (with caching host ports) - Average time 0.82 microseconds.
Using 'gettimeofday' (original implementation) - Average time 0.05 microseconds.
Using 'mach_absolute_time' - Average time 0.04 microseconds.
-rw-r--r-- | src/pal/src/config.h.in | 2 | ||||
-rw-r--r-- | src/pal/src/configure.cmake | 12 | ||||
-rw-r--r-- | src/pal/src/misc/time.cpp | 40 |
3 files changed, 23 insertions, 31 deletions
diff --git a/src/pal/src/config.h.in b/src/pal/src/config.h.in index c267a39556..354f455bf4 100644 --- a/src/pal/src/config.h.in +++ b/src/pal/src/config.h.in @@ -85,7 +85,7 @@ #cmakedefine01 HAVE_WORKING_GETTIMEOFDAY #cmakedefine01 HAVE_WORKING_CLOCK_GETTIME #cmakedefine01 HAVE_CLOCK_MONOTONIC -#cmakedefine01 HAVE_MACH_CLOCK_MONOTONIC +#cmakedefine01 HAVE_MACH_ABSOLUTE_TIME #cmakedefine01 STATVFS64_PROTOTYPE_BROKEN #cmakedefine01 HAVE_MMAP_DEV_ZERO #cmakedefine01 MMAP_IGNORES_HINT diff --git a/src/pal/src/configure.cmake b/src/pal/src/configure.cmake index dce3ef4c44..bc3d0c83b9 100644 --- a/src/pal/src/configure.cmake +++ b/src/pal/src/configure.cmake @@ -328,18 +328,16 @@ int main() }" HAVE_CLOCK_MONOTONIC) check_cxx_source_runs(" #include <stdlib.h> -#include <mach/mach.h> -#include <mach/clock.h> +#include <mach/mach_time.h> int main() { int ret; - clock_serv_t clock; - mach_timespec_t mts; - host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &clock); - ret = clock_get_time(clock, &mts); + mach_timebase_info_data_t timebaseInfo; + ret = mach_timebase_info(&timebaseInfo); + mach_absolute_time(); exit(ret); -}" HAVE_MACH_CLOCK_MONOTONIC) +}" HAVE_MACH_ABSOLUTE_TIME) check_cxx_source_runs(" #include <stdlib.h> #include <sys/types.h> diff --git a/src/pal/src/misc/time.cpp b/src/pal/src/misc/time.cpp index d5065dbd37..be875a4487 100644 --- a/src/pal/src/misc/time.cpp +++ b/src/pal/src/misc/time.cpp @@ -28,13 +28,16 @@ Abstract: #include <errno.h> #include <string.h> -#if HAVE_MACH_CLOCK_MONOTONIC -#include <mach/mach.h> -#include <mach/clock.h> +#if HAVE_MACH_ABSOLUTE_TIME +#include <mach/mach_time.h> +static mach_timebase_info_data_t s_TimebaseInfo; #endif SET_DEFAULT_DEBUG_CHANNEL(MISC); + + + /*++ Function: GetSystemTime @@ -275,28 +278,19 @@ GetTickCount64() } retval = (ts.tv_sec * tccSecondsToMillieSeconds)+(ts.tv_nsec / tccMillieSecondsToNanoSeconds); } -#elif HAVE_MACH_CLOCK_MONOTONIC +#elif HAVE_MACH_ABSOLUTE_TIME { - kern_return_t machRet; - clock_serv_t clock; - mach_timespec_t mts; - host_t host = mach_host_self(); - - if((machRet = host_get_clock_service(host, SYSTEM_CLOCK, &clock)) != KERN_SUCCESS) - { - ASSERT("host_get_clock_service() failed: %s\n", mach_error_string(machRet)); - goto EXIT; - } - machRet = clock_get_time(clock, &mts); - mach_port_deallocate(mach_task_self(), host); - mach_port_deallocate(mach_task_self(), clock); - - if(machRet != KERN_SUCCESS) + // use denom == 0 to indicate that s_TimebaseInfo is uninitialised. + if (s_TimebaseInfo.denom == 0) { - ASSERT("clock_get_time() failed: %s\n", mach_error_string(machRet)); - goto EXIT; + kern_return_t machRet; + if((machRet = mach_timebase_info(&s_TimebaseInfo)) != KERN_SUCCESS) + { + ASSERT("mach_timebase_info() failed: %s\n", mach_error_string(machRet)); + goto EXIT; + } } - retval = (mts.tv_sec * tccSecondsToMillieSeconds)+(mts.tv_nsec / tccMillieSecondsToNanoSeconds); + retval = (mach_absolute_time() * s_TimebaseInfo.numer / s_TimebaseInfo.denom) / tccMillieSecondsToNanoSeconds; } #elif HAVE_GETHRTIME { @@ -326,4 +320,4 @@ GetTickCount64() #endif // HAVE_CLOCK_MONOTONIC EXIT: return retval; -} +}
\ No newline at end of file |