Use Simpleperf for CPU Profiling
Simpleperf samples an application at a given frequency to determine where the CPU is consuming time, as well as where other performance-related hardware events occur. No changes need to be made to code to take a Simpleperf trace, making it an excellent way to get a quick and broad overview of the performance of your app. It is recommended that you use Simpleperf to debug performance issues in your application.
Applications profiled with Simpleperf must be development builds. Simpleperf is installed in the /bin/
directory on Meta Quest devices, but the Android NDK provides scripts to run Simpleperf from a host machine. You must install the Android NDK to use the scripts.
In Android Studio, it’s recommended to build with optimizations and symbols enabled. Though it’s not required, profiling with optimizations enabled gives a more accurate picture of how your app will behave when released to users.
The following workflows show how to use Simpleperf to capture and read a performance trace.
Capturing a Simpleperf Trace After the app is installed on your device and running, use the app_profiler.py
script to start a trace recording as follows:
python <ndk path>/SimplePerf/app_profiler.py --disable_adb_root --ndk_path <ndk path> --app <package name> -r "-g --duration <seconds> -e cpu-cycles,cache-misses"
--disable_adb_root
is required to prevent app_profiler.py
from attempting to get root access, while -r
allows you to specify arguments to pass to Simpleperf on the device.
Invoking Simpleperf through adb shell
as shown below gives a complete list of additional arguments that can be passed through -r
:
adb shell bin/simpleperf record --help
Arguments used above include the following:
-g
- Tells Simpleperf to record dwarf-based call graphs, which provide better support than stack frame-based call graphs on ARM devices.--duration
- Allows you to set an amount of time in seconds that the trace will run for. This is optional.-e
- Allows you to specify which cpu events you want to record. In this example, both cpu-cycles
and cache-misses
are being recorded:
cpu-cycles
- This event is useful for determining what functions your app is spending time in during a trace. The report shows how much cpu time is being spent as a percentage compared to other functions in the app. If you do not include -e
, this event is enabled by default.cache-misses
- This event is useful for finding where data cache misses occur in the app. Like cpu-cycles, the report breaks down which functions in the app are suffering the most cache misses by percentage. This event is disabled by default, but enabling it can help you discover poor memory access patterns in the app.- More events are available that can be captured with Simpleperf. Run
adb shell bin/simpleperf list
to get a complete list of events that can be passed with -e
.
After capturing a trace with app_profiler.py
, view the trace data with report_html.py
:
python <ndk path>/SimplePerf/report_html.py
The report will open as a web page in the default browser.
report_html.py
generates a page with 3 tabs. Each tab allows you to switch the view between the different CPU events specified with the -e
argument.
The Chart Statistics tab shows a pie chart of samples recorded from each process. Click the segments of the chart to explore threads, libraries, and function calls.
The Sample Table tab shows a sortable and filterable table of all functions that were sampled in the trace. Clicking a row in the table displays a call graph of samples from that function.
The Flamegraph tab shows call graphs for each thread of your app. Clicking any function slice in a graph will zoom into that function.