The Blink Scheduler
London is minding your tasks
BlinkOn 3, Nov 5th 2014
{alexclarke, petrcermak, picksi, rmcilroy, skyostil}@chromium.org
The main problem: Traffic jams
The main problem: Traffic jams
The main problem: Traffic jams
Compositor task
posted here
...and executed here, after 1 second
Issue: How do we measure traffic jams?
queueing_durations track how long compositor tasks are stuck in the message loop queue.
20 ms median delay
Issue: How do we measure traffic jams?
mean_input_event_latency tracks how long user input takes to hit the GPU.
50 ms median delay!
ChromiumPerf/android-nexus4/smoothness.sync_scroll.key_mobile_sites/mean_input_event_latency
Task sources
Renderer main thread tasks come from many sources:
IPC messages
Main thread
MessageLoop
Blink shared timers
Input events from cc
BeginFrames from cc
DOM timers
Input events
v8 GC
callOnMain
HTML parsing
Network loads
Goal: Perfect Scheduling
All about scheduling
Pre-Scheduler world
Task 1
Task 3
New Task
Task 2
Pre-Scheduler world
Task 1
Task 3
Task 4
Task 2
Pre-Scheduler world
Task 1 taken from the front of the queue and executed.
Task 1
Task 3
Task 4
Task 2
Pre-Scheduler world
Task 1
Task 3
◕︵◕
Task 2
A new task will need to wait until all the preceding tasks have been executed.
Scheduler world
Task 1
Task 3
New Task
Task 2
Fast Lane
Ideally we’d like to be able to fast-track high priority tasks.
Scheduler world
Task 1
Task 3
Task 2
Task 4
Scheduler world
Task 1
Task 3
Task 2
Task 1
\(• ◡ •)/
Multiple queues give more flexibility
Task 1
Task 3
Task 1
Task 4
Task 2
Issue: Maintaining execution order
Most tasks need to have their relative execution order maintained.
Only reorder tasks that have opted into prioritization.
Solution: Tasks are grouped by type
Default
Compositor
Idle
Solution: Tasks are grouped by type
Default
Compositor
Idle
Always prioritise compositor?
Priority
Issue: Static prioritisation doesn’t work
Always prioritising compositor tasks regressed page loading time by 14%.
Solution: Dynamic prioritisation
Use contextual awareness to determine prioritisation policy.
Policy selection
Events will change the active policy:
Queue priorities set by policy
Default
CC
Idle
Compositor
Normal
Loading
Default
Idle
CC
Default
Idle
CC
Priority
Issue: Task starvation
We need a scheduler which cannot be ‘gamed’ by sociopathic tasks to completely starve out other tasks.
Issue: Task starvation
CC
CC
CC
CC
CC
CC
CC
CC
CC
Solution: Weighted round robin
to avoid starvation
CC
CC
CC
CC
CC
CC
CC
CC
Default
CC
CC
CC
CC
Default
CC
CC
CC
Architecture
Finding a home for the Scheduler
Version 1 implementation was in Blink
Finding a home for the Scheduler
Version 2 implementation was in base/message_loop
Finding a home for the Scheduler
Version 3 (current) lives in content/renderer/scheduler/
Scheduler architecture overview
Scheduler architecture overview
Three key elements�
Architecture
base::MessageLoop
Task
Task
Task
...
MessageLoop
Proxy
Architecture: Posting API
TaskQueueManager
Incoming
task
queue
Work
queue
Incoming
task
queue
Work
queue
DefaultTaskRunner
Compositor
TaskRunner
base::MessageLoop
Sched.
task
Task
Sched.
task
Scheduling entry point
Other tasks that aren’t scheduled (e.g. IPC)
...
Architecture: Posting API
TaskQueueManager
Incoming
task
queue
Work
queue
Incoming
task
queue
Work
queue
base::MessageLoop
Sched.
task
Task
Sched.
task
Scheduling entry point
Other tasks that aren’t scheduled (e.g. IPC)
...
DefaultTask
Runner
Chromium:
DefaultTaskRunner()->PostTask()
CompositorTaskRunner()->PostTask()
IdleTaskRunner()->PostIdleTask()
Blink:
Scheduler::shared()->scheduler()
Platform::current()->callOnMain()
WebThread::postTask()
Compositor
TaskRunner
Architecture: Queue selector
Scheduling decision: which work queue to service
TaskQueueManager
Incoming
task
queue
Work
queue
Incoming
task
queue
Work
queue
base::MessageLoop
Sched.
task
Task
Sched.
task
Scheduling entry point
...
Work queue state
DefaultTaskRunner
Compositor
TaskRunner
RendererTask QueueSelector
Architecture: Policies
TaskQueueManager
Incoming
task
queue
Work
queue
Incoming
task
queue
Work
queue
RendererTask QueueSelector
base::MessageLoop
Sched.
task
Task
Sched.
task
Scheduling entry point
...
Contextual information
(e.g., user input) drives policy
Renderer
Scheduler
Queue priorities
DefaultTaskRunner
Compositor
TaskRunner
Results
Results from Scheduler V1
Queueing_durations ~12ms => ~7ms
(Nexus 7v2)
Preliminary results for V3
(Nexus 7v2)
Future steps
Future steps: Idle tasks
Idle Period
CC
commit
begin frame
Idle task characteristics
First idle task customer: V8 GC
Future Idle task customers…?
Future steps: LoadingTaskQueue
Future steps: Half-baked ideas
Future steps: Half-baked ideas
Lessons learned
Making your tasks scheduler aware