Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions src/BuildPrediction/ProjectGraphPredictionExecutor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,28 +80,30 @@ public void PredictInputsAndOutputs(
{
foreach (var projectNode in projectGraph.ProjectNodes)
{
ExecuteAllPredictors(projectNode, _projectPredictors, _projectGraphPredictors, projectPredictionCollector);
ExecuteAllPredictors(projectNode, _projectPredictors, _projectGraphPredictors, projectPredictionCollector, _options.MaxDegreeOfParallelismPerProject);
}
}
else
{
int maxDegreeOfParallelismPerProject = _options.MaxDegreeOfParallelismPerProject;
Parallel.ForEach(
projectGraph.ProjectNodes.ToArray(),
new ParallelOptions() { MaxDegreeOfParallelism = _options.MaxDegreeOfParallelism },
projectNode => ExecuteAllPredictors(projectNode, _projectPredictors, _projectGraphPredictors, projectPredictionCollector));
projectNode => ExecuteAllPredictors(projectNode, _projectPredictors, _projectGraphPredictors, projectPredictionCollector, maxDegreeOfParallelismPerProject));
}
}

private static void ExecuteAllPredictors(
ProjectGraphNode projectGraphNode,
ValueAndTypeName<IProjectPredictor>[] projectPredictors,
ValueAndTypeName<IProjectGraphPredictor>[] projectGraphPredictors,
IProjectPredictionCollector projectPredictionCollector)
IProjectPredictionCollector projectPredictionCollector,
int maxDegreeOfParallelismPerProject)
{
ProjectInstance projectInstance = projectGraphNode.ProjectInstance;

// Run the project predictors. Use single-threaded prediction since we're already parallelizing on projects.
ProjectPredictionExecutor.ExecuteProjectPredictors(projectInstance, projectPredictors, projectPredictionCollector, maxDegreeOfParallelism: 1);
// Run the project predictors.
ProjectPredictionExecutor.ExecuteProjectPredictors(projectInstance, projectPredictors, projectPredictionCollector, maxDegreeOfParallelismPerProject);

// Run the graph predictors
for (var i = 0; i < projectGraphPredictors.Length; i++)
Expand Down
17 changes: 17 additions & 0 deletions src/BuildPrediction/ProjectPredictionOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,22 @@ public sealed class ProjectPredictionOptions
/// If the caller of <see cref="ProjectPredictionExecutor"/> is parallelizing across projects, it's recommended to set this to 1 to avoid over-scheduling.
/// </remarks>
public int MaxDegreeOfParallelism { get; set; } = Environment.ProcessorCount;

/// <summary>
/// Gets or sets the max degree of parallelism to use for running predictors within a single project during graph prediction.
/// Defaults to 1, meaning predictors for each project run sequentially.
/// </summary>
/// <remarks>
/// <para>
/// When using <see cref="ProjectGraphPredictionExecutor"/>, projects are processed in parallel (controlled by <see cref="MaxDegreeOfParallelism"/>),
/// and predictors within each project are processed with this level of parallelism. The total thread usage may be up to
/// <see cref="MaxDegreeOfParallelism"/> × <see cref="MaxDegreeOfParallelismPerProject"/>, so care should be taken to avoid over-subscription.
/// </para>
/// <para>
/// Increasing this value can help when individual projects are bottlenecks (e.g. projects with many items that take a long time to predict),
/// but it assumes all predictors are thread-safe. Built-in predictors are thread-safe, but custom predictors should be verified.
/// </para>
/// </remarks>
public int MaxDegreeOfParallelismPerProject { get; set; } = 1;
}
}
Loading