上海启嘟渡科技商贸有限公司
SEARCH

与我们合作

我们专注提供互联网一站式服务,助力企业品牌宣传多平台多途径导流量。
主营业务:网站建设、移动端微信小程序开发、营销推广、基础网络、品牌形象策划等

您也可通过下列途径与我们取得联系:

微 信: wxyunyingzhe

手 机: 15624122141

邮 箱:

利用 PGO 提升 .NET 程序性能

更新时间:2025-01-10 14:17:11

.NET 6开始引入了PGO(Profile Guided Optimization),这是一种通过收集运行时信息来指导JIT如何优化代码的技术。相比之前没有PGO的情况,现在可以完成更多以前难以完成的优化。

为了测试.NET 6中的PGO,我们使用了nightly build版本6.0.100-rc.1.21377.6。

.NET 6提供了静态PGO和动态PGO。静态PGO通过工具收集profile数据,然后应用到下一次编译中,指导编译器进行代码优化;动态PGO则直接在运行时收集profile数据并进行优化。此外,从.NET 5开始引入了OSR(On Stack Replacement),可以在运行时替换正在运行的函数,允许将低优化代码迁移到高优化代码。

.NET从Core 3.1开始引入了分层编译,程序启动时JIT首先快速生成低优化的tier 0代码,随着程序运行,对多次调用的方法进行再次JIT产生高优化的tier 1代码。然而,这样做对于程序的性能几乎没有提升,只是改善了延时。因此,在开发客户端类程序时通常关闭分层编译,而在开发服务器程序时开启分层编译。.NET 6引入PGO后,分层编译的机制变得非常重要。

由于tier 0的代码是低优化代码,因此更能够收集到完整的运行时profile数据,指导JIT做更全面的优化。例如,在tier 1代码中,某方法B被某方法A内联,运行期间多次调用方法A后收集到的profile将只包含A的信息,而没有B的信息;又例如在tier 1代码中,某循环被JIT做了loop cloning,那此时收集到的profile则是不准确的。

为了发挥PGO的最大效果,我们需要开启分层编译,并给循环启用Quick Jit在一开始生成低优化代码。

下面通过一个测试代码的例子来说明如何使用.NET 6的PGO。

测试环境:不使用PGO,关闭分层编译,使用动态PGO,使用静态PGO + AOT编译。

测试结果显示,启用PGO后,性能得到了显著提升,性能提升幅度达到了322%。

总结:有了PGO之后,之前的很多性能经验就不再有效。借助PGO,我们可以预见大幅度的执行效率提升。在后续版本中,.NET将会带来更多基于PGO的优化。

多重随机标签

猜你喜欢文章

QQ客服 电话咨询