有谁见过不同程序的真实世界数字,这些程序使用 C/C++ 编译器提供的反馈优化来支持分支预测、缓存预加载功能等。
我搜索了它,令人惊讶的是,即使是流行的解释器开发小组似乎也没有检查过效果。并且将 ruby、python、php 等性能提高 10% 左右应该被认为是有用的。
真的没有任何好处,还是整个开发者社区都懒得使用它?
10% 是一个不错的大概数字。 也就是说,...
你必须真正关心性能才能走这条路。 我从事的产品 (DB2) 使用 PGO 和其他侵入式和攻击性优化。 其中成本包括大量的构建时间(在某些平台上是三倍)以及开发和支持噩梦。
当出现问题时,将优化代码中的故障位置映射回源头可能并不简单。 开发人员通常不会期望不同模块中的函数最终可以合并和内联,这可能会产生“有趣”的效果。
指针别名问题很难追踪,通常也会出现在这些类型的优化中。 您可以享受非确定性构建的额外乐趣(别名问题可能会出现在周一的构建中,直到周四再次消失,...)。
在这些激进的优化下,正确或不正确的编译器行为之间的界限也变得相当模糊。 即使有我们的编译器人员在内部(字面意思),优化问题(无论是在我们的源代码还是编译器中)仍然不容易理解和解决。
来自 unladen-swallow(优化 CPython VM 的项目):
对我们来说,PyBench 棺材上的最后一颗钉子是在尝试 gcc 的反馈导向优化工具时,我们能够在整个宏基准测试中实现 15% 的通用性能提升;使用相同的训练工作负载,PyBench 慢了 10%。
所以至少有些人正在关注它。也就是说,PGO 对构建环境提出了一些相当棘手的要求,这些要求对于由分布式异构人群构建的开源项目来说很难满足。大量优化也会造成难以调试的 heisenbug。为编译器提供有关性能关键部分的显式提示的工作量更少。
也就是说,我预计运行时配置文件引导优化会显着提高性能。 JIT'ing 允许优化器应对程序执行过程中数据变化的情况,并执行许多极其特定于运行时数据的优化,这会增加静态编译的代码大小。特别是动态语言需要良好的基于运行时数据的优化才能表现良好。随着动态语言性能最近受到广泛关注(JavaScript VM、MS DLR、JSR-292、PyPy 等),该领域正在进行大量工作。
通过性能分析来提高编译器效率的传统方法是通过性能分析工具来完成的。但是,工具中的数据如何用于优化仍然取决于您使用的编译器。例如,GCC 是一个正在开发的框架,用于为不同领域生成编译器。在这样的编译器框架中提供分析机制将非常困难。
我们可以依靠统计数据来做一定的优化。例如,如果循环计数小于常量(例如 7),GCC 就会展开循环。它如何修复该常数将基于针对不同目标架构生成的代码大小的统计结果。
配置文件引导优化跟踪源的特殊区域。需要存储有关先前运行结果的详细信息,这是一项开销。另一方面,输入需要可能使用编译器的目标应用程序的统计表示。因此,复杂程度随着不同输入和输出的数量而增加。简而言之,决定配置文件引导优化需要大量的数据收集。自动化或将此类分析嵌入到源代码中需要仔细监控。如果不是,整个结果就会出错,在我们努力游泳的过程中,我们实际上会被淹死。
不过,这方面的实验正在进行中。看看POGO。