/MP
(使用多个进程生成)
/MP
选项可缩短在命令行上编译源文件的总时间。 /MP
选项将使编译器在每个单独进程中创建一个或多个自身副本。 然后,这些实例将同时编译源文件。 在某些情况下,可以显著减少生成源文件的总时间。
语法
]$
参数
processMax
(可选)编译器可以创建的最大进程数。
processMax
参数的范围必须介于 1 到 65536。 否则,编译器会发出警告消息 D9014,忽略 processMax
参数,并假定最大进程数为 1。
如果省略 processMax
参数,编译器会从计算机的操作系统中检索 有效处理器 的数目,并为每个处理器创建一个进程。
备注
/MP
编译器选项可以在编译多个文件时显著缩短生成时间。 为了缩短生成时间,编译器最多会创建 processMax
个其自身的副本,然后同时使用这些副本来编译您的源文件。 /MP
选项适用于编译,但不适用于链接或链接时间代码生成。 默认情况下,/MP
选项是关闭的。
生成时间的改善取决于计算机上的处理器数、要编译的文件数以及系统资源可用性,如 I/O 容量。 试验 /MP
选项,以确定生成特定项目的最佳设置。 获取帮助你做出决定的建议,请参阅 准则。
不兼容的选项和语言功能
/MP
选项与一些编译器选项和语言功能不兼容。 如果将不兼容的编译器选项与 /MP
选项一起使用,编译器会发出警告 D9030 并忽略 /MP
选项。 如果你使用不兼容的语言功能,编译器会发出错误 C2813,然后结束或继续,具体取决于当前编译器警告等级选项。
注意
大多数选项不兼容,因为如果允许这些选项,并发执行的编译器会将其输出同时写入控制台或特定文件。 因此,输出会互相混合,产生混淆。 在某些情况下,选项组合会使性能变得更糟。
下表列出了与 /MP
选项不兼容的编译器选项和与语言功能:
选项或语言功能 | 说明 |
---|---|
#import 预处理器指令 |
将类型库中的类型转换为 C++ 类,然后将这些类写入头文件。 |
%> | 将预处理器输出复制到标准输出 (stdout )。 |
/Gm |
已弃用。 启用增量重新生成。 |
/showIncludes |
将包含文件的列表写入标准错误 (stderr )。 |
/Yc |
编写预编译头文件。 |
诊断消息
如果指定与 /MP
选项不兼容的选项或语言功能,将收到一条诊断消息。 下表列出了编译器的消息和行为:
诊断消息 | 说明 | 编译器行为 |
---|---|---|
C2813 | #import 指令与 /MP 选项不兼容。 |
除非另外指定了 编译器警告等级 选项,否则编译终止。 |
D9014 | 为 processMax 参数指定了无效值。 |
编译器将忽略无效值,并假定值为 1。 |
D9030 | 指定选项与 /MP 不兼容。 |
编译器忽略 /MP 选项。 |
准则
测量性能
使用总生成时间来测量性能。 可以使用物理时钟测量生成时间,或使用能够计算生成启动和停止之间的时间差的软件。 如果计算机具有多个处理器,物理时钟测量结果可能会比软件时间测量结果更准确。
有效处理器
计算机的每个物理处理器可具有一个或多个虚拟处理器,又称为有效处理器。 每个物理处理器可具有一个或多个核心,如果操作系统为核心启用了超线程,则类似于每个核心具有两个虚拟处理器。
例如,如果某计算机具有一个物理处理器,该物理处理器有一个核心,并且禁用了超线程,则这台计算机具有一个有效处理器。 相反,如果某计算机具有两个物理处理器,每个物理处理器有两个核心,且所有核心均已启用超线程,则这台计算机具有八个有效处理器。 也就是说,(8 个有效处理器)=(2 个物理处理器)x(2 个核心/物理处理器)x(2 个有效处理器/核心,由于启用了超线程)。
如果省略 /MP
选项中的 processMax
参数,编译器会从操作系统获取有效处理器数目,然后为每个有效处理器创建一个进程。 但是,编译器无法保证特定处理器上执行的是哪个进程;该决策由操作系统做出。
进程数
编译器计算将用于编译源文件的进程数。 该值是在命令行上指定的源文件数和使用 /MP
选项显式或隐式指定的进程数中较小的值。 如果提供 /MP
选项的 processMax
参数,可以显式设置最大进程数。 如果省略 processMax
参数,则可以使用默认值,默认值等于计算机中的有效处理器数。
例如,假设指定以下命令行:
cl /MP7 a.cpp b.cpp c.cpp d.cpp e.cpp
在本例中,编译器使用五个进程,因为它是五个源文件和最多七个进程中的较小值。 或者,假设计算机具有两个有效处理器,并且指定以下命令行:
cl /MP a.cpp b.cpp c.cpp
在本例中,操作系统报告两个处理器,因此编译器在计算过程中使用两个进程。 因此,编译器将使用两个进程执行生成,因为它是两个进程和三个源文件中的较小值。
源文件和生成顺序
可能无法按照源文件显示在命令行上的相同顺序对源文件进行编译。 虽然编译器创建了一组包含编译器副本的进程,但由操作系统安排每个进程的执行时间。 /MP
选项无法保证按特定顺序编译源文件。
在有可用于编译源文件的进程时编译源文件。 如果文件多于进程数,则可用进程会编译第一组文件。 当进程处理完以前的文件并可处理其中一个剩余文件时,将处理剩余的文件。
不要在命令行上多次指定同一源文件。 例如,如果某工具自动创建基于项目中依赖项信息的 makefile,可能会出现多个规范。 如果未指定 /MP
选项,编译器将按顺序处理文件列表,并重新编译每个出现的文件。 但是,如果指定了 /MP
选项,不同的编译器实例可能会同时编译相同的文件。 不同的实例可能会尝试同时写入相同的输出文件。 一个编译器将获得对输出文件独占写入访问权限并成功完成写入,而其他编译器实例则会失败并出现文件访问错误。
使用类型库 (#import
)
编译器不支持通过 /MP
开关使用 #import
指令。 如果可能,请执行以下步骤解决此问题:
将各种源文件中的所有
#import
指令移动到一个或多个文件,然后不使用/MP
选项编译这些文件。 将生成一组头文件。在剩余的源文件中,插入指定生成标头的
#include
指令,然后使用/MP
选项编译剩余源文件。
Visual Studio 项目设置
MSBuild 工具
Visual Studio 使用 MSBuild
工具 (msbuild.exe
) 生成解决方案和项目。 MSBuild 工具的 /maxcpucount:number
(或 /m:number
)命令行选项可以同时生成多个项目。 /MP
编译器选项可以同时生成多个编译单元。 如果它适用于你的应用程序,可以使用 /MP
和/或 /maxcpucount
缩短解决方案生成时间。
解决方案生成时间在一定程度上取决于执行生成的进程数。 /maxcpucount
MSBuild 选项的 number
参数指定同时生成的最大项目数。 类似地,/MP
编译器选项的 processMax
参数指定同时生成的最大编译单元数。 如果 /maxcpucount
选项指定了 P 项目,/MP
选项指定了 C 进程,P x C 个(最大数量)进程会同时执行。
决定使用 MSBuild 还是 /MP
技术的准则如下所示:
如果有许多项目,而每个项目中只有少数几个文件,请使用带有
/maxcpucount
选项的 MSBuild 工具。如果项目较少,而每个项目中有许多文件,请使用
/MP
选项。如果项目数和每个项目中的文件数相当,请同时使用 MSBuild 和
/MP
。 起初,将/maxcpucount
选项设置为要生成的项目数,并将/MP
选项设置为计算机上的处理器数。 测量性能,然后调整设置以生成最佳结果。 重复此过程,直到对总生成时间感到满意。