基于 Xcode 自带工具 PGO 优化启动时间

Profile Guided Optimization (PGO) is a high-performance optimization tool that is easy to set up and use. In this chapter, you’ll see all the steps needed to use PGO.

跟二进制重排原理好像很类似,都是降低Page In次数来提速。这个方案非常简单,比起找启动函数,配置order文件要方便的多。

PGO配置

PGO是苹果官方提供的工具,具体使用方法是点击xcode工具栏 Product -> Perform Action -> Generate Optimization Profile 按xcode提示操作即可。

点击Run后待项目启动完成后,点击xcode的停止按钮,项目中会自动添加一个OptimizationProfiles文件夹。在build setting中搜索 Use optimization Profile,将release配置为yes,需要注意的是,苹果文档中说明,PGO只支持release环境

查看项目Page In次数

配置PGO完成后可以用instruments查看项目pageIn次数。效果相当可观。

具体操作步骤 点击xcode工具栏Open Developer Tool -> instruments -> System trace

点击红色按钮等待项目完全启动完毕,再点击暂停按钮,得到分析数据,搜索main Thread

每次启动得到的Page In次数并不会完全相同,这取决于app占用的物理内存是否已经被覆盖。杀死app之后,app的物理内存有可能还在。

优化配置文件数据文件

优化配置文件是一个扩展名为.profdata. Xcode 将.profdata文件写入项目中优化配置文件文件构建设置指定的位置,默认情况下,在OptimizationProfiles添加到项目中的名为的文件夹中。文件夹和文件出现在项目导航器中,如下例所示:

优化配置文件有效性

随着继续开发和更改应用项目中的代码,优化配置文件会过时。

LLVM 编译器会识别出配置文件何时不再与应用程序的当前状态良好匹配,并提供警告。当收到此警告时,可以再次使用 Generate Optimization Profile 命令来创建更新的配置文件。

每次重新生成优化配置文件时,Xcode 都会替换现有的配置文件数据。

苹果官方PGO 和 二进制重排的区别

PGO (Profile-Guided Optimization) 和二进制重排 (Binary Reordering) 是两种优化程序性能的技术,但它们的操作方式有所不同。

PGO 是编译器的一个特性,它通过对程序的实际执行进行采样,找出最常执行的代码路径,并根据这些信息对程序进行优化。这种优化可以包括重新编排代码以减少分支预测错误,优化内存使用以提高缓存命中率等。这是一种动态优化技术,因为它需要实际运行程序才能收集到优化所需的信息。

二进制重排则是在程序编译完成后,对二进制代码进行优化的技术。它的主要思想是将最常执行的代码块放在一起,这样可以减少指令缓存的错失率,提高程序的执行效率。这是一种静态优化技术,因为它不需要实际运行程序就能进行。

虽然这两种技术的目标都是优化程序性能,但它们的适用情况不同。PGO 需要有实际运行的程序才能进行,所以对于那些不能或不方便进行实际运行的程序,可能就无法使用 PGO。而二进制重排则不需要程序的实际运行,因此在某些情况下可能更适合使用。

同时,这两种技术并不是互斥的。实际上,很多优化技术都可以并用,以达到更好的优化效果。在一些情况下,可以先使用 PGO 对程序进行优化,然后再使用二进制重排进一步提高程序的执行效率。

为什么我的App需要重排的符号个数这么少

二进制重排(Binary Reordering)主要通过调整二进制文件中的代码顺序,以改善性能。它依赖于识别出程序中最常使用或热门的代码路径,然后将这些路径的代码放在一起,以减少CPU的缓存未命中率。

然而,虽然理论上所有的代码都可以进行重排,但实际上,根据应用程序的特性,可能只有一部分代码是频繁执行的,也就是所谓的"热点"代码。这部分代码会被优先考虑进行重排,因为这样可以最大化性能提升。

另外,重排过程需要考虑到许多限制和约束,如符号之间的依赖关系,这可能会限制哪些符号可以移动和重新排序。如果一些符号因为它们之间的关系而不能被移动,那么这些符号就不会被考虑在重排中。

因此,你看到的"需要重排的符号个数"相对较少,可能是因为只有这些符号是被识别出来的"热点"代码,或者它们是唯一可以在不违反任何约束和限制的情况下被移动的符号。