build-parallelism
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseMSBuild Parallelism Model
MSBuild并行构建模型
- (or
/maxcpucount): number of worker nodes (processes)-m - Default: 1 node (sequential!). Always use for parallel builds
-m - Recommended: without a number = use all logical processors
-m - Each node builds one project at a time
- Projects are scheduled based on dependency graph
- (或
/maxcpucount):工作节点(进程)数量-m - 默认值:1个节点(即串行构建!)。并行构建时务必使用参数
-m - 推荐用法:不带数字的= 使用所有逻辑处理器
-m - 每个节点一次仅构建一个项目
- 项目基于依赖图进行调度
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 and check Project Performance Summary — shows per-project time; grep for
performancesummaryto check schedulingnode.*assigned - Wide graphs (many independent projects) parallelize well; deep graphs (long chains) don't
- MSBuild按照依赖顺序构建项目(拓扑排序)
- 关键路径:最长的依赖项目链决定了最短构建时间
- 瓶颈:如果项目A依赖于B、C、D,且B需要60秒而C和D仅需5秒,那么B就是瓶颈
- 诊断方法:使用参数重放binlog生成诊断日志,查看“项目性能摘要”——其中显示每个项目的构建时间;通过搜索
performancesummary来检查调度情况node.*assigned - 宽依赖图(大量独立项目)的并行化效果好;深依赖图(长依赖链)的并行化效果差
Graph Build Mode (/graph
)
/graph图构建模式(/graph
)
/graph- or
dotnet build /graphmsbuild /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 (no programmatic MSBuild task references)
<ProjectReference> - When to use: large solutions with many projects, CI builds
- When NOT to use: projects that dynamically discover references at build time
- 命令:或
dotnet build /graphmsbuild /graph - 变更点:MSBuild会在构建前先构建完整的项目依赖图
- 优势:调度更合理,避免重复评估,支持隔离构建
- 限制:所有项目必须使用(不支持程序化的MSBuild任务引用)
<ProjectReference> - 适用场景:包含大量项目的大型解决方案、CI构建
- 不适用场景:在构建时动态发现引用的项目
Optimizing Project References
优化项目引用
- Reduce unnecessary — each adds to the dependency chain
<ProjectReference> - Use to avoid extra evaluations
<ProjectReference ... SkipGetTargetFrameworkProperties="true"> - for build-order-only dependencies
<ProjectReference ... ReferenceOutputAssembly="false"> - Consider if a ProjectReference should be a PackageReference instead (pre-built NuGet)
- Use (
solution filters) to build subsets of the solution.slnf
- 减少不必要的——每个引用都会增加依赖链长度
<ProjectReference> - 使用来避免额外评估
<ProjectReference ... SkipGetTargetFrameworkProperties="true"> - 对于仅需保证构建顺序的依赖,使用
<ProjectReference ... ReferenceOutputAssembly="false"> - 考虑将ProjectReference替换为PackageReference(预构建的NuGet包)
- 使用解决方案筛选器()来构建解决方案的子集
.slnf
BuildInParallel
BuildInParallel属性
- in custom targets
<MSBuild Projects="@(ProjectsToBuild)" BuildInParallel="true" /> - Without , MSBuild task batches projects sequentially
BuildInParallel="true" - Ensure > 1 for this to have effect
/maxcpucount
- 在自定义目标中使用
<MSBuild Projects="@(ProjectsToBuild)" BuildInParallel="true" /> - 如果不设置,MSBuild任务会按顺序批处理项目
BuildInParallel="true" - 需确保> 1才能生效
/maxcpucount
Multi-threaded MSBuild Tasks
多线程MSBuild任务
- Individual tasks can run multi-threaded within a single project build
- Tasks implementing can run on multiple threads
IMultiThreadableTask - Tasks must declare thread-safety via
[MSBuildMultiThreadableTask]
- 单个任务可在单个项目构建过程中以多线程运行
- 实现接口的任务可在多线程上运行
IMultiThreadableTask - 任务必须通过特性声明线程安全性
[MSBuildMultiThreadableTask]
Analyzing Parallelism with Binlog
使用Binlog分析并行构建情况
Step-by-step:
- Replay the binlog:
dotnet msbuild build.binlog -noconlog -fl -flp:v=diag;logfile=full.log;performancesummary - Check Project Performance Summary at the end of
full.log - Ideal: build time should be much less than sum of project times (parallelism)
- If build time ≈ sum of project times: too many serial dependencies, or one slow project blocking others
- → find the bottleneck targets
grep 'Target Performance Summary' -A 30 full.log - Consider splitting large projects or optimizing the critical path
步骤:
- 重放binlog:
dotnet msbuild build.binlog -noconlog -fl -flp:v=diag;logfile=full.log;performancesummary - 查看末尾的“项目性能摘要”
full.log - 理想情况:构建时间应远小于所有项目构建时间的总和(体现并行性)
- 如果构建时间≈所有项目构建时间的总和:依赖关系过于串行,或者存在某个慢项目阻塞了其他项目
- 执行→ 找到瓶颈目标
grep 'Target Performance Summary' -A 30 full.log - 考虑拆分大型项目或优化关键路径
CI/CD Parallelism Tips
CI/CD并行构建技巧
- Use in CI (many CI runners have multiple cores)
-m - Consider splitting solution into build stages for extreme parallelism
- Use build caching (NuGet lock files, deterministic builds) to avoid rebuilding unchanged projects
- works well with structured CI pipelines
dotnet build /graph
- 在CI中使用参数(许多CI运行器配备多核CPU)
-m - 为实现极致并行性,可考虑将解决方案拆分为多个构建阶段
- 使用构建缓存(NuGet锁定文件、确定性构建)避免重新构建未变更的项目
- 适用于结构化CI流水线
dotnet build /graph