Skip to content
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

Driver: Implement audio scheduler #179

Merged
merged 28 commits into from
May 21, 2023

Conversation

FelixMcFelix
Copy link
Member

@FelixMcFelix FelixMcFelix commented May 1, 2023

This PR introduces a scheduler for audio threads: idle tasks are all run on a single background async task, while live audio threads are grouped up into full sync threads. Tasks are dynamically promoted and demoted based on whether they have any live audio tracks. This adds in some other niceties like preventing packet buffer reallocations, where possible. I intend to add reclamation of packet buffers, worker threads, and offloading expensive tasks to other threads.

This defaults to grouping 16 live calls per thread, mainly to prevent issues with users not compiling in release mode and/or using weaker machines. This can be configured during Config creation, and should be tuned for users at scale -- for instance, a passthrough-only workload can serve up to ~660 calls per thread on a Ryzen 5700X.

To put this in context, if all calls are live, this defaults to a 16x reduction in the amount of threads used. If only 30% of calls are live, the remainder all go in a single async task, giving an asymptotic 53x reduction of thread count.

TODO:

  • Cleanup & document the draft implementation
  • Fix Benchmarks to account for scheduler
  • Integrate testing of scheduler behaviours into harness
  • Periodically reclaim threads and packet blocks
  • Update ARCHITECTURE.md

@FelixMcFelix FelixMcFelix added enhancement New feature or request driver Relates to the driver or one of its sub-tasks. labels May 16, 2023
@FelixMcFelix FelixMcFelix marked this pull request as ready for review May 21, 2023 10:14
This seemed to provide a decent speedup (4--10%) for multiple mixers, both float and opus.
@FelixMcFelix FelixMcFelix merged commit f38021f into serenity-rs:next May 21, 2023
FelixMcFelix added a commit to FelixMcFelix/songbird that referenced this pull request Nov 20, 2023
This PR implements a custom scheduler for audio threads, which reduces thread use and (often) memory consumption.

To save threads and memory (e.g., packet buffer allocations), Songbird parks Mixer tasks which do not have any live Tracks.
These are now all co-located on a single async 'Idle' task.
This task is responsible for managing UDP keepalive messages for each task, maintaining event state, and executing any Mixer task messages.
Whenever any message arrives which adds a `Track`, the mixer task is moved to a live thread.
The Idle task inspects task counts and execution time on each thread, choosing the first live thread with room, and creating a new one if needed.

Each live thread is responsible for running as many live mixers as it can in a single tick every 20ms: this currently defaults to 16 mixers per thread, but is user-configurable.
A live thread also stores RTP packet blocks to be written into by each sub-task.
Each live thread has a conservative limit of 18ms that it will aim to stay under: if all work takes longer than this, it will offload the task with the highest mixing cost once per tick onto another (possibly new) live worker thread.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
driver Relates to the driver or one of its sub-tasks. enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant