mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-11-07 01:53:24 +09:00
[Tools] (P14): the sampler and profiler find spawn and tcp server processes by their install path, plus a per-component profile split.
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Inclusive share of fixed components on one thread of a simpleperf profile, converted to
|
||||
milliseconds per frame with the thread's measured CPU ms/frame.
|
||||
|
||||
python components.py <perf.data> <binary_cache> <thread comm> [cpu_ms_per_frame]
|
||||
|
||||
A sample counts toward a component when any frame of its call chain matches the component's
|
||||
pattern (first match in COMPONENTS order wins for the 'exclusive' column, so the rows of that
|
||||
column add up to 100%).
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
from collections import Counter
|
||||
|
||||
sys.path.insert(0, os.environ.get("SIMPLEPERF_DIR", ""))
|
||||
from simpleperf_report_lib import ReportLib # noqa: E402
|
||||
|
||||
COMPONENTS = [
|
||||
("trace parse (harness)", ("trace::Parser::", "BrotliFile", "trace::Call::~Call", "trace::File::")),
|
||||
("validate point", ("MGPipeValidateForVerb",)),
|
||||
("backend draw setup", ("SetupWireDraw", "VulkanRenderer::SetupDraw", "DirectGLES::PrepareForDraw")),
|
||||
("backend draw other", ("DirectVulkan::DrawElements", "DirectGLES::DrawElements", "VulkanRenderer::DrawElements")),
|
||||
("verb port / record sink", ("EmitDrawRecord", "VerbChannel::Port", "RecordVerbSink::")),
|
||||
("wire encode (client)", ("ClientSession::Emit", "PipeWireEncoder::")),
|
||||
("apply decode", ("PipeWireDecoder::", "PipeApplier::ApplyOne")),
|
||||
("apply loop idle/poll", ("ServerLoop::ApplyThreadMain", "ServerLoop::DrainRing")),
|
||||
("other GL entry points", ("retrace::retraceCall",)),
|
||||
]
|
||||
|
||||
|
||||
def main():
|
||||
data, symfs, comm = sys.argv[1], sys.argv[2], sys.argv[3]
|
||||
cpu = float(sys.argv[4]) if len(sys.argv) > 4 else None
|
||||
lib = ReportLib()
|
||||
lib.SetRecordFile(data)
|
||||
lib.SetSymfs(symfs)
|
||||
total = 0
|
||||
inclusive = Counter()
|
||||
exclusive = Counter()
|
||||
while True:
|
||||
sample = lib.GetNextSample()
|
||||
if sample is None:
|
||||
break
|
||||
if comm not in sample.thread_comm:
|
||||
continue
|
||||
total += 1
|
||||
frames = [lib.GetSymbolOfCurrentSample().symbol_name]
|
||||
chain = lib.GetCallChainOfCurrentSample()
|
||||
frames += [chain.entries[i].symbol.symbol_name for i in range(chain.nr)]
|
||||
first = None
|
||||
for name, patterns in COMPONENTS:
|
||||
if any(p in f for f in frames for p in patterns):
|
||||
inclusive[name] += 1
|
||||
if first is None:
|
||||
first = name
|
||||
exclusive[first or "rest"] += 1
|
||||
print(f"{comm}: {total} samples" + (f", {cpu:.2f} ms/frame" if cpu else ""))
|
||||
for name, _ in COMPONENTS + [("rest", ())]:
|
||||
inc = 100.0 * inclusive[name] / max(1, total)
|
||||
exc = 100.0 * exclusive[name] / max(1, total)
|
||||
ms = f" {cpu * exc / 100.0:6.2f} ms" if cpu else ""
|
||||
print(f" {name:28} incl {inc:5.1f}% excl {exc:5.1f}%{ms}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -95,9 +95,9 @@ static int ScanPids(const char* pkg, int* pids) {
|
||||
snprintf(path, sizeof path, "/proc/%s/cmdline", e->d_name);
|
||||
if (ReadSmall(path, buf, sizeof buf) <= 0) continue;
|
||||
// The replay process (and its :services), plus the render-server processes the spawn and
|
||||
// tcp arms exec (their cmdline is the server library's name, not the package's).
|
||||
// tcp arms exec (their cmdline is the server library's path in the package's install dir).
|
||||
if ((strncmp(buf, pkg, len) == 0 && (buf[len] == 0 || buf[len] == ':')) ||
|
||||
strncmp(buf, "libMobileGLServer.so", 20) == 0)
|
||||
(strstr(buf, "libMobileGLServer.so") != NULL && strstr(buf, pkg) != NULL))
|
||||
pids[n++] = atoi(e->d_name);
|
||||
}
|
||||
closedir(d);
|
||||
|
||||
@@ -33,7 +33,7 @@ esac
|
||||
adb -s "$SER" shell "am force-stop $PKG_FEAT; am force-stop $PKG_DEV; run-as $pkg sh -c 'rm -f $app/output/*.json'" >/dev/null 2>&1
|
||||
adb -s "$SER" shell "am start -a top.mobilegl.plugin.TRACE_REPLAY -n $pkg/top.mobilegl.plugin.trace.TraceReplayActivity --es trace_path $app/input-$WL/trace.trace --es golden_path $app/input-$WL/golden.png --es output_dir $app/output --es backend $BACKEND $args --ez use_pbuffer true --ez benchmark true --es benchmark_result_path $app/output/benchmark.json --es mobilegl_env '$env'" >/dev/null
|
||||
sleep "$DELAY"
|
||||
pids=$(adb -s "$SER" shell "su -c 'echo \$(pidof $pkg) \$(pgrep -f ^libMobileGLServer.so)'" | tr -d '\r' | tr -s ' ' ',' | sed 's/^,//; s/,$//')
|
||||
pids=$(adb -s "$SER" shell "su -c 'echo \$(pidof $pkg) \$(pgrep -f $pkg.*libMobileGLServer.so)'" | tr -d '\r' | tr -s ' ' ',' | sed 's/^,//; s/,$//')
|
||||
echo "pids=$pids" | tee "$OUT/pids.txt"
|
||||
adb -s "$SER" shell "su -c 'simpleperf record -e cpu-clock -p $pids --call-graph fp -f 4000 --duration $DUR -o /data/local/tmp/p14perf.data'" >"$OUT/record.log" 2>&1
|
||||
adb -s "$SER" exec-out "run-as $pkg cat $app/output/benchmark.json" >"$OUT/benchmark.json" 2>/dev/null
|
||||
|
||||
Reference in New Issue
Block a user