Firefox OS/Performance/Boot Sequence Optimization
Initial Ideas
- Minimize data loaded by boot loader.
- Compacting vmlinuz/zImage by moving compiled-in drivers to modules.
- Minimize initial ramdisk if there is one.
- Minimize kernel cruft by excluding all unneeded drivers.
- Strip the kernel and all modules.
- Minimize init launch sequence.
- Make init only launch the bare minimum for b2g process to launch.
- Ideally, init will only launch b2g.
- B2G start-up sequence.
- Remove all synchronous external dependencies from B2G start-up sequence.
- Kernel modules must be lazy loaded as needed.
- Any sync waits on daemons must become async. Start-up b2g pieces as daemons finish launching.
- Minimize start-up initializations.
- Global statics need to be minimized as their constructors are run before main().
- Global singletons must be initialized as needed.
- Remove all synchronous external dependencies from B2G start-up sequence.
- Homescreen start-up.
- Minimize _init() code to bare minimum.
- Maybe freeze the homescreen app into a memory image that can be loaded and unfrozen instead of launching the app every time.
- Eliminate dependency on enumerating installed apps on launch.
- Cache the list in local storage?
- Cache the list in the frozen memory image?
- Speed up mgmt.getAll()
The Plan
FirefoxOS/Performance/Boot_Profiling
Bootchart
Some example preliminary data collected via bootchart here.
To enable the collection of bootchart data in FireFox OS one must build init with the following environment variable set.
INIT_BOOTCHART=true
Once init has been replaced on the device (see process here), to enable logging one simply creates a file |/data/bootchart-start| on the device containing an integer representing the number of seconds for which bootchart should collect data, and then reboot the device.
Bootchart data is pulled from the device with the system/core/grab-bootchart.sh script, and presented in the form of a bootchart.tgz file. With the data collected one can then generate graphs by invoking:
java -jar bootchart.jar -f eps bootchart.tgz
Without the |-f eps| parameters, the default is for a PNG to be generated. The SVG format is also supported.
Note that the charts generated by the stock bootchart.jar do not seem to include disk stats. This is because it does not recognize the mmcblkNpM format of partition names, and this can easily be fixed in the bootchart source code ( in particular, at |bootchart-0.9/src/org/bootchart/parser/linux/ProcDiskStatParser.java| ).
Data
Data collected are organized as follows:
repo-state -> Information about the state of the source tree that applies to this experiment. Note that things such as changes in init.rc, kernel arguments would not be visible in this manifest.xml -> Repository info auto-generated by repo. This can be used with repo to reset the tree (not including changes to the working tree) experi-info -> Information about this particular experiment N/ -> Each of the numbered directories represent one sample of data N/bootchart.N.tgz -> Bootchart archive encapsulating the data that was collected N/kmsg.N -> A dump of the kernel logs of the device Contains timestamp for when init has started, and time stamp for when b2g.sh is run by init (and misc. other component initialization) N/logcat.N -> A dump of the android logs of the device Contains timestamp of when b2g has started (which is also useful to synchronize with kernel log times) (since logcat logs time absolutely, and kmsg as an offset from startup N/rebootstamp.N -> Local unix time recorded directly after an adb reboot to approximate time of boot N/synchstamp.N -> Kernel logs are time since boot and so are the process start times, this file contains the local time and the current device uptime so that one may determine when the kernel logs were initialized
Old Baseline statistics These results were collected but then i decided to base my experiments on a slightly newer baseimage
This is data collected for the purposes of establishing a baseline. For this and future data collection, at least 30 trials will be recorded. Also in the root directory there are a few randomly selected trials for which charts were generated for quick reference.
A rough idea of what we are seeing currently, as well as empirical hypotheses (Have i found my 5 seconds yet?):
- B2G starts after roughly 8s of mysterious "stuff"
- It has been noted that time between 5s and 8s is likely script execution up until |class_start main| in the init.rc
- Vertical comes up around 16s, however it does not seem to actually do anything until several seconds after that.
- As well it seems init is only really alive at 4 seconds anyway (based on inserted kernel log output)
- As such it is likely that
- -3.5s = bootloader + Early kernel
- 0s = kernel timing initialized
- ~4.5s = init main
- 7~8s = B2G
- ~14s = (Nuwa)
- ~16s = Vertical
- ~25s = Lockscreen presented to user
Of course, more concrete data will be explored later, but that is the general gist of things. Note the discrepancy between the vertical process coming up and actual availability, that will be the focus of a future investigation.
In this simple experiment only a change to "init.rc" was made. By default b2g was started along with a host of other services in the same class "main". For this experiment B2G was moved into its own class that was run just before main. As expected this did not have significant effect however. Quantitatively one does notice a difference in the bootchart images reflecting B2G being started slightly earlier. Of note is that as a result of this change, there is a more pronounced black screen between the T2mobile and the "Mozilla Developer Network" logos. Dave Huseby has noted in the past that such a noticeable black screen exists in other devices.
The next step is to determine if there are any dependencies such that B2G can't be moved even further back (and if this is done, take care of the black screen somehow)