Node assignments pessimized in multitargeted->multitargeted refs with BuildProjectReferences=false
#8563
Description
Given a project that itself multitargets and references several multitargeted projects, like pessimized_node_assignments.zip, the scheduler does a terrible job spreading the work around among nodes when the referencing project (here Aggregate\Aggregate.csproj
) is built with -p:BuildProjectReferences=false -m:3 -nr:false
.
The true optimal node count and scheduling for such a system may not be knowable, but number_of_nodes = number_of_TargetFrameworks
seems like a very reasonable guess.
From my debugging, what's going wrong is that we have these dependencies (filtered to a single reference):
graph TD
subgraph Aggregate
Aggregate_outer
Aggregate_net5
Aggregate_net6
Aggregate_net7
end
subgraph Lib1
Lib1_outer
Lib1_net5
Lib1_net6
Lib1_net7
end
Aggregate_outer -->|Build| Aggregate_net5
Aggregate_outer -->|Build| Aggregate_net6
Aggregate_outer -->|Build| Aggregate_net7
Aggregate_net5 -->|GetTargetFrameworks| Lib1_outer
Aggregate_net6 -->|GetTargetFrameworks| Lib1_outer
Aggregate_net7 -->|GetTargetFrameworks| Lib1_outer
Lib1_outer -->|GetTargetFrameworksWithPlatformForSingleTargetFramework| Lib1_net5
Lib1_outer -->|GetTargetFrameworksWithPlatformForSingleTargetFramework| Lib1_net6
Lib1_outer -->|GetTargetFrameworksWithPlatformForSingleTargetFramework| Lib1_net7
Aggregate_net5 -->|GetTargetPath| Lib1_net5
Aggregate_net6 -->|GetTargetPath| Lib1_net6
Aggregate_net7 -->|GetTargetPath| Lib1_net7
Unfortunately, the calls to GetTargetFrameworksWithPlatformForSingleTargetFramework
are all getting assigned to node 1
, locking the inner builds for all referenced projects to that node. That node is also used to do actual build work for one of the inner builds of Aggregate
, which blocks work that should be able to run in parallel for the other inner builds:
@dfederm has observed worse cascading where all of the inner builds were serialized on real-world projects.