An orderfile is a list of symbols that defines an ordering of functions. One can make a static linker, such as LLD, respect this ordering when generating a binary.
Reordering code this way can improve startup performance by fetching machine code to memory more efficiently, since it requires fetching fewer pages from disk, and a big part of the I/O work is done sequentially by the readahead.
Code reordering can also improve memory usage by keeping the used code in a smaller number of memory pages. It can also reduce TLB and L1i cache misses by placing functions commonly called together closely in memory.
To generate an orderfile you can run the generate_orderfile_full.py
script. You will need an Android device connected with adb to generate the orderfile as the generation pipeline will need to run benchmarks on a device. The script will automatically verify the generated orderfile at the end of the process.
Example:
tools/cygprofile/generate_orderfile_full.py --target-arch=arm64 --use-remoteexec
You can specify the architecture (arm or arm64) with --target-arch
. For quick local testing you can use --streamline-for-debugging
. To build using Reclient, use --use-remoteexec
(Googlers only). There are several other options you can use to configure/debug the orderfile generation. Use the -h
option to view the various options.
NB: If your checkout is non-internal you must use the --public
option.
To build Chrome with a locally generated orderfile, use the chrome_orderfile_path=<path_to_orderfile>
GN arg.
To verify that an orderfile is valid for a given build, you can use the check_orderfile.py
script. This is useful to ensure that the orderfile is compatible with the version of the library you are building.
Example:
tools/cygprofile/check_orderfile.py --target-arch=arm64 \ -C out/Release --orderfile-path=clank/orderfiles/orderfile.arm64.out
Alternatively, you can use the --verify
flag with generate_orderfile_full.py
to build and verify in one step.
Orderfiles can be tested using Pinpoint. To do this, please create and upload a Gerrit change overriding the value of chrome_orderfile_path
to, for instance, //path/to/my_orderfile
(relative to src
), where my_orderfile
is the orderfile that needs to be evaluated. The orderfile should be added to the local branch and uploaded to Gerrit along with build/config/compiler/BUILD.gn
. This Gerrit change can then be used as an “experiment patch” for a Pinpoint try job.
Occasionally, an orderfile roll will cause performance problems on perfbots. This typically triggers an alert in the form of a bug report, which contains a group of related regressions like the one shown here.
In such cases it is important to keep in mind that effectiveness of the orderfile is coupled with using a recent PGO profile when building the native code. As a result some orderfile improvements (or effective no-ops) register as regressions on perfbots using non-PGO builds, which is the most common perfbot configuration.
If a new regression does not include alerts from the android-pixel6-perf-pgo (the only Android PGO perfbot as of 2024-06) then the first thing to check is to query the same benchmark+metric combinations for the PGO bot. If the graphs demonstrate no regression, feel free to close the issue as WontFix(Intended Behavior). However, not all benchmarks are exercised on the PGO bot continuously. If there is no PGO coverage for a particular benchmark+metric combination, this combination can be checked on Pinpoint with the right perfbot choice (example).
Finally, the PGO+orderfile coupling exists only on arm64. Most speed optimization efforts on Android are focused on this configuration. On arm32 the most important orderfile optimization is for reducing memory used by machine code. Only one benchmark measures it: system_health.memory_mobile
.
The generate_orderfile_full.py
script runs several key steps:
Build and install Chrome with orderfile instrumentation. This uses the -finstrument-function-entry-bare
Clang command line option to insert instrumentation for function entry. The build will be generated in out/arm_instrumented_out/
or out/arm64_instrumented_out
, depending on the CPU architecture (instruction set).
Run the benchmarks and collect profiles. These benchmarks can be found in orderfile.py. These profiles are a list of function offsets into the binary that were called during execution of the benchmarks.
Cluster the symbols from the profiles to generate the orderfile. The offsets are processed and merged using a clustering algorithm to produce an orderfile.
Run benchmarks on the final orderfile. We run some benchmarks to compare the performance with/without the orderfile. You can supply the --no-benchmark
flag to skip this step.
The official orderfiles are generated on CI by dedicated builders. These builders ensure that the orderfiles used in release builds of Chrome are always fresh and based on a recent PGO profile. These builders also ensure that the orderfile and PGO profile are generated at the same Chromium commit and used together. See https://crbug.com/372686816 for more context.
The generation is handled by two builders for Android:
android-arm32-orderfile
android-arm64-orderfile
These builders can be found on the chrome.orderfile console. They include builders for trunk and the various release branches/milestones.
The orderfile generation process is tightly coupled with Profile-Guided Optimization (PGO). The orderfile builders are automatically triggered by their corresponding PGO profile generation builders. This is configured for the orderfile builders in the triggered_by
parameter in the orderfile builder configuration. For example:
ci/android-arm32-pgo
triggers android-arm32-orderfile
.ci/android-arm64-pgo
triggers android-arm64-orderfile
.This ensures that the orderfile is always generated using the most recent PGO profile and at the same Chromium commit, which is crucial for its effectiveness. The PGO profile provides the necessary data to determine which functions are used most frequently and in what order, forming the basis for the clustering algorithm that generates the final orderfile. The PGO builder passes the GCS file path and name of the new profile to the orderfile builder so that the orderfile builder can download it, as it has not yet been rolled into trunk at this point.
The configuration for these builders is defined in //internal/infra/config/subprojects/chrome/ci/chrome.orderfile.star
. This configuration specifies the build steps, target architecture, and other parameters. The builders run the generate_orderfile.py
script, which orchestrates the process described in the “Orderfile Pipeline” section above.
For questions or issues with the orderfile builders, the point of contact is orderfile-discuss@google.com
.