Skip to content

unix: hierarchical time wheels implemention and benchmarks#823

Closed
yjhjstz wants to merge 3 commits intolibuv:v1.xfrom
yjhjstz:v1.x-time-wheel
Closed

unix: hierarchical time wheels implemention and benchmarks#823
yjhjstz wants to merge 3 commits intolibuv:v1.xfrom
yjhjstz:v1.x-time-wheel

Conversation

@yjhjstz
Copy link
Copy Markdown

@yjhjstz yjhjstz commented Apr 12, 2016

see issue #809.

time wheels worse case benchmark result:

heap:

➜  libuv git:(v1.x) ✗ out/Release/run-benchmarks million_timers_cascade
10.42 seconds total
2.47 seconds init
7.57 seconds dispatch
0.38 seconds cleanup

time-wheels:

➜  libuv git:(v1.x-time-wheel) ✗ out/Release/run-benchmarks million_timers_cascade 
6.00 seconds total
1.46 seconds init
4.15 seconds dispatch
0.39 seconds cleanup

heap:

➜  libuv git:(v1.x) ✗ out/Release/run-benchmarks million_timers_cancel
9.92 seconds total
9.38 seconds start/stop
0.00 seconds run
0.54 seconds cleanup

time-wheels:

➜  libuv git:(v1.x-time-wheel) ✗ out/Release/run-benchmarks million_timers_cancel
1.39 seconds total
0.95 seconds start/stop
0.00 seconds run
0.45 seconds cleanup

@saghul @bnoordhuis

Comment thread include/list.h Outdated
This file is licensed to you under your choice of the GNU Lesser
General Public License, version 3 or any later version (LGPLv3 or
later), or the GNU General Public License, version 2 (GPLv2), in all
cases as published by the Free Software Foundation.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We cannot incorporate code with this license.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will delete it.

@yjhjstz
Copy link
Copy Markdown
Author

yjhjstz commented Apr 21, 2016

update benchmark result, big improve!

Comment thread include/list.h Outdated
@@ -0,0 +1,241 @@
#ifndef _LLIST_H
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the same file as before? If so, you can't just delete the license and be done with it, we cannot incorporate GPL code. Can't you use our queue.h?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Later, I will try use queue.h , any other suggestion?

@yjhjstz yjhjstz changed the title hierarchical time wheels implemention and benchmarks unix: hierarchical time wheels implemention and benchmarks Apr 22, 2016
@yjhjstz
Copy link
Copy Markdown
Author

yjhjstz commented Apr 26, 2016

update commit message, separate implemention and benchmarks.

@saghul
Copy link
Copy Markdown
Member

saghul commented Apr 28, 2016

Sorry @yjhjstz, I won't be able to look at this in the upcoming weeks. I have not forgotten though!

@yjhjstz
Copy link
Copy Markdown
Author

yjhjstz commented Apr 28, 2016

any other libuv member can review it for me ? thanks.

Comment thread include/uv-unix.h Outdated
#endif


// 8+6+6+6+6=32
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do not use //, use only /* */, old c style compliant comments

@txdv
Copy link
Copy Markdown
Contributor

txdv commented Apr 28, 2016

Just putting out the inpact on the struct sizes. With your code:

sizeof(uv_loop_t) = 9032
sizeof(uv_timer_t) = 144

with the old code:

sizeof(uv_loop_t) = 848
sizeof(uv_timer_t) = 152

Comment thread src/unix/timer.c Outdated
heap_remove((struct heap*) &handle->loop->timer_heap,
(struct heap_node*) &handle->heap_node,
timer_less_than);
--handle->loop->timer_counter;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think handle->loop->timer_counter-- would be cleaner (put the decrement operator at the end).

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok.

@Fishrock123
Copy link
Copy Markdown
Contributor

ping me if I forget to take a look :)

@yjhjstz
Copy link
Copy Markdown
Author

yjhjstz commented May 27, 2016

cc @libuv/collaborators

@bnoordhuis
Copy link
Copy Markdown
Member

Ping @Fishrock123? I don't have time to review it myself.

@yjhjstz
Copy link
Copy Markdown
Author

yjhjstz commented Jul 22, 2016

@saghul can you ?

@saghul
Copy link
Copy Markdown
Member

saghul commented Jul 22, 2016

@yjhjstz sorry, I don't have much time these days. At any rate, this PR would need to be applied to master, not v1.x because it breaks the ABI. And it should be used also on Windows.

Give this is a v2 thing, it may take a while for us to find the time, please don't despair!

@Fishrock123
Copy link
Copy Markdown
Contributor

ugh geez, I'll try to take a look soon >_<

@Fishrock123
Copy link
Copy Markdown
Contributor

@saghul in http://www.slideshare.net/saghul/planning-libuv-v2/12?src=clipshare you noted that:

  • Timer Wheels
    • Linux removed them! Worst case scenario is far worse. Complex implementation.

Could you give some more insight as to points 1 and 2 there? I am relatively familiar with the complexity increase.

@Fishrock123
Copy link
Copy Markdown
Contributor

Also as a note from my time profiling Node timers: the existing impl here seems pretty performant.

(And AFAIK the existing algorithm is a O(log n) insert/remove heap, correct me if I'm wrong.)

@saghul
Copy link
Copy Markdown
Member

saghul commented Sep 20, 2016

@Fishrock123 I was planning on commenting here, but ran out of time yesterday :-S

@bnoordhuis can probably elaborate but the key points (if I noted them correctly) are:

  • Performance in the bad cases is notably worse
  • The Linux kernel removed its timer wheel implementation because of this (I found some text about this here: https://www.kernel.org/doc/Documentation/timers/hrtimers.txt)
  • Complexity: maintaining the implementation is non-trivial
  • Size: it adds some overhead to the loop struct (though this is not a show stopper)

For these reasons we ( @bnoordhuis, @piscisaureus, @indutny and myself ) generally agreed to not pursue this.

If anyone sees any inaccuracies please feel free to correct me here.

@Fishrock123
Copy link
Copy Markdown
Contributor

Thanks. I'll try to read though that wall of text within the next few days.

@saghul
Copy link
Copy Markdown
Member

saghul commented Sep 27, 2016

Thanks! At any rate, we should consider including the benchmarks.

@Fishrock123
Copy link
Copy Markdown
Contributor

Fishrock123 commented Oct 11, 2018

So at least in regarding to how node does stuff, @apapirovski took a look at using timer wheels and we both concluded that it was a less optimal solution than the one we already have and is already described in this great big wall of text.

That is: make a map of timer durations to linked lists, insert timers to the end of those lists, and keep timeout information on those lists similar to a heap, processing it first similar to a heap, and then the timers in each list. (That's the tl;dr, please go read the read deal for more.)


Modern linux distro timer wheels have very slightly improved perf characteristics (always O(1) vs Lists operations are O(1), map lookup is somewhere sub O(n) for way less entries, usually less than 10), but at a pretty significant cost. The accuracy of its hierarchical timer wheel impl degrades quite significantly over time. Ours does not.

Edit: In case it wasn't clear, I personally recommend closing this.

@stale
Copy link
Copy Markdown

stale Bot commented Sep 30, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale Bot added the stale label Sep 30, 2019
@stale stale Bot closed this Oct 7, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants