diff options
author | Justin M. Keyes <justinkz@gmail.com> | 2019-06-29 16:39:22 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-06-29 16:39:22 +0200 |
commit | e2ce5ff9d6168de0ffaf59d6bf20f20631a34a2d (patch) | |
tree | 937e9bb7204b5ed160feba358a95d5e036cedc7c /src/nvim/os/time.c | |
parent | 23a97949206bbe7dbbd3f7581bb2a24fabce116e (diff) | |
download | rneovim-e2ce5ff9d6168de0ffaf59d6bf20f20631a34a2d.tar.gz rneovim-e2ce5ff9d6168de0ffaf59d6bf20f20631a34a2d.tar.bz2 rneovim-e2ce5ff9d6168de0ffaf59d6bf20f20631a34a2d.zip |
viml/profile: switch to uv_gettimeofday() #10356
Performance of high-resolution time (clock_gettime via uv_hrtime) is
expensive on some systems. For profiling VimL, syntax, etc., we don't
care about nanosecond-precision and monotonicity edge-cases, so avoid
uv_hrtime().
closes #10328
From the uv__hrtime() source:
https://github.com/libuv/libuv/blob/0cdb4a5b4b706d0e09413d9270da28f9a88dc083/src/unix/linux-core.c#L442-L462
/* Prefer CLOCK_MONOTONIC_COARSE if available but only when it has
* millisecond granularity or better. CLOCK_MONOTONIC_COARSE is
* serviced entirely from the vDSO, whereas CLOCK_MONOTONIC may
* decide to make a costly system call.
*/
This micro-benchmark (Debug build) shows negligible differences on my
system:
#include <sys/time.h>
...
proftime_T tm = profile_start();
int trials = 999999;
int64_t t = 0;
struct timeval tv;
for (int i = 0; i < trials; i++) {
t += gettimeofday(&tv,NULL);
}
tm = profile_end(tm);
ILOG("%d trials of gettimeofday: %s", trials, profile_msg(tm));
tm = profile_start();
for (int i = 0; i < trials; i++) {
t += os_hrtime();
}
tm = profile_end(tm);
ILOG("%d trials of os_hrtime: %s", trials, profile_msg(tm));
tm = profile_start();
for (int i = 0; i < trials; i++) {
t += os_utime();
}
tm = profile_end(tm);
ILOG("%d trials of os_utime: %s", trials, profile_msg(tm));
ILOG("%zu", t);
Diffstat (limited to 'src/nvim/os/time.c')
-rw-r--r-- | src/nvim/os/time.c | 46 |
1 files changed, 43 insertions, 3 deletions
diff --git a/src/nvim/os/time.c b/src/nvim/os/time.c index 31ef1a0cd6..18239c5566 100644 --- a/src/nvim/os/time.c +++ b/src/nvim/os/time.c @@ -9,6 +9,7 @@ #include <uv.h> +#include "nvim/assert.h" #include "nvim/os/time.h" #include "nvim/os/input.h" #include "nvim/event/loop.h" @@ -22,6 +23,7 @@ static uv_cond_t delay_cond; #ifdef INCLUDE_GENERATED_DECLARATIONS # include "os/time.c.generated.h" #endif + /// Initializes the time module void time_init(void) { @@ -29,15 +31,53 @@ void time_init(void) uv_cond_init(&delay_cond); } -/// Obtain a high-resolution timer value +/// Gets the current time with microsecond (μs) precision. +/// +/// Subject to system-clock quirks (drift, going backwards, skipping). +/// But it is much faster than os_hrtime() on some systems. #10328 +/// +/// @see gettimeofday(2) +/// +/// @return Current time in microseconds. +uint64_t os_utime(void) + FUNC_ATTR_WARN_UNUSED_RESULT +{ + uv_timeval64_t tm; + int e = uv_gettimeofday(&tm); + if (e != 0 || tm.tv_sec < 0 || tm.tv_usec < 0) { + return 0; + } + uint64_t rv = (uint64_t)tm.tv_sec * 1000 * 1000; // s => μs + STRICT_ADD(rv, tm.tv_usec, &rv, uint64_t); + return rv; +} + +/// Gets a high-resolution (nanosecond), monotonically-increasing time relative +/// to an arbitrary time in the past. /// -/// @return a timer value, not related to the time of day and not subject -/// to clock drift. The value is expressed in nanoseconds. +/// Not related to the time of day and therefore not subject to clock drift. +/// +/// @return Relative time value with nanosecond precision. uint64_t os_hrtime(void) + FUNC_ATTR_WARN_UNUSED_RESULT { return uv_hrtime(); } +/// Gets a millisecond-resolution, monotonically-increasing time relative to an +/// arbitrary time in the past. +/// +/// Not related to the time of day and therefore not subject to clock drift. +/// The value is cached by the loop, it will not change until the next +/// loop-tick (unless uv_update_time is called). +/// +/// @return Relative time value with millisecond precision. +uint64_t os_now(void) + FUNC_ATTR_WARN_UNUSED_RESULT +{ + return uv_now(&main_loop.uv); +} + /// Sleeps for `ms` milliseconds. /// /// @param ms Number of milliseconds to sleep |