Mac OS/Android在下面Static Initializer
Mozillaproject师通过优化Static Initializer(静态初始化,或全局建构函数, Global Constructor)和Binary布局来提升FireFox启动速度的文章。很有參考价值。
文章中以x86及x86-64平台为基础,以下加了Mac OS及Android上的binary布局。
什么是Static Initializer? 简而言之就是全局C++对象的初始化。
有人笑称一个C++程序的main()函数运行之前,可能该做事都做完了。这就是Static Initializer的影响。假设里面又有一层层依赖引用,就会大大影响启动时间。以下是一个演示样例程序:
MyClass oneClass(0x010203); const MyClass twoClass(0x010204); attribute ((constructor)) void foo(void) { printf(“foo is running and printf is available at this point\n”); } int main(int argc, const char * argv[]) { //do something here… }
前两个对象oneClass和twoClass即是使用了静态初始化的两个对象, 而foo函数则通过编译选项强制放到程序的初始化段(init segement)中,在程序初始化时就会运行。以下即终于在Mac OS上的布局: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvSG9ya3lDaGVu/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" /> 在Android ARM ELF中则是以下这个布局:
FireFox的优化
在Mozillaproject师的文章[p=1296">链接]中,基于Firefox 4.0b8在x86及x86-64的測试数据发现例如以下的平均启动时间:
平均启动时间(ms) | Pages Read | Bytes Read | |
x86 | 3,228.76 ± 0.57% | 4,787 | 19,607,552 |
x86-64 | 3,382.0 ± 0.51% | 5,874 | 24,059,904 |
- 红点表示从磁盘载入的页数
- 红线则是在文件里的定位(seek)操作
- 背景中的色块代表了.rel.dyn/.rela.syn(红色)。.text(粉色),.rodata(绿色),.data.rel.ro(淡绿色)。
Static Initializers
在開始时那些垂直的线段正是Static Initializers运行的时间,占去了不少的时间。解决之道就是降低static initializers。特别留心那些全局变量、静态变量。 以这样的方法分析了一下,一共同拥有237个static initializers,当中147是由cycle collection globals所引入的。经过修正后cycle collection的全局对象降到一个,整个情况并未有大的改观:平均启动时间(ms) | Pages Read | Bytes Read | |
x86 | 3,216.1 ± 0.59% | 4,656 | 19,070,976 |
x86-64 | 3,488.14 ± 0.75% | 5,759 | 23,588,864 |
Reordering objects
还有一工作即是又一次布局binary, 让内核须要的数据能够尽快获取。之前Taras的一个研究发现仅仅要做些toolchain上的变更就能够实现。 使用Taras的icegrind做了优化后。改进变得明显了:平均启动时间(ms) | Pages Read | Bytes Read | |
x86 | 2,939.18 ± 0.81% | 4,129 | 16,912,384 |
x86-64 | 3,247.64 ± 0.68% | 5,254 | 21,520,384 |
Packing Relocations
最后,再能够通过降低relocation段。来优化启动时间。 这样能够有效降低I/O,以及dynamic relocations section,也能减小程序包。 我使用的工具在这里。 參考:关于通过调整ELF优化启动时间 以下是终于的效果:平均启动时间(ms) | Pages Read | Bytes Read | |
x86 | 3,149.32 ± 0.62% | 4,443 | 18,198,528 |
x86-64 | 3,191.58 ± 0.62% | 4,733 | 19,386,368 |
參考
1. How to Make Startup Suck Less (Also Reduce Memory Usage!) 2. Death by static initialization 3. icegrind - Valgrind Plugin for optimizing Cold Startup 4. Resolving ELF Relocation Name / Symbols 5. Static initializers 6. ELF for ARM Architecture版权声明:本文博主原创文章,博客,未经同意不得转载。
时间: 2024-09-29 09:01:51