metrics: add mcycles breakdown by core type to startup metric
This CL adds a per-core type mcycle counter for each startup.
Change-Id: I28135a8d45d575171df43b9577368447288f107d
Bug: 183956291
diff --git a/protos/perfetto/metrics/android/startup_metric.proto b/protos/perfetto/metrics/android/startup_metric.proto
index ecbd0a9..5d8fcf8 100644
--- a/protos/perfetto/metrics/android/startup_metric.proto
+++ b/protos/perfetto/metrics/android/startup_metric.proto
@@ -31,6 +31,13 @@
optional int64 interruptible_sleep_dur_ns = 4;
}
+ message McyclesByCoreType {
+ optional int64 little = 1;
+ optional int64 big = 2;
+ optional int64 bigger = 3;
+ optional int64 unknown = 4;
+ }
+
message Slice {
optional int64 dur_ns = 1;
optional double dur_ms = 2;
@@ -38,12 +45,16 @@
// Timing information spanning the intent received by the
// activity manager to the first frame drawn.
- // Next id: 26.
+ // Next id: 27.
message ToFirstFrame {
optional int64 dur_ns = 1;
optional double dur_ms = 17;
optional TaskStateBreakdown main_thread_by_task_state = 2;
+ // The mcycles taken by this startup across all CPUs (broken down by core
+ // type).
+ optional McyclesByCoreType mcycles_by_core_type = 26;
+
// In this timespan, how many processes (apart from the main activity) were
// spawned.
optional uint32 other_processes_spawned_count = 3;
diff --git a/protos/perfetto/metrics/perfetto_merged_metrics.proto b/protos/perfetto/metrics/perfetto_merged_metrics.proto
index 678c85e..5736909 100644
--- a/protos/perfetto/metrics/perfetto_merged_metrics.proto
+++ b/protos/perfetto/metrics/perfetto_merged_metrics.proto
@@ -706,6 +706,13 @@
optional int64 interruptible_sleep_dur_ns = 4;
}
+ message McyclesByCoreType {
+ optional int64 little = 1;
+ optional int64 big = 2;
+ optional int64 bigger = 3;
+ optional int64 unknown = 4;
+ }
+
message Slice {
optional int64 dur_ns = 1;
optional double dur_ms = 2;
@@ -713,12 +720,16 @@
// Timing information spanning the intent received by the
// activity manager to the first frame drawn.
- // Next id: 26.
+ // Next id: 27.
message ToFirstFrame {
optional int64 dur_ns = 1;
optional double dur_ms = 17;
optional TaskStateBreakdown main_thread_by_task_state = 2;
+ // The mcycles taken by this startup across all CPUs (broken down by core
+ // type).
+ optional McyclesByCoreType mcycles_by_core_type = 26;
+
// In this timespan, how many processes (apart from the main activity) were
// spawned.
optional uint32 other_processes_spawned_count = 3;
diff --git a/src/trace_processor/metrics/android/android_startup.sql b/src/trace_processor/metrics/android/android_startup.sql
index 77745c4..808d7d3 100644
--- a/src/trace_processor/metrics/android/android_startup.sql
+++ b/src/trace_processor/metrics/android/android_startup.sql
@@ -19,6 +19,39 @@
SELECT RUN_METRIC('android/process_metadata.sql');
SELECT RUN_METRIC('android/hsc_startups.sql');
+-- Create the base CPU span join table.
+SELECT RUN_METRIC('android/android_cpu_agg.sql');
+
+-- Create a span join safe launches view; since both views
+-- being span joined have an "id" column, we need to rename
+-- the id column for launches to disambiguate the two.
+DROP VIEW IF EXISTS launches_span_join_safe;
+CREATE VIEW launches_span_join_safe AS
+SELECT ts, dur, id AS launch_id
+FROM launches;
+
+-- Span join the CPU table with the launches table to get the
+-- breakdown per-cpu.
+DROP TABLE IF EXISTS cpu_freq_sched_per_thread_per_launch;
+CREATE VIRTUAL TABLE cpu_freq_sched_per_thread_per_launch
+USING SPAN_JOIN(
+ launches_span_join_safe,
+ cpu_freq_sched_per_thread PARTITIONED cpu
+);
+
+SELECT RUN_METRIC('android/cpu_info.sql');
+
+DROP VIEW IF EXISTS mcycles_per_core_type_per_launch;
+CREATE VIEW mcycles_per_core_type_per_launch AS
+SELECT
+ launch_id,
+ IFNULL(core_type_per_cpu.core_type, 'unknown') AS core_type,
+ CAST(SUM(dur * freq_khz / 1000) / 1e9 AS INT) AS mcycles
+FROM cpu_freq_sched_per_thread_per_launch
+LEFT JOIN core_type_per_cpu USING (cpu)
+WHERE utid != 0
+GROUP BY 1, 2;
+
-- Slices for forked processes. Never present in hot starts.
-- Prefer this over process start_ts, since the process might have
-- been preforked.
@@ -211,6 +244,28 @@
WHERE l.launch_id = launches.id AND state = 'S'
), 0)
),
+ 'mcycles_by_core_type', AndroidStartupMetric_McyclesByCoreType(
+ 'little', (
+ SELECT mcycles
+ FROM mcycles_per_core_type_per_launch m
+ WHERE m.launch_id = launches.id AND m.core_type = 'little'
+ ),
+ 'big', (
+ SELECT mcycles
+ FROM mcycles_per_core_type_per_launch m
+ WHERE m.launch_id = launches.id AND m.core_type = 'big'
+ ),
+ 'bigger', (
+ SELECT mcycles
+ FROM mcycles_per_core_type_per_launch m
+ WHERE m.launch_id = launches.id AND m.core_type = 'bigger'
+ ),
+ 'unknown', (
+ SELECT mcycles
+ FROM mcycles_per_core_type_per_launch m
+ WHERE m.launch_id = launches.id AND m.core_type = 'unknown'
+ )
+ ),
'to_post_fork', (
SELECT slice_proto
FROM to_event_protos p
diff --git a/src/trace_processor/python/perfetto/trace_processor/metrics.descriptor b/src/trace_processor/python/perfetto/trace_processor/metrics.descriptor
index c1af116..1155e2b 100644
--- a/src/trace_processor/python/perfetto/trace_processor/metrics.descriptor
+++ b/src/trace_processor/python/perfetto/trace_processor/metrics.descriptor
Binary files differ
diff --git a/test/trace_processor/startup/android_startup.out b/test/trace_processor/startup/android_startup.out
index 578295a..bef8217 100644
--- a/test/trace_processor/startup/android_startup.out
+++ b/test/trace_processor/startup/android_startup.out
@@ -32,6 +32,8 @@
dur_ns: 8
dur_ms: 8e-06
}
+ mcycles_by_core_type {
+ }
dur_ms: 0.000108
}
report_fully_drawn {
diff --git a/test/trace_processor/startup/android_startup_attribution.out b/test/trace_processor/startup/android_startup_attribution.out
index 22d4e4f..733dfc7 100644
--- a/test/trace_processor/startup/android_startup_attribution.out
+++ b/test/trace_processor/startup/android_startup_attribution.out
@@ -26,6 +26,8 @@
dur_ns: 40
dur_ms: 4e-05
}
+ mcycles_by_core_type {
+ }
}
activity_hosting_process_count: 1
process {
diff --git a/test/trace_processor/startup/android_startup_breakdown.out b/test/trace_processor/startup/android_startup_breakdown.out
index f29b01a..e6c360e 100644
--- a/test/trace_processor/startup/android_startup_breakdown.out
+++ b/test/trace_processor/startup/android_startup_breakdown.out
@@ -3,63 +3,59 @@
startup_id: 1
package_name: "com.google.android.calendar"
process_name: "com.google.android.calendar"
- process: {
+ zygote_new_process: true
+ to_first_frame {
+ dur_ns: 108000000000
+ main_thread_by_task_state {
+ running_dur_ns: 25000000000
+ runnable_dur_ns: 5000000000
+ uninterruptible_sleep_dur_ns: 0
+ interruptible_sleep_dur_ns: 0
+ }
+ other_processes_spawned_count: 0
+ time_activity_manager {
+ dur_ns: 8000000000
+ dur_ms: 8000
+ }
+ time_bind_application {
+ dur_ns: 9000000000
+ dur_ms: 9000
+ }
+ time_before_start_process {
+ dur_ns: 18000000000
+ dur_ms: 18000
+ }
+ time_during_start_process {
+ dur_ns: 35000000000
+ dur_ms: 35000
+ }
+ dur_ms: 108000
+ to_bind_application {
+ dur_ns: 83000000000
+ dur_ms: 83000
+ }
+ time_inflate {
+ dur_ns: 3000000000
+ dur_ms: 3000
+ }
+ time_get_resources {
+ dur_ns: 1000000000
+ dur_ms: 1000
+ }
+ mcycles_by_core_type {
+ unknown: 103
+ }
+ }
+ activity_hosting_process_count: 1
+ process {
name: "com.google.android.calendar"
}
activities {
name: "com.google.android.calendar.MainActivity"
method: "performCreate"
slice {
- dur_ns: 4
- dur_ms: 4e-06
- }
- }
- activities {
- name: "com.google.android.calendar.MainActivity"
- method: "performResume"
- slice {
- dur_ns: 1
- dur_ms: 1e-06
- }
- }
- zygote_new_process: true
- to_first_frame {
- dur_ns: 108
- main_thread_by_task_state {
- running_dur_ns: 0
- runnable_dur_ns: 0
- uninterruptible_sleep_dur_ns: 0
- interruptible_sleep_dur_ns: 0
- }
- other_processes_spawned_count: 0
- time_activity_manager {
- dur_ns: 8
- dur_ms: 8e-06
- }
- time_bind_application {
- dur_ns: 10
- dur_ms: 1e-05
- }
- time_before_start_process {
- dur_ns: 18
- dur_ms: 1.8e-05
- }
- time_during_start_process {
- dur_ns: 35
- dur_ms: 3.5e-05
- }
- dur_ms: 0.000108
- to_bind_application {
- dur_ns: 83
- dur_ms: 8.3e-05
- }
- time_inflate {
- dur_ns: 3
- dur_ms: 3e-06
- }
- time_get_resources {
- dur_ns: 1
- dur_ms: 1e-06
+ dur_ns: 4000000000
+ dur_ms: 4000
}
}
optimization_status {
@@ -74,6 +70,5 @@
compilation_reason: "unknown"
location: "error"
}
- activity_hosting_process_count: 1
}
-}
+}
\ No newline at end of file
diff --git a/test/trace_processor/startup/android_startup_breakdown.py b/test/trace_processor/startup/android_startup_breakdown.py
index 066d2fc..11df3e5 100644
--- a/test/trace_processor/startup/android_startup_breakdown.py
+++ b/test/trace_processor/startup/android_startup_breakdown.py
@@ -17,6 +17,11 @@
import synth_common
+
+def to_s(ts):
+ return ts * 1000 * 1000 * 1000
+
+
trace = synth_common.create_trace()
trace.add_packet()
trace.add_process(1, 0, 'init')
@@ -27,64 +32,80 @@
# Start intent for a successful launch of calendar
trace.add_atrace_begin(
- ts=102, tid=2, pid=2, buf='MetricsLogger:launchObserverNotifyIntentStarted')
-trace.add_atrace_end(ts=103, tid=2, pid=2)
+ ts=to_s(102),
+ tid=2,
+ pid=2,
+ buf='MetricsLogger:launchObserverNotifyIntentStarted')
+trace.add_atrace_end(ts=to_s(103), tid=2, pid=2)
trace.add_atrace_async_begin(
- ts=110, tid=2, pid=2, buf='launching: com.google.android.calendar')
+ ts=to_s(110), tid=2, pid=2, buf='launching: com.google.android.calendar')
trace.add_atrace_begin(
- ts=120, tid=2, pid=2, buf='Start proc: com.google.android.calendar')
-trace.add_atrace_end(ts=155, tid=2, pid=2)
+ ts=to_s(120), tid=2, pid=2, buf='Start proc: com.google.android.calendar')
+trace.add_atrace_end(ts=to_s(155), tid=2, pid=2)
# Unrelated process binding, ignored
-trace.add_atrace_begin(ts=125, tid=1, pid=1, buf='bindApplication')
-trace.add_atrace_end(ts=195, tid=1, pid=1)
+trace.add_atrace_begin(ts=to_s(125), tid=1, pid=1, buf='bindApplication')
+trace.add_atrace_end(ts=to_s(195), tid=1, pid=1)
-trace.add_atrace_begin(ts=185, tid=3, pid=3, buf='bindApplication')
+trace.add_atrace_begin(ts=to_s(185), tid=3, pid=3, buf='bindApplication')
trace.add_atrace_begin(
- ts=188,
+ ts=to_s(188),
tid=3,
pid=3,
buf='performCreate:com.google.android.calendar.MainActivity')
-trace.add_atrace_begin(ts=188, tid=3, pid=3, buf='inflate')
-trace.add_atrace_end(ts=189, tid=3, pid=3)
+trace.add_atrace_begin(ts=to_s(188), tid=3, pid=3, buf='inflate')
+trace.add_atrace_end(ts=to_s(189), tid=3, pid=3)
trace.add_atrace_begin(
- ts=188, tid=3, pid=3, buf='ResourcesManager#getResources')
-trace.add_atrace_end(ts=189, tid=3, pid=3)
-trace.add_atrace_begin(ts=190, tid=3, pid=3, buf='inflate')
-trace.add_atrace_end(ts=192, tid=3, pid=3)
-trace.add_atrace_end(ts=192, tid=3, pid=3)
+ ts=to_s(188), tid=3, pid=3, buf='ResourcesManager#getResources')
+trace.add_atrace_end(ts=to_s(189), tid=3, pid=3)
+trace.add_atrace_begin(ts=to_s(190), tid=3, pid=3, buf='inflate')
+trace.add_atrace_end(ts=to_s(192), tid=3, pid=3)
+trace.add_atrace_end(ts=to_s(192), tid=3, pid=3)
trace.add_atrace_begin(
ts=193,
tid=3,
pid=3,
buf='performResume:com.google.android.calendar.MainActivity')
-trace.add_atrace_end(ts=194, tid=3, pid=3)
-trace.add_atrace_end(ts=195, tid=3, pid=3)
+trace.add_atrace_end(ts=to_s(194), tid=3, pid=3)
+trace.add_atrace_end(ts=to_s(195), tid=3, pid=3)
trace.add_atrace_begin(
- ts=200,
+ ts=to_s(200),
tid=3,
pid=3,
buf='location=error status=io-error-no-oat ' \
'filter=run-from-apk reason=unknown')
-trace.add_atrace_end(ts=202, tid=3, pid=3)
+trace.add_atrace_end(ts=to_s(202), tid=3, pid=3)
trace.add_atrace_begin(
- ts=204,
+ ts=to_s(204),
tid=3,
pid=3,
buf='location=/system/framework/oat/arm/com.android.location.provider' \
'.odex status=up-to-date filter=speed reason=prebuilt')
-trace.add_atrace_end(ts=205, tid=3, pid=3)
+trace.add_atrace_end(ts=to_s(205), tid=3, pid=3)
trace.add_atrace_async_end(
- ts=210, tid=2, pid=2, buf='launching: com.google.android.calendar')
+ ts=to_s(210), tid=2, pid=2, buf='launching: com.google.android.calendar')
trace.add_atrace_begin(
- ts=211,
+ ts=to_s(211),
tid=2,
pid=2,
buf='MetricsLogger:launchObserverNotifyActivityLaunchFinished')
-trace.add_atrace_end(ts=212, tid=2, pid=2)
+trace.add_atrace_end(ts=to_s(212), tid=2, pid=2)
+
+# Add the scheduling data to match the timestamps of events above but with
+# some idle time inbetween to make the computation more realisitic.
+trace.add_cpufreq(ts=to_s(50), freq=1000, cpu=0)
+trace.add_sched(ts=to_s(100), prev_pid=0, next_pid=2)
+trace.add_sched(ts=to_s(115), prev_pid=2, next_pid=0)
+trace.add_sched(ts=to_s(120), prev_pid=0, next_pid=2)
+trace.add_sched(ts=to_s(125), prev_pid=2, next_pid=1)
+trace.add_sched(ts=to_s(150), prev_pid=1, next_pid=2)
+trace.add_sched(ts=to_s(160), prev_pid=2, next_pid=1)
+trace.add_sched(ts=to_s(180), prev_pid=1, next_pid=3)
+trace.add_sched(ts=to_s(205), prev_pid=3, next_pid=2)
+trace.add_sched(ts=to_s(220), prev_pid=2, next_pid=0)
sys.stdout.buffer.write(trace.trace.SerializeToString())
diff --git a/test/trace_processor/startup/android_startup_process_track.out b/test/trace_processor/startup/android_startup_process_track.out
index 3a3d5a8..817b19d 100644
--- a/test/trace_processor/startup/android_startup_process_track.out
+++ b/test/trace_processor/startup/android_startup_process_track.out
@@ -20,6 +20,8 @@
dur_ns: 2
dur_ms: 2e-06
}
+ mcycles_by_core_type {
+ }
dur_ms: 4e-06
}
activity_hosting_process_count: 1
@@ -45,6 +47,8 @@
dur_ns: 2
dur_ms: 2e-06
}
+ mcycles_by_core_type {
+ }
dur_ms: 4e-06
}
activity_hosting_process_count: 1