-
-
Notifications
You must be signed in to change notification settings - Fork 43
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rewrite the process scheduler from the ground up
This new scheduler still uses work stealing, just using a different and much better implementation compared to the old scheduler. Instead of using crossbeam-deque we now use crossbeam-queue's ArrayQueue type for local queues. crossbeam's Chase-lev deque is generally OK, but uses epoch based garbage collection and isn't as fast as it could/should be. Tokio reached the same conclusions back in 2019 [1]. The ArrayQueue type is a simple bounded MPMC queue, and provides an API that's easier to work with. When the queue is full, work overflows into the global queue. The global queue is just a synchronised Vec. While a mutex may come with greater overhead, the scheduler tries to avoid using it until truly necessary, meaning the overhead isn't that big of a deal. A benefit of using a Vec is that we can quickly steal multiple jobs from this queue, instead of having to pop values one by one. This reduces the time the lock stays open, reducing contention. For putting threads to sleep we use crossbeam-utils' Parker/Unparker type. These types allow parking/unparking of threads without the need for condition variables and locks. Crucially, if you unpark a thread before parking it, the thread doesn't park. This means the implementation is less likely to result in threads sleeping when they should instead be performing work. For stealing work each thread starts stealing from the thread that comes after it, wrapping around where needed. We experimented with stealing from a randomly chosen thread but didn't find any significant performance benefits to doing so. When given the choice between questionable performance benefits and simplicity, we prefer simplicity. Each thread also has a priority slot. This slot stores a single process to run, and other threads can't steal from this slot. This is useful when rescheduling processes that we can to run as soon as possible. Currently this is only used when sending a message to a process that isn't performing work, and we want to await the result immediately. Since the sending process needs to be suspended and the receiving process needs to be woken up, we can schedule it onto the current thread using the priority slot. When running Inko's test suite and measuring the total execution time, we found the new scheduler to be 25-30% faster compared to the old scheduler. We did experiment with alternatives to work stealing, such as work pushing (where busy threads push excess work to idle threads), but these alternatives proved much slower than even our old work stealing scheduler. This fixes https://gitlab.com/inko-lang/inko/-/issues/273. [1]: https://tokio.rs/blog/2019-10-scheduler Changelog: performance
- Loading branch information
1 parent
1a51d97
commit 4cf9101
Showing
16 changed files
with
597 additions
and
1,203 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.