PGO - Profile-guided optimizations

Posted rtoax

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PGO - Profile-guided optimizations相关的知识,希望对你有一定的参考价值。

Profile Guided Optimization (PGO) – Under the Hood - C++ Team Bloghttps://devblogs.microsoft.com/cppblog/profile-guided-optimization-pgo-under-the-hood/Profile Guided Optimization (PGO) - C++ Team Bloghttps://devblogs.microsoft.com/cppblog/profile-guided-optimization-pgo/Profile-guided optimizations | Microsoft DocsLearn more about: Profile-guided optimizationshttps://docs.microsoft.com/en-us/cpp/build/profile-guided-optimizations?view=msvc-170

PGO是一种运行时编译器优化,它利用从运行重要且以性能为中心的用户场景中收集的配置文件数据来构建应用程序的优化版本。PGO 优化与传统的静态优化相比具有一些显着优势,因为它们基于应用程序在生产环境中的可能执行方式,这允许优化器针对较热的代码路径(常见用户场景)优化速度并针对较冷的代码优化大小路径(不那么常见的用户场景)导致为应用程序生成更快和更小的代码,从而显着提高性能。

入门

最佳实践

  • [将于 2013 年 4 月出版:PGO 最佳实践、提示和技巧]
  • [将于 2013 年 4 月发布:如何分析使用 PGO 时的训练场景]

视频资源

社区

在社区中了解有关 PGO、C++ 和相关开发人员和技术主题的更多信息。我们很幸运拥有许多充满活力的社区和数百名愿意参与的聪明、乐于助人的成员。

  • 在FacebookTwitter上关注 Visual C++ 团队,获取提示、技巧、更新、链接、问题和其他信息。
  • 在MSDN 论坛Stack Overflow上提问(并查看其他人的提问)。
  • 了解 Microsoft C++ MVP在做什么。
  • 参加本地用户组会议。参加像//build/这样的会议。
  • 直接向Ping  Ankit Asthana (PGO PM) 提出问题、评论、对未来内容的想法以及您可能拥有的任何其他反馈。

自我介绍一下,我是Ankit Asthana,我是后端 C++ 编译器的程序经理。在我最近的几篇博客中,我介绍了 PGO 的全部内容以及案例研究,这些案例研究涵盖了如何使用Profile Guided Optimization (PGO)使SAP NetWeaverWindows PHP 等现实世界的应用程序更快在这篇博客中,我想谈谈 PGO 如何在后台工作并帮助生成更快的代码。因此,让我们看看 PGO 如何帮助编译器后端构建应用程序的优化版本。一旦我们了解了 PGO 优化的工作原理,我们就可以了解 PGO 如何使应用程序更快。所以让我们开始吧!

PGO 如何帮助构建更精简、更快的原生应用程序?

继续我的第一篇博客,让我们再次看一下以下代码片段:

回想一下,PGO 通过利用从运行以性能为中心的用户场景中收集的配置文件数据来帮助优化应用程序。PGO'izing 应用程序需要三个基本步骤(仪器、训练和优化)。检测应用程序意味着使用特殊的编译器/链接标志进行构建,这些标志将探针插入到生成的代码中。然后,这些探测器在训练阶段被击中时会收集数据,这些数据提供有关在whichBranchIsTaken代码片段中采用哪个分支的信息,或者作为示例,去虚拟化代码片段中*p的通常值是什么。探针在训练阶段收集的这些数据被转储到数据库文件*.pgd然后将其作为 PGO 优化阶段的输入提供给编译器。

在 PGO 的优化阶段,数据库文件中收集的数据用作优化列表的输入(下表 1,如下)。尽管数据库文件被用作许多优化的输入,但基于内联和布局的 PGO 优化提供了大部分性能提升,因此让我们看看收集的训练数据如何有助于更好地内联和基于布局的决策。

 表 1: 从 PGO 获得的一些优化
Full and Partial InliningFunction LayoutSpeed and Size decision
Basic Block LayoutCode SeparationVirtual Call Expansion
Switch ExpansionData SeparationLoop Unrolling

PGO 的内联决策基于调用图路径分析。简而言之,使用调用图路径分析进行内联决策背后的基本原则是了解从特定调用路径调用的函数的行为。这很重要,因为来自一个调用路径的函数调用行为可能与另一个调用路径截然不同。了解哪个调用路径更热有助于更好地内联决策,因为优化器仅内联频繁调用路径,从而最大限度地减少内联导致的代码膨胀,但仍通过内联更热的调用路径获得性能。看看下面给出的例子: 

     图 1a:从“goo”、“foo”和“bat”调用函数“bar”的顺序

 上面图 1a 中描述的示例说明了从函数“goo”、“foo”和“bat”对函数“bar”进行的函数调用。边缘的数字表示分别从函数“goo”、“foo”和“bat”调用函数“bar”的次数。因此,从函数“goo”到函数“bar”的边表示对于给定的 PGO 培训课程,函数“bar”被函数“goo”调用了 10 次。现在调用图路径分析就是从特定调用路径中找出函数调用的行为。因此,图 1a 将进一步分解为图 1b。

图 1b:从“goo”、“foo”和“bat”调用函数“bar”的序列 从“bar”调用函数“baz”的序列

 分析图 1b 很明显,考虑到从 'bat' 到 'bar' 的调用频率更高,即 100 次调用,主要好处将来自内联函数 'bar' 到 'bat'。此外,考虑到从调用路径“goo-bar”和“foo-bar”对函数“baz”的高频率调用,另一个主要优势将来自内联“baz”到“bar”中也很明显。pgo-inlining 对上述场景的影响如下图 1c 所示。

  图 1c:PGO 内联的影响,“bar”被内联到“bat”,“baz”被内联到“bar”。

 内联决策是在布局、速度与大小决策以及所有其他优化之前做出的。现在,从我的上一篇博客中,让我们回顾一下优化 PGO 构建的输出(图 2)。    

 “速度与大小”决策基于内联后动态指令计数。具有较高动态指令计数的代码段(即函数)针对速度进行了优化,而具有较低动态指令计数的代码段针对大小进行了优化。在上面图 2 所示的构建输出中,将编译 3619 个(0.17%)个配置文件中的 6 个函数以提高速度,其余函数将针对大小进行编译,这是该决策过程的结果。速度和大小决定之后是“块布局”“实时和场景死代码分离”优化。基本块是有序的,以便最频繁的路径通过(图 3)。执行实时和场景死代码分离以最小化工作集并提高代码局部性。场景失效(即在训练场景中未执行)的代码(功能/块)被放置在一个特殊的部分(图 4)。

 最后,基于post-inliner和post-code-separation,进行调用图profile数据函数布局。仅布置了实时部分中的功能。不包括死块。函数布局背后的总体策略是将强连接(高频相互调用)的函数放在一起。如果被调用者位于同一页面中,则调用应该具有页面局部性。请看下面图 6 中的示例:

基于训练数据执行的一些其他优化是 switch case 扩展和虚拟调用推测。switch case 扩展优化使用 PGO 收集的最常见的 switch 表达式值,并将其从 switch 构造中提取出来。看看在执行 switch case 扩展优化时,如何使用 PGO 数据优化本博客开头提供的代码片段。 

包起来

尽管配置文件引导优化 (PGO) 是一项复杂的技术,但本博客应该让您了解配置文件引导优化的有用性以及 PGO 如何在后台工作以使大量产品更具性能。在我未来的博客中,我将尝试介绍一个最佳实践指南,其中涵盖常见的陷阱并重点介绍一些针对 PGO 用户的提示和技巧。所以敬请期待!此外,如果您希望我们在博客中介绍其他一些与 PGO 相关的场景,请告诉我们。

原理图概览

 

以上是关于PGO - Profile-guided optimizations的主要内容,如果未能解决你的问题,请参考以下文章

利用 PGO 提升 .NET 程序性能

Rust 编译器探索使用 PGO

一探即将到来的 C# 10

译.NET 7 中的性能改进

错误 # args: 应该是“_o3 self class proc file optx opty”

JS 循环遍历JSON数据 分类: JS技术 JS JQuery 2010-12-01 13:56 43646人阅读 评论 收藏 举报 jsonc JSON数据如:{"opti