Optimization: a slot for the next task to run #529
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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, whilerunqget
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
withOnceCell
.Benchmarks: