Static initializer in Mac OS/android
Mozilla engineers can improve Firefox startup speed by optimizing static initializer (static initialization, or global constructor) and binary layout. Based on x86 and x86-64 platform, the binary layout of Mac OS and Android is added below.
What is static initializer? In short, it is the initialization of the global C ++ object. Someone laughed and said that before the main () function of a C ++ program is executed, all operations may have been completed, which is the impact of static initializer. If there is another layer-by-layer dependency reference, the startup time will be greatly affected. The following is an example program:
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…}
The first two objects oneclass and twoclass are two objects that use static initialization, And the foo function forces the object to be placed in the init segement of the program through the compilation option, the program will be executed during initialization. The following figure shows the final layout on Mac OS: In Android arm elf, the layout is as follows:
Firefox OptimizationIn Mozilla engineer's article [LINK], test data on x86 and x86-64 Based on Firefox 4.0b8 found the following average start time:
|
Average start time (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 |
Use systemtap [LINK] to obtain an access pattern for accessing the core library Libxul. So:
- Red points indicate the number of pages loaded from the disk
- The red line is the location (seek) operation in the file.
- The color block in the background represents. Rel. Dyn/. Rela. Syn (red),. Text (pink),. rodata (green),. Data. Rel. Ro (light green ).
Static initializers
At the beginning, the vertical line segments are exactly the time when static initializers runs, which takes a lot of time. The solution is to reduce static initializers and pay special attention to global and static variables.
This method is used to analyze a total of 237 static initializers, 147 of which were introduced by cycle collection globals. After modification, the Global Object of cycle collection is reduced to one, but the overall situation has not changed significantly:
|
Average start time (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 |
The new I/O access pattern is as follows:
Although I/O is reduced, there are still many other read operations before static initialization, so there are other work to be done.
Reordering objects
Another task is to relay binary so that the data required by the kernel can be obtained as soon as possible. A previous study of Taras found that only some changes on the toolchain can be implemented.
After Optimization Using icegrind of Taras, the improvements become obvious:
|
Average start time (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 |
I/O pattern:
Packing relocations
Finally, you can reduce the relocation segment to optimize the startup time. This effectively reduces I/O, dynamic relocations section, and packages. Here is the tool I used. Reference: the final effect is as follows:
|
Average start time (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 |
I/O pattern is as follows:
This is an obscure topic. It is worth further research and can be started from the links provided by the author. My skills are limited and I look forward to a more in-depth explanation.
Reprinted please indicate the source: http://blog.csdn.net/horkychen
Reference
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