Build Parallelism

dotnet/skills/plugins/dotnet-msbuild/skills/build-parallelism

作者 dotnet0608d8924cd3MIT5.5K 個星標收錄於 2026年10月8日更新於 2026年10月8日儲存庫今天更新

Analyze an MSBuild solution, solution filter, or Build.proj that schedules multiple project files. USE FOR: measured idle worker nodes, `-m` that does not scale, a serial ProjectReference critical path, graph builds, or an MSBuild task that builds a Projects list. Requires at least two distinct project files whose scheduling or throughput must be analyzed. DO NOT USE for non-MSBuild build systems.

AI 產生的概覽

診斷緩慢的平行 MSBuild 建置,找出序列相依鏈與排程瓶頸。

功能
引導代理分析會排程多個專案檔的 MSBuild 方案、方案篩選器或 Build.proj。內容涵蓋 MSBuild 平行處理機制、相依性圖形、圖形建置模式、ProjectReference 最佳化、BuildInParallel 以及 binlog 分析,最後產出指出關鍵路徑的診斷結果,以及扁平化虛假相依或使用 /graph 等建議。
適用情境
適用於平行 MSBuild 建置出現背景工作節點閒置、-m 無法擴充、懷疑有序列 ProjectReference 關鍵路徑,或需要檢視圖形建置與 MSBuild 工作的 Projects 清單時。它需要至少兩個不同的專案檔來分析其排程或輸送量,不適用於非 MSBuild 建置系統。
執行需求
僅為說明內容,不含指令碼。需要一個至少包含兩個專案檔的 MSBuild 專案;偏好的分析路徑需要 binlog MCP 伺服器(Microsoft.AITools.BinlogMcp),文字記錄重播備援方案則使用帶診斷記錄的 dotnet msbuild。

Diagnose a slow parallel build (start here)

Work this checklist in order — it targets the usual root cause (a serial dependency chain that no number of cores can parallelize):

  1. Check how many worker nodes actually built the solution. Capture a binlog with dotnet build /bl:{} (PowerShell: dotnet build '-bl:{}') and inspect the node timeline to see whether more than one node ran. Every dotnet CLI command built on the SDK's MSBuild-forwarding path (build, msbuild, test, pack, publish, etc.) enables /maxcpucount (multiple nodes) by default; -m:1 forces a single node. A direct MSBuild.exe invocation is sequential by default, so pass -m explicitly to enable parallel worker nodes there.
  2. Find the critical path. From the binlog, read per-project timings and the node timeline. If total build time ≈ the sum of the projects on one dependency chain, that chain — not CPU count — is the bottleneck.
  3. Name the chain explicitly, e.g. Core → Api → Web → Tests. A long serial chain stays serial no matter how large -m is, because each project waits on its predecessor.
  4. Look for unnecessary ProjectReference edges that lengthen the chain — a reference that only needs build order (not the output assembly), or one that could be a PackageReference, forces serialization it doesn't need.
  5. Recommend flattening: break false dependencies so independent projects build concurrently, and consider /graph for better scheduling.

MSBuild Parallelism Model

  • /maxcpucount (or -m): number of worker nodes (processes)
  • Every dotnet CLI command (build, msbuild, test, pack, publish, etc.) passes /maxcpucount by default via the SDK's shared MSBuild-forwarding path; -m:1 overrides it with one node
  • A direct MSBuild.exe invocation is sequential by default and requires an explicit -m
  • Recommended: -m without a number = use all logical processors
  • Each node builds one project at a time
  • Projects are scheduled based on dependency graph

Project Dependency Graph

  • MSBuild builds projects in dependency order (topological sort)
  • Critical path: longest chain of dependent projects determines minimum build time
  • Bottleneck: if project A depends on B, C, D and B takes 60s while C and D take 5s, B is the bottleneck
  • Diagnosis: replay binlog to diagnostic log with performancesummary and check Project Performance Summary — shows per-project time; grep for node.*assigned to check scheduling
  • Wide graphs (many independent projects) parallelize well; deep graphs (long chains) don't

Graph Build Mode (/graph)

  • dotnet build /graph or msbuild /graph
  • What it changes: MSBuild constructs the full project dependency graph BEFORE building
  • Benefits: better scheduling, avoids redundant evaluations, enables isolated builds
  • Limitations: all projects must use <ProjectReference> (no programmatic MSBuild task references)
  • When to use: large solutions with many projects, CI builds
  • When NOT to use: projects that dynamically discover references at build time

Optimizing Project References

  • Reduce a <ProjectReference> only after proving it is unnecessary; a slow but valid dependency must stay in the graph
  • Use <ProjectReference ... SkipGetTargetFrameworkProperties="true"> to avoid extra evaluations
  • <ProjectReference ... ReferenceOutputAssembly="false"> for build-order-only dependencies
  • Consider if a ProjectReference should be a PackageReference instead (pre-built NuGet)
  • Use solution filters (.slnf) to build subsets of the solution

BuildInParallel

  • <MSBuild Projects="@(ProjectsToBuild)" BuildInParallel="true" /> in custom targets
  • Without BuildInParallel="true", MSBuild task batches projects sequentially
  • Ensure /maxcpucount > 1 for this to have effect

Multi-threaded MSBuild Tasks

  • Individual tasks can run multi-threaded within a single project build
  • Tasks implementing IMultiThreadableTask can run on multiple threads
  • Tasks must declare thread-safety via [MSBuildMultiThreadableTask]

Analyzing Parallelism with Binlog

Primary: binlog MCP (preferred)

Use the binlog MCP server (Microsoft.AITools.BinlogMcp, exposed under the binlog MCP namespace):

  1. Use expensive_projects tool → find the slowest projects and compare individual vs total build time
  2. Use expensive_targets tool → find bottleneck targets
  3. Use project_target_times tool → drill into a specific project's target-level timing
  4. Ideal: build time should be much less than sum of project times (parallelism)
  5. If build time ≈ sum of project times: too many serial dependencies, or one slow project blocking others

Fallback: text-log replay (when MCP is unavailable)

Step-by-step:

  1. Replay the binlog: dotnet msbuild build.binlog -noconlog -fl "-flp:v=diag;logfile=full.log;performancesummary"
  2. Check Project Performance Summary at the end of full.log
  3. Ideal: build time should be much less than sum of project times (parallelism)
  4. If build time ≈ sum of project times: too many serial dependencies, or one slow project blocking others
  5. grep 'Target Performance Summary' -A 30 full.log → find the bottleneck targets
  6. Consider splitting large projects or optimizing the critical path

CI/CD Parallelism Tips

  • Use -m in CI (many CI runners have multiple cores)
  • Consider splitting solution into build stages for extreme parallelism
  • Use build caching (NuGet lock files, deterministic builds) to avoid rebuilding unchanged projects
  • dotnet build /graph works well with structured CI pipelines

來源與署名

來源:dotnet/skills位於plugins/dotnet-msbuild/skills/build-parallelism提交0608d89

授權條款: MIT

內容歸原作者所有。SourceWeft 從公開儲存庫中收錄這些內容。

檢舉或申請下架