mirror of
https://github.com/sched-ext/scx.git
synced 2024-11-24 20:00:22 +00:00
scx_rustland: improve dynamic slice scaling
Move scaling after tasks are sent to the dispatcher: tasks are dispatched based on the amount of idle CPUs, so checking for any remaining tasks still sitting in the scheduler after dispatch gives a better idea how busy the system is. Moreover, do not scale the time slice based on nr_cpus (otherwise, systems with a large amount of CPUs would rarely get any scaling at all). Instead, apply a scaling factor as a function of how many tasks are still waiting in the scheduler: nr_scheduled / 2. This method scales better as the number of CPUs increases. Signed-off-by: Andrea Righi <andrea.righi@canonical.com>
This commit is contained in:
parent
1da2983804
commit
db9a29d618
@ -312,14 +312,12 @@ impl<'a> Scheduler<'a> {
|
||||
|
||||
// Dynamically adjust the time slice based on the amount of waiting tasks.
|
||||
fn scale_slice_ns(&mut self) {
|
||||
let nr_queued = *self.bpf.nr_queued_mut();
|
||||
let nr_scheduled = *self.bpf.nr_scheduled_mut();
|
||||
let nr_waiting = nr_queued + nr_scheduled;
|
||||
let nr_cpus = self.bpf.get_nr_cpus() as u64;
|
||||
let nr_scheduled = self.task_pool.tasks.len() as u64;
|
||||
let slice_us_max = self.slice_ns / 1000;
|
||||
|
||||
// Scale time slice, but never scale below 1 ms.
|
||||
let scaling = nr_waiting / nr_cpus + 1;
|
||||
let slice_us = (self.slice_ns / scaling / 1000).max(1000);
|
||||
// Scale time slice as a function of nr_scheduled, but never scale below 1 ms.
|
||||
let scaling = (nr_scheduled / 2).max(1);
|
||||
let slice_us = (slice_us_max / scaling).max(1000);
|
||||
|
||||
// Apply new scaling.
|
||||
self.bpf.set_effective_slice_us(slice_us);
|
||||
@ -329,9 +327,6 @@ impl<'a> Scheduler<'a> {
|
||||
fn dispatch_tasks(&mut self) {
|
||||
let mut idle_cpus = self.get_idle_cpus();
|
||||
|
||||
// Adjust the dynamic time slice immediately before dispatching the tasks.
|
||||
self.scale_slice_ns();
|
||||
|
||||
// Dispatch only a batch of tasks equal to the amount of idle CPUs in the system.
|
||||
//
|
||||
// This allows to have more tasks sitting in the task pool, reducing the pressure on the
|
||||
@ -385,6 +380,9 @@ impl<'a> Scheduler<'a> {
|
||||
self.drain_queued_tasks();
|
||||
self.dispatch_tasks();
|
||||
|
||||
// Adjust the dynamic time slice immediately after dispatching the tasks.
|
||||
self.scale_slice_ns();
|
||||
|
||||
// Yield to avoid using too much CPU from the scheduler itself.
|
||||
thread::yield_now();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user