PGO 新玩法: 优化移动端 APP 性能和体积
文章目录
之前很多研究是针对大型应用而言,很少有关注移动端应用的影响,这里会同时关注两个主要的目标,安装包体积和冷启动耗时。
1、代码布局优化
函数布局(function layout) 优化,即函数重排(function reordering),把频繁执行(hot) 或连续执行的函数放到一起,让内存页更加紧凑,减少缺页中断的次数。当然还有代码块重排,以及内联(inlining) 的优化。
但之前很多研究是针对大型应用而言,很少有关注移动端应用的影响,这里会同时关注两个主要的目标,安装包体积和冷启动耗时。本文的内容来源于论文 《Optimizing Function Layout for Mobile Applications》。
PGO(Profile-Guided-Optimization) 的概念就不重复介绍了,之前的文章有写到过,主要是通过插桩或采样,拿到应用的运行时数据(代码块调用次数等),通过重排等手段来优化性能。
2、建立模型
尝试定义图,来建立优化的模型。这里会涉及到一点数学,在图中会标注写明公式的含义。
2.1、compression
按照压缩算法的实际实验,越多连续重复的字串挨在一起,压缩率就越高。依此,我们定义模型的优化指标,是高压缩率。
定义 U 为出现在不同函数 F 的相同指令,即目标为把有更多共同指令的函数放得更近。
但由于我们是需要考虑综合指标,即安装包体积和性能,所以最好是优先考虑把执行频繁的函数(hot) 排列到一起。
2.2、start-up
假设冷启动情况下,函数只在第一次执行时,需要从磁盘传递到主存,触发缺页中断,所以我们需要记录每个函数第一次执行的时间戳(timestamp)。按这种时间顺序执行的一连串函数称之为 trace,用符号 S 标识。
按下图分析,比较好的布局是按照 trace 的顺序排列函数,看起来缺页次数和时间的关系曲线会比较线性,不过我们的目标是使得这个关系曲线更加扁平。
如何让曲线更加扁平呢?那就是在某个时刻,让所需的 trace 都已经能在内存中拿得到,也就是缺页已经发生过,且尽可能少。
3、算法
这里的算法都直接在上图解释了,是一个递归不断划分成子问题优化的过程,最后再整合到一起。关于如何定义划分的收益,就是函数划分到另一部分的损耗,主要如下图,实际操作中,也可以像人工智能算法一样自己设置。
4、实现
那么该如何获取到函数第一次执行的时间等信息,就需要通过 PGO 的方式来进行了。
拿到大量的用户运行时执行数据后,就需要整合,文中会先进行冷启动耗时的优化,然后再在 LTO(Link-Time-Optimization,之前文章写过) 阶段对执行很少(cold) 的函数进行包体积优化。
5、效果
对于缺页次数的优化,比起按顺序平均布局函数,bps(模型算法) 的冷启动优化效果更好。
对于体积的优化,bpc(模型算法) 的体积减少效果也更好。
参考
文章作者 calssion
上次更新 2023-05-04