These are instructions for collecting a CPU profile of chromium. All of the profiling methods described here produce output that can be view using the pprof
tool. pprof
is highly customizable; here's a screenshot of some example pprof
output:
This doc is intended to be an authoritative one-stop resource for profiling chromium. At the time of writing, there are a number of existing docs with profiling instructions, in varying states of obsolescence:
CPU profiling is not to be confused with tracing or task profiling:
Profiling support is built into tcmalloc and exposed in chromium, so any platform that uses tcmalloc should be able to generate profiling data without using external tools.
Profiling should always be done on a Release build, which has very similiar performance characteristics to an official build. Make sure the following appears in your args.gn
file:
is_debug = false enable_profiling = true enable_callgrind = true
By default, the profiler will take a sample 100 times per second. You can adjust this rate by setting the CPUPROFILE_FREQUENCY
environment variable before launching chromium:
$ export CPUPROFILE_FREQUENCY=1000
The maximum supported rate is 4000 samples per second.
To profile the main browser process, add the following argument to your chrome invocation:
--enable-profiling --profiling-at-start
To profile, e.g., every renderer process, add the following argument to your chrome invocation:
--enable-profiling --profiling-at-start=renderer --no-sandbox
To profile the gpu process, add the following argument to your chrome invocation:
--enable-profiling --profiling-at-start=gpu-process --no-sandbox --profiling-flush
The gpu process does not shut down cleanly and so requires periodic flushing to write the profile to disk.
When the process being profiled ends, you should see one or more chrome-profile-{process type}-{process ID}
files in your $PWD
. Run pprof
to view the results, e.g.:
$ pprof -web chrome-profile-renderer-12345
pprof
is packed with useful features for visualizing profiling data. Try pprof --help
for more info.prodaccess
first will make pprof
run faster, and eliminate some useless spew to the terminal.First, make sure you have the linux-perf
package installed:
$ sudo apt-get install linux-perf
After starting up the browser and loading the page you want to profile, press ‘Shift-Escape’ to bring up the task manager, and get the Process ID of the process you want to profile.
Run the perf tool like this:
$ perf record -g -p <Process ID> -o <output file>
perf
does not honor the CPUPROFILE_FREQUENCY
env var. To adjust the sampling frequency, use the -F
argument, e.g., -F 1000
.To stop profiling, press Control-c
in the terminal window where perf
is running. Run pprof
to view the results, providing the path to the browser executable; e.g.:
$ pprof -web src/out/Release/chrome <perf output file>
pprof
is packed with useful features for visualizing profiling data. Try pprof --help
for more info.If you want to limit the profile to a single thread, run:
$ ps -T -p <Process ID>
From the output, find the Thread ID (column header “SPID”) of the thread you want. Now run perf:
$ perf record -g -t <Thread ID> -o <output file>
Use the same pprof
command as above to view the single-thread results.
You can generate a highly-focused profile for any period that can be defined in javascript using the chrome.gpuBenchmarking
javascript interface. First, adding the following command-line flags when you start chrome:
$ chrome --enable-gpu-benchmarking --no-sandbox [...]
Open devtools, and in the console, use chrome.gpuBenchmarking.startProfiling
and chrome.gpuBenchmarking.stopProfiling
to define a profiling period. e.g.:
> chrome.gpuBenchmarking.startProfiling('perf.data'); doSomething(); chrome.gpuBenchmarking.stopProfiling()
chrome.gpuBenchmarking
has a number of useful methods for simulating user-gesture-initiated actions; for example, to profile scrolling:
> chrome.gpuBenchmarking.startProfiling('perf.data'); chrome.gpuBenchmarking.smoothScrollBy(1000, () => { chrome.gpuBenchmarking.stopProfiling() });
Android (Nougat and later) supports profiling using the simpleperf tool.
Follow the instructions for building and installing chromium on android. With chromium running on the device, run the following command to start profiling on the browser process (assuming your build is in src/out/Release
):
$ src/out/Release/bin/chrome_public_apk profile Profiler is running; press Enter to stop...
Once you stop the profiler, the profiling data will be copied off the device to the host machine and post-processed so it can be viewed in pprof
, as described above.
To profile the renderer process, you must have just one tab open in chromium, and use a command like this:
$ src/out/Release/bin/chrome_public_apk profile --profile-process=renderer
To limit the profile to a single thread, use a command like this:
$ src/out/Release/bin/chrome_public_apk profile --profile-process=renderer --profile-thread=main
The --profile-process
and --profile-thread
arguments support most of the common process names (‘browser’, ‘gpu’, ‘renderer’) and thread names (‘main’, ‘io’, ‘compositor’, etc.). However, if you need finer control of the process and/or thread to profile, you can specify an explicit Process ID or Thread ID. Check out the usage message for more info:
$ src/out/Release/bin/chrome_public_apk help profile
The perf benchmark runner can generate a CPU profile over the course of running a perf test. Currently, this is supported only on Linux and Android. To get info about the relevant options, run:
$ src/tools/perf/run_benchmark help run
... and look for the --interval-profiling-*
options. For example, to generate a profile of the main thread of the renderer process during the “page interactions” phase of a perf benchmark, you might run:
$ src/tools/perf/run_benchmark run <benchmark name> --interval-profiling-target=renderer:main --interval-profiling-period=interactions --interval-profiling-frequency=2000
The profiling data will be written into the artifacts/
sub-directory of your perf benchmark output directory (default is src/tools/perf
), to files with the naming pattern *.profile.pb
. You can use pprof
to view the results, as described above.