Skip to content

Optimization: a slot for the next task to run #529

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
2 commits merged into from Nov 13, 2019
Merged

Optimization: a slot for the next task to run #529

2 commits merged into from Nov 13, 2019

Conversation

ghost
Copy link

@ghost ghost commented Nov 13, 2019

This is an optimization from Go's scheduler, which has recently also been adoped by Tokio.

The idea is that each worker thread, besides holding a local task queue, also holds a slot of type Cell<Option<Runnable>> that contains the next task to run. When scheduling a new runnable task, we store it into the slot. If the slot already contained a task, we then push that task into the local task queue. This way we don't have to touch queues in many cases at all. Since queues are more expensive that task slots, this can drastically improve performance.

In Go's scheduler, runqput stores a task into this slot to schedule it, while runqget takes a task from the slot. The linked Tokio blog post illustrates this nicely with diagrams: take a look at the "Run next" slot that is positioned in front of "Run queue".

This PR also deleted some unsafe code by replacing UnsafeCell with OnceCell.

Benchmarks:

 name           before ns/iter  after ns/iter  diff ns/iter   diff %  speedup
 contention     983,233         270,738            -712,495  -72.46%   x 3.63
 create         4               4                         0    0.00%   x 1.00
 no_contention  271,792         215,953             -55,839  -20.54%   x 1.26
 name           before ns/iter  after ns/iter  diff ns/iter   diff %  speedup
 chained_spawn  119,929         121,418               1,489    1.24%   x 0.99
 ping_pong      256,357         259,504               3,147    1.23%   x 0.99
 spawn_many     2,728,784       2,842,761           113,977    4.18%   x 0.96
 yield_many     3,530,096       3,141,737          -388,359  -11.00%   x 1.12

@ghost ghost merged commit 0c2282f into async-rs:master Nov 13, 2019
@ghost ghost deleted the next-slot branch November 13, 2019 19:32
This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

0 participants