dabeaz / curio

Good Curio!
Other
4.04k stars 243 forks source link

Cache current loop cycle clock value #139

Closed ZhukovAlexander closed 7 years ago

ZhukovAlexander commented 7 years ago

This PR is an implementation of the libuv smart time caching. This has the following benefits:

njsmith commented 7 years ago

Interesting idea!

Since part of the motivation here is presumably speed, have you measured the performance impact?

I find the part where the public clock() trap always returns the same value to be quite surprising, and the part where relative timeouts use the stale time when converting to absolute times to be somewhat surprising. Does libuv do this too?

On Dec 8, 2016 8:16 AM, "Alexander Zhukov" notifications@github.com wrote:

This PR is an implementation of the libuv smart time caching http://docs.libuv.org/en/v1.x/design.html#the-i-o-loop. This has the following benefits:

  • all traps, that rely on a kernel's clock will have a slight performance increase
  • avoid multiple calls to time.monotonic during a single event loop ineration
  • all tasks that are being run during the same loop iteration will see the same value of the kernel's clock, which is what happens in a truly parallel environment.

You can view, comment on, or merge this pull request online at:

https://github.com/dabeaz/curio/pull/139 Commit Summary

  • Cache the current time per the event loop tick
  • Update docs

File Changes

Patch Links:

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/dabeaz/curio/pull/139, or mute the thread https://github.com/notifications/unsubscribe-auth/AAlOaA1dldJZdBA3Ihx6itVg968MaJniks5rGC1EgaJpZM4LH_7q .

dabeaz commented 7 years ago

I'm kind of surprised by clock() returning the same value as well. What happens if the ready queue fills up with a bunch of stuff that takes a bit of time to work through and one of the later tasks calls clock(). It seems that its time value could be skewed in some way.

I'm thinking that clock() should return the most accurate time possible. Partly because certain parts of curio have been written in a way to allow for periodic heartbeat timers and things like that (e.g., having a task wake up at precise periodic intervals). It seems that knowing the time as precisely as possible would be essential for that.

tahajahangir commented 7 years ago

Note that clock and gettimeofday system calls actually are virtual system calls, and are pretty fast (even with CPython wrappers).

In [4]: def f(): pass

In [5]: %timeit f()
The slowest run took 34.07 times longer than the fastest. This could mean that an intermediate result is being cached.
10000000 loops, best of 3: 90.8 ns per loop

In [6]: %timeit time.monotonic()
The slowest run took 25.96 times longer than the fastest. This could mean that an intermediate result is being cached.
10000000 loops, best of 3: 115 ns per loop

In [7]: t = time.monotonic

In [8]: %timeit t()
The slowest run took 31.04 times longer than the fastest. This could mean that an intermediate result is being cached.
10000000 loops, best of 3: 81.3 ns per loop

In [9]: i = 0

In [10]: %timeit i + 1
The slowest run took 63.23 times longer than the fastest. This could mean that an intermediate result is being cached.
10000000 loops, best of 3: 43 ns per loop

Calling time.monotonic is cheaper than calling an empty python function!