基于分析数据的优化

通过分析引导优化(PGO),可以优化整个可执行文件。 优化器使用 .exe 或 .dll 文件测试运行中的数据。 这些数据表示程序在生产环境中的预期性能。

注意

SPGO(示例 Profile-Guided 优化)是使用硬件 CPU Windows性能计数器而不是检测的替代方法。 SPGO 无需插桩构建——你可以使用 xperf 对现有的发布版二进制文件进行性能分析。 有关更多信息,请参阅 示例配置文件引导优化(SPGO)教程

按配置优化仅适用于 x86、x64 或 ARM64 本机目标。 在公共语言运行时上运行的可执行文件无法使用分析引导优化。 即使生成包含本机代码和托管代码的混合程序集(使用 /clr 编译器选项),也无法仅对本机代码使用性能分析指导优化。 如果尝试使用 IDE 中设置的这些选项生成项目,会导致生成错误。

注意

从分析测试运行中收集的信息会替代在指定 /Ob/Os/Ot 时将生效的优化。 有关详细信息,请参阅 /Ob(内联函数扩展)/Os、/Ot(代码大小优先、代码速度优先)

优化应用的步骤

要使用配置文件引导的优化,请按照以下步骤优化您的应用:

  • 使用 /GL 编译一个或多个源代码文件。

    编译器会在配置文件引导的优化测试运行过程中检查使用 /GL 生成的每个模块,以收集其运行时行为信息。 无需使用 /GL 在配置文件引导式优化生成中编译每个模块。 但是,仅检测使用 /GL 编译的模块,稍后才可用于分析引导优化。

  • 使用 /LTG/GENPROFILE 或 /FASTGENPROFILE 进行链接。

    当你同时使用 /LTG/GENPROFILE/FASTGENPROFILE 时,检测的应用会在它运行时创建一个 .pgd 文件。 将测试运行数据添加到 .pgd 文件后,可以将它用作下一个链接步骤的输入(创建优化映像)。 指定 /GENPROFILE 时,可以选择添加 PGD=filename 参数来指定文件的非默认名称或位置 .pgd 。 /LTCG 和 /GENPROFILE 或 /FASTGENPROFILE 链接器选项的组合替换了已弃用的 /LTCG:PGINSTRUMENT 链接器选项。

  • 对应用程序进行性能分析。

    每次分析的 EXE 会话结束时或分析的 DLL 卸载时,进程都会创建一个 appname!N.pgc 文件。 .pgc 文件包含特定应用程序测试运行的相关信息。 appname 是应用的名称, N 是以 1 开头的数字。 它根据目录中其他 appname!N.pgc 文件的数量递增。 如果测试运行表示的不是你想要优化的方案,则可以删除对应的 .pgc 文件。

    在测试运行期间,可以使用 .pgc 实用工具强制关闭当前打开.pgc的文件和创建新文件(例如,当测试方案的末尾与应用程序关闭不一致时)。

    应用程序还可以直接调用 PGO 函数 PgoAutoSweep,以将调用时的配置文件数据作为 .pgc 文件进行捕获。 它可以使你更好地控制 .pgc 文件中的捕获数据所涵盖的代码。 有关如何使用此函数的示例,请参阅 PgoAutoSweep 文档。

    创建检测生成时,默认情况下,数据收集在非线程安全模式下进行,该模式速度更快,但可能不精确。 通过对 /GENPROFILE 或 /FASTGENPROFILE 使用 EXACT 参数,可以指定在线程安全模式下进行数据收集,该模式更精确,但速度更慢。 如果在创建检测生成时,设置了已弃用的 PogoSafeMode 环境变量或已弃用的 /POGOSAFEMODE 链接器选项,也可使用此选项。

  • 使用 /LTG/USEPROFILE 进行链接。

    同时使用 /LTCG/USEPROFILE 链接器选项来创建优化的映像。 此步骤将 .pgd 文件作为输入。 指定 /USEPROFILE 时,可以选择添加 PGD=filename 参数来指定文件的非默认名称或位置 .pgd 。 还可以使用已弃用的 /PGD 链接器选项指定此名称。 /LTG/USEPROFILE 链接器选项的组合取代了已弃用的 /LTG:PGOPTIMIZE/LTG:PGUPDATE 链接器选项。

甚至可以先创建一个经过优化的可执行文件,之后再发现,进行更多性能分析将有助于创建一个更优化的映像。 如果检测到的映像及其.pgd文件可用,则可以使用相同的 .pgd/USEPROFILE 链接器选项执行更多测试运行,并使用较新的文件重新生成优化映像。

注意

.pgc.pgd 文件都是二进制文件类型。 如果将它们存储在源代码管理系统中,请避免对文本文件进行的任何自动转换。

PGO 执行的优化措施

按配置文件引导的优化包括以下检查和改进:

  • 内联 - 例如,如果函数 A 经常调用函数 B,并且函数 B 相对较小,那么基于性能分析的优化会将函数 B 内联到函数 A 中。

  • 虚调用推测 - 如果某个虚调用或其他通过函数指针实现的调用频繁指向特定函数,配置文件指导优化可以将一个按条件执行的直接调用插入到该频繁指向的函数中,并且可以将该直接调用内联。

  • 寄存器分配 - 使用配置文件数据进行优化,可以实现更好的寄存器分配。

  • 基本块优化 - 使用基本块优化,可以将暂时在给定框架内执行的经常执行的基本块放在同一组页面(区域)中。 它可以让使用的页数减至最少,从而使内存开销最少。

  • 大小/速度优化 - 对于耗费程序大多数执行时间的函数,可以对其进行优化以加快速度。

  • 函数布局 - 根据调用关系图和经过分析的调用方/被调用方行为,将倾向于沿相同路径执行的函数放在同一段中。

  • 条件分支优化 - 使用值探测,按配置优化可以确定 switch 语句中的给定值是否比其他值更常用。 然后,可以从 switch 语句中取出此值。 同样的优化也可以通过使用 if...else 指令来实现,其中优化器可以对 if...else 进行排序,从而将 ifelse 代码块中的一个放在前面,具体取决于哪个代码块对应的条件更常为真。

  • 死代码分离 - 基于性能分析的优化会将性能分析过程中未被调用的代码移到该节集合末尾的一个特殊节中。 它可以有效地将该段排除在常用页面之外。

  • EH 代码分隔 - 由于 EH 代码仅在异常情况下执行,因此通常可以将它移动到单独的部分。 基于配置文件的优化在确定只有在异常情况下才会发生异常时,会将其移走。

  • 内存内部函数 - 是否扩展内部函数取决于它是否经常被调用。 也可根据移动或复制的块大小对内部函数进行优化。

后续步骤

若要详细了解可在配置文件引导优化中使用的这些环境变量、函数和工具,请参阅以下资源:

用于性能分析引导优化的环境变量
这些变量指定测试方案的运行时行为。 它们现在已不推荐使用,并已被新的链接器选项取代。 本文档演示如何从环境变量转向链接器选项。

PgoAutoSweep
一个函数,可以添加到应用以提供细化 .pgc 文件数据捕获控制。

pgosweep
一个命令行实用工具,可将所有配置文件数据写入 .pgc 文件,关闭 .pgc 文件,然后打开新的 .pgc 文件。

pgomgr
一个命令行实用工具,可将一个或多个 .pgc 文件中的配置文件数据添加到 .pgd 文件。

如何将多个 PGO 配置文件合并为一个配置文件
pgomgr 的用法示例。

示例配置文件引导优化(SPGO)教程
使用 CPU 硬件性能计数器而不是检测。 无需插桩构建 - 使用 xperf 对现有发布版二进制文件进行性能分析。

另请参阅

其他 MSVC 生成工具