When more crates are ready to start compiling than there is available parallelism, how does Cargo pick which ones to start first? Are there ways to influence this scheduling? (For example, does the order of declarations of dependencies in a given Cargo.toml file matter? Or, what effect would it have to add an otherwise unnecessary edge to the dependency graph?) Should we add a new mechanism to influence it?
Here is the output of cargo build -Z timings for Servo: (with "Min unit time" set to 10 seconds)


If we start from the end of the graph, (part of) a critical path is very apparent: the final executable only starts to build after the script crate has finished. The script crate in turns only starts after the build script for the mozjs_sys has finished.
Additionally, CPU utilization drops while script is compiling because Cargo runs out of other tasks to do and rustc only has limited intra-crate parallelism. (Though I expected codegen-units to provide some more parallelism during codegen, but that’s a separate issue.)
It seems that if we could start mozjs_sys and script and earlier, the total time could be significantly reduced. Specifically: cargo build -p mozjs_sys && cargo build -p script && cargo build might lead to better scheduling. A way to achieve that scheduling with more parallelism could be to assign priorities. mozjs_sys and its recursive dependencies have priority 2 (more urgent), script and its dependencies that don’t already have a priority have priority 1, and everything else has priority 1.
Literally this mechanism with numeric priority levels is probably not the UX we want for Cargo. But how does it sound to add some way to influence the scheduling? Maybe call it “hints” to avoid setting in stone the current algorithm.
CC #5125 which is on the more general topic of scheduling
When more crates are ready to start compiling than there is available parallelism, how does Cargo pick which ones to start first? Are there ways to influence this scheduling? (For example, does the order of declarations of dependencies in a given
Cargo.tomlfile matter? Or, what effect would it have to add an otherwise unnecessary edge to the dependency graph?) Should we add a new mechanism to influence it?Here is the output of
cargo build -Z timingsfor Servo: (with "Min unit time" set to 10 seconds)If we start from the end of the graph, (part of) a critical path is very apparent: the final executable only starts to build after the
scriptcrate has finished. The script crate in turns only starts after the build script for themozjs_syshas finished.Additionally, CPU utilization drops while
scriptis compiling because Cargo runs out of other tasks to do and rustc only has limited intra-crate parallelism. (Though I expectedcodegen-unitsto provide some more parallelism during codegen, but that’s a separate issue.)It seems that if we could start
mozjs_sysandscriptand earlier, the total time could be significantly reduced. Specifically:cargo build -p mozjs_sys && cargo build -p script && cargo buildmight lead to better scheduling. A way to achieve that scheduling with more parallelism could be to assign priorities.mozjs_sysand its recursive dependencies have priority 2 (more urgent),scriptand its dependencies that don’t already have a priority have priority 1, and everything else has priority 1.Literally this mechanism with numeric priority levels is probably not the UX we want for Cargo. But how does it sound to add some way to influence the scheduling? Maybe call it “hints” to avoid setting in stone the current algorithm.
CC #5125 which is on the more general topic of scheduling