Skip to content

Commit 649376e

Browse files
committed
sort the pending queue according to cost/priority
If multiple pieces of work are waiting in the pending queue, we can sort it according to their priorities: higher priorities should be scheduled sooner. They are more often than not wider than pure chains, and this should create more parallelism opportunities earlier in the pipeline: a high priority piece of work represents more future pieces of work down the line. This is a scheduling tradeoff that behaves differently for each project, machine configuration, amount of available parallelism at a given point in time, etc, but seems to help more often than hinders, at low-core counts and with enough units of work to be done, so that there is jobserver token contention where choosing a "better" piece of work to work on next is possible.
1 parent 4ed54ce commit 649376e

File tree

2 files changed

+18
-0
lines changed

2 files changed

+18
-0
lines changed

src/cargo/core/compiler/job_queue.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,17 @@ impl<'cfg> DrainState<'cfg> {
583583
}
584584
}
585585

586+
// If multiple pieces of work are waiting in the pending queue, we can sort it according to
587+
// their priorities: higher priorities should be scheduled sooner.
588+
if self.pending_queue.len() > 1 {
589+
self.pending_queue.sort_by(|(unit_a, _), (unit_b, _)| {
590+
// We want to sort in descending order, as bigger values represent higher priorities.
591+
let priority_a = self.queue.priority(unit_a);
592+
let priority_b = self.queue.priority(unit_b);
593+
priority_b.partial_cmp(&priority_a).unwrap()
594+
});
595+
}
596+
586597
// Now that we've learned of all possible work that we can execute
587598
// try to spawn it so long as we've got a jobserver token which says
588599
// we're able to perform some parallel work.

src/cargo/util/dependency_queue.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,13 @@ impl<N: Hash + Eq + Clone, E: Eq + Hash + Clone, V> DependencyQueue<N, E, V> {
170170
self.dep_map.len()
171171
}
172172

173+
/// Returns the relative priority of a node. Higher priorities should be scheduled sooner.
174+
/// Currently computed as the transitive cost of the given node: its own, plus the cost of its
175+
/// reverse dependencies.
176+
pub(crate) fn priority(&self, node: &N) -> usize {
177+
self.priority[node]
178+
}
179+
173180
/// Indicate that something has finished.
174181
///
175182
/// Calling this function indicates that the `node` has produced `edge`. All

0 commit comments

Comments
 (0)