【譯】Simpleperf分析之Android系統篇
譯者按:
Simpleperf是用於Native的CPU效能分析工具,主要用來分析程式碼執行耗時。本文是主文件的一部分,系統篇。
原文見aosp倉庫:android_platform_profiling.md
Simpleperf主文件見aosp倉庫:Simpleperf
官網介紹:https://developer.android.com/ndk/guides/simpleperf
目錄
- Simpleperf分析之Android系統篇
通用技巧
這裡有一些技巧給有root許可權的Android系統開發者:
- 執行
adb root
後, simpleperf可用於分析系統範圍內任何程式。 - 如果不是在主分支上工作,建議使用AOSP main中最新的simpleperf。指令碼位置在
system/extras/simpleperf/scripts
,二進位制程式在system/extras/simpleperf/scripts/bin/android
. - 推薦使用
app_profiler.py
抓trace,然後用report_html.py
生成html報告。 下面是一個示例。
# Record surfaceflinger process for 10 seconds with dwarf based call graph. More examples are in
# scripts reference in the doc.
$ python app_profiler.py -np surfaceflinger -r "-g --duration 10"
# Generate html report.
$ python report_html.py
- 從 Android >= O 開始系統庫預設有符號表,我們不需要用
$ANDROID_PRODUCT_OUT/symbols
中未striped二進位制檔案來抓了。 但是,在報告中新增原始碼和反彙編(帶有行號)時需要它們。下面是一個例子。
# Doing recording with app_profiler.py or simpleperf on device, and generates perf.data on host.
$ python app_profiler.py -np surfaceflinger -r "--call-graph fp --duration 10"
# Collect unstripped binaries from $ANDROID_PRODUCT_OUT/symbols to binary_cache/.
$ python binary_cache_builder.py -lib $ANDROID_PRODUCT_OUT/symbols
# Report source code and disassembly. Disassembling all binaries is slow, so it's better to add
# --binary_filter option to only disassemble selected binaries.
$ python report_html.py --add_source_code --source_dirs $ANDROID_BUILD_TOP --add_disassembly \
--binary_filter surfaceflinger.so
在system_server程式上抓simpleperf
有時我們希望在發生特殊情況時抓系統程式。在這種情況下,我們可以在檢測到情況的點處新增SimplEperf的程式碼。
- 關掉selinux
adb shell setenforce 0
。因為selinux只允許simpleperf在shell或debuggable/profileable 應用中使用。 - 在檢測到特殊情況的地方新增下面的程式碼。
try {
// for capability check
Os.prctl(OsConstants.PR_CAP_AMBIENT, OsConstants.PR_CAP_AMBIENT_RAISE,
OsConstants.CAP_SYS_PTRACE, 0, 0);
// Write to /data instead of /data/local/tmp. Because /data can be written by system user.
Runtime.getRuntime().exec("/system/bin/simpleperf record -g -p " + String.valueOf(Process.myPid())
+ " -o /data/perf.data --duration 30 --log-to-android-buffer --log verbose");
} catch (Exception e) {
Slog.e(TAG, "error while running simpleperf");
e.printStackTrace();
}
硬體 PMU 計數器限制
監視指令和快取相關的效能事件時 (在list命令列出的hw/cache/raw/pmu 類別),這些事件被對映到每個cpu核心上的PMU計數器。但每個核心只有有限數量的PMU計數器。如果事件數量 > PMU計數器的數量,然後計數器在事件之間多路複用,這可能不是我們想要的。
在Pixel裝置上,每個核上的PMU計數器的數量通常是7個,其中4個被核心用於監視記憶體延遲。所以只有3個計數器可用。可以同時監控最多3個PMU事件。要監視3個以上的事件,可以使用 --use-devfreq-counters
選項借用核心使用的計數器。