tp: Add cluster label mapping from cluster_id
- Use cluster_id to determine the cluster type of a CPU instead of the previous heuristic which used only maximum frequency.
Change-Id: Iaf0a7b84f28dda2045fce462435f9ebf864af308
diff --git a/Android.bp b/Android.bp
index 2bcbd0e..fa85cc4 100644
--- a/Android.bp
+++ b/Android.bp
@@ -13258,6 +13258,7 @@
"src/trace_processor/perfetto_sql/stdlib/android/battery_stats.sql",
"src/trace_processor/perfetto_sql/stdlib/android/binder.sql",
"src/trace_processor/perfetto_sql/stdlib/android/broadcasts.sql",
+ "src/trace_processor/perfetto_sql/stdlib/android/cpu/cluster_type.sql",
"src/trace_processor/perfetto_sql/stdlib/android/critical_blocking_calls.sql",
"src/trace_processor/perfetto_sql/stdlib/android/device.sql",
"src/trace_processor/perfetto_sql/stdlib/android/dvfs.sql",
diff --git a/BUILD b/BUILD
index 8339af3..fc4db19 100644
--- a/BUILD
+++ b/BUILD
@@ -2543,6 +2543,14 @@
],
)
+# GN target: //src/trace_processor/perfetto_sql/stdlib/android/cpu:cpu
+perfetto_filegroup(
+ name = "src_trace_processor_perfetto_sql_stdlib_android_cpu_cpu",
+ srcs = [
+ "src/trace_processor/perfetto_sql/stdlib/android/cpu/cluster_type.sql",
+ ],
+)
+
# GN target: //src/trace_processor/perfetto_sql/stdlib/android/frames:frames
perfetto_filegroup(
name = "src_trace_processor_perfetto_sql_stdlib_android_frames_frames",
@@ -2893,6 +2901,7 @@
deps = [
":src_trace_processor_perfetto_sql_stdlib_android_android",
":src_trace_processor_perfetto_sql_stdlib_android_auto_auto",
+ ":src_trace_processor_perfetto_sql_stdlib_android_cpu_cpu",
":src_trace_processor_perfetto_sql_stdlib_android_frames_frames",
":src_trace_processor_perfetto_sql_stdlib_android_gpu_gpu",
":src_trace_processor_perfetto_sql_stdlib_android_memory_heap_graph_heap_graph",
diff --git a/src/trace_processor/perfetto_sql/stdlib/android/BUILD.gn b/src/trace_processor/perfetto_sql/stdlib/android/BUILD.gn
index b655e53..f51ef75 100644
--- a/src/trace_processor/perfetto_sql/stdlib/android/BUILD.gn
+++ b/src/trace_processor/perfetto_sql/stdlib/android/BUILD.gn
@@ -17,6 +17,7 @@
perfetto_sql_source_set("android") {
deps = [
"auto",
+ "cpu",
"frames",
"gpu",
"memory",
diff --git a/src/trace_processor/perfetto_sql/stdlib/android/cpu/BUILD.gn b/src/trace_processor/perfetto_sql/stdlib/android/cpu/BUILD.gn
new file mode 100644
index 0000000..3afe0df
--- /dev/null
+++ b/src/trace_processor/perfetto_sql/stdlib/android/cpu/BUILD.gn
@@ -0,0 +1,19 @@
+# Copyright (C) 2024 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("../../../../../../gn/perfetto_sql.gni")
+
+perfetto_sql_source_set("cpu") {
+ sources = [ "cluster_type.sql" ]
+}
diff --git a/src/trace_processor/perfetto_sql/stdlib/android/cpu/cluster_type.sql b/src/trace_processor/perfetto_sql/stdlib/android/cpu/cluster_type.sql
new file mode 100644
index 0000000..f15301f
--- /dev/null
+++ b/src/trace_processor/perfetto_sql/stdlib/android/cpu/cluster_type.sql
@@ -0,0 +1,49 @@
+--
+-- Copyright 2024 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+
+-- Uses cluster_id which has been calculated using the cpu_capacity in order
+-- to determine the cluster type for cpus with 2, 3 or 4 clusters
+-- indicating whether they are "little", "medium" or "big".
+
+CREATE PERFETTO TABLE _cores AS
+WITH data(cluster_id, cluster_type, cluster_count) AS (
+ VALUES
+ (0, 'little', 2), (1, 'big', 2),
+ (0, 'little', 3), (1, 'medium', 3), (2, 'big', 3),
+ (0, 'little', 4), (1, 'medium', 4), (2, 'medium', 4), (3, 'big', 4)
+)
+SELECT * FROM data;
+
+-- Stores the mapping of a cpu to its cluster type - e.g. little, medium, big.
+-- This cluster type is determined by initially using cpu_capacity from sysfs
+-- and grouping clusters with identical capacities, ordered by size.
+-- In the case that capacities are not present, max frequency is used instead.
+-- If nothing is avaiable, NULL is returned.
+CREATE PERFETTO TABLE android_cpu_cluster_mapping (
+ -- Alias of `cpu.ucpu`.
+ ucpu INT,
+ -- Alias of `cpu.cpu`.
+ cpu INT,
+ -- The cluster type of the CPU.
+ cluster_type STRING
+) AS
+SELECT
+ ucpu,
+ cpu,
+ _cores.cluster_type AS cluster_type
+FROM
+ cpu
+LEFT JOIN _cores ON _cores.cluster_id = cpu.cluster_id
+AND _cores.cluster_count = (SELECT COUNT(DISTINCT cluster_id)FROM cpu)
\ No newline at end of file
diff --git a/test/trace_processor/diff_tests/include_index.py b/test/trace_processor/diff_tests/include_index.py
index 1012f80..57705ad 100644
--- a/test/trace_processor/diff_tests/include_index.py
+++ b/test/trace_processor/diff_tests/include_index.py
@@ -100,6 +100,7 @@
from diff_tests.parser.translated_args.tests import TranslatedArgs
from diff_tests.parser.ufs.tests import Ufs
from diff_tests.parser.zip.tests import Zip
+from diff_tests.stdlib.android.cpu_cluster_tests import CpuClusters
from diff_tests.stdlib.android.frames_tests import Frames
from diff_tests.stdlib.android.gpu import AndroidGpu
from diff_tests.stdlib.android.heap_graph_tests import HeapGraph
@@ -279,6 +280,7 @@
*AndroidMemory(index_path, 'stdlib/android', 'AndroidMemory').fetch(),
*AndroidGpu(index_path, 'stdlib/android', 'AndroidGpu').fetch(),
*AndroidStdlib(index_path, 'stdlib/android', 'AndroidStdlib').fetch(),
+ *CpuClusters(index_path, 'stdlib/android', 'CpuClusters').fetch(),
*LinuxCpu(index_path, 'stdlib/linux/cpu', 'LinuxCpu').fetch(),
*DominatorTree(index_path, 'stdlib/graphs', 'DominatorTree').fetch(),
*CriticalPathTests(index_path, 'stdlib/graphs', 'CriticalPath').fetch(),
diff --git a/test/trace_processor/diff_tests/stdlib/android/cpu_cluster_tests.py b/test/trace_processor/diff_tests/stdlib/android/cpu_cluster_tests.py
new file mode 100644
index 0000000..fc1820b
--- /dev/null
+++ b/test/trace_processor/diff_tests/stdlib/android/cpu_cluster_tests.py
@@ -0,0 +1,314 @@
+#!/usr/bin/env python3
+# Copyright (C) 2024 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License a
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from python.generators.diff_tests.testing import Path
+from python.generators.diff_tests.testing import Csv, TextProto
+from python.generators.diff_tests.testing import DiffTestBlueprint
+from python.generators.diff_tests.testing import TestSuite
+
+
+class CpuClusters(TestSuite):
+
+ def test_android_cpu_cluster_type_one_core(self):
+ return DiffTestBlueprint(
+ trace=TextProto(r"""
+ packet {
+ cpu_info {
+ cpus {
+ processor: "unknown"
+ capacity: 1024
+ frequencies: 100000
+ frequencies: 200000
+ }
+ }
+ }
+ """),
+ query="""
+ INCLUDE PERFETTO MODULE android.cpu.cluster_type;
+
+ SELECT
+ ucpu,
+ cpu,
+ cluster_type
+ FROM
+ android_cpu_cluster_mapping;
+ """,
+ out=Csv("""
+ "ucpu","cpu","cluster_type"
+ 0,0,"[NULL]"
+ """))
+
+ def test_android_cpu_cluster_type_two_core(self):
+ return DiffTestBlueprint(
+ trace=TextProto(r"""
+ packet {
+ cpu_info {
+ cpus {
+ processor: "unknown"
+ capacity: 158
+ frequencies: 100000
+ frequencies: 200000
+ }
+ cpus {
+ processor: "unknown"
+ capacity: 1024
+ frequencies: 500000
+ frequencies: 574000
+ }
+ }
+ }
+ """),
+ query="""
+ INCLUDE PERFETTO MODULE android.cpu.cluster_type;
+
+ SELECT
+ ucpu,
+ cpu,
+ cluster_type
+ FROM
+ android_cpu_cluster_mapping;
+ """,
+ out=Csv("""
+ "ucpu","cpu","cluster_type"
+ 0,0,"little"
+ 1,1,"big"
+ """))
+
+ def test_android_cpu_cluster_type_three_core(self):
+ return DiffTestBlueprint(
+ trace=TextProto(r"""
+ packet {
+ cpu_info {
+ cpus {
+ processor: "unknown"
+ capacity: 158
+ frequencies: 100000
+ frequencies: 200000
+ }
+ cpus {
+ processor: "unknown"
+ capacity: 550
+ frequencies: 300000
+ frequencies: 400000
+ }
+ cpus {
+ processor: "unknown"
+ capacity: 1024
+ frequencies: 500000
+ frequencies: 574000
+ }
+ }
+ }
+ """),
+ query="""
+ INCLUDE PERFETTO MODULE android.cpu.cluster_type;
+
+ SELECT
+ ucpu,
+ cpu,
+ cluster_type
+ FROM
+ android_cpu_cluster_mapping;
+ """,
+ out=Csv("""
+ "ucpu","cpu","cluster_type"
+ 0,0,"little"
+ 1,1,"medium"
+ 2,2,"big"
+ """))
+
+ def test_android_cpu_cluster_type_four_core(self):
+ return DiffTestBlueprint(
+ trace=TextProto(r"""
+ packet {
+ cpu_info {
+ cpus {
+ processor: "unknown"
+ capacity: 158
+ frequencies: 100000
+ frequencies: 200000
+ }
+ cpus {
+ processor: "unknown"
+ capacity: 550
+ frequencies: 300000
+ frequencies: 400000
+ }
+ cpus {
+ processor: "unknown"
+ capacity: 700
+ frequencies: 400000
+ frequencies: 500000
+ }
+ cpus {
+ processor: "unknown"
+ capacity: 1024
+ frequencies: 500000
+ frequencies: 574000
+ }
+ }
+ }
+ """),
+ query="""
+ INCLUDE PERFETTO MODULE android.cpu.cluster_type;
+
+ SELECT
+ ucpu,
+ cpu,
+ cluster_type
+ FROM
+ android_cpu_cluster_mapping;
+ """,
+ out=Csv("""
+ "ucpu","cpu","cluster_type"
+ 0,0,"little"
+ 1,1,"medium"
+ 2,2,"medium"
+ 3,3,"big"
+ """))
+
+ def test_android_cpu_cluster_type_five_core(self):
+ return DiffTestBlueprint(
+ trace=TextProto(r"""
+ packet {
+ cpu_info {
+ cpus {
+ processor: "unknown"
+ capacity: 158
+ frequencies: 100000
+ frequencies: 200000
+ }
+ cpus {
+ processor: "unknown"
+ capacity: 550
+ frequencies: 300000
+ frequencies: 400000
+ }
+ cpus {
+ processor: "unknown"
+ capacity: 700
+ frequencies: 400000
+ frequencies: 500000
+ }
+ cpus {
+ processor: "unknown"
+ capacity: 800
+ frequencies: 500000
+ frequencies: 520000
+ }
+ cpus {
+ processor: "unknown"
+ capacity: 1024
+ frequencies: 500000
+ frequencies: 574000
+ }
+ }
+ }
+ """),
+ query="""
+ INCLUDE PERFETTO MODULE android.cpu.cluster_type;
+
+ SELECT
+ ucpu,
+ cpu,
+ cluster_type
+ FROM
+ android_cpu_cluster_mapping;
+ """,
+ out=Csv("""
+ "ucpu","cpu","cluster_type"
+ 0,0,"[NULL]"
+ 1,1,"[NULL]"
+ 2,2,"[NULL]"
+ 3,3,"[NULL]"
+ 4,4,"[NULL]"
+ """))
+
+ def test_android_cpu_cluster_type_capacity_not_present(self):
+ return DiffTestBlueprint(
+ trace=TextProto(r"""
+ packet {
+ cpu_info {
+ cpus {
+ processor: "unknown"
+ frequencies: 100000
+ frequencies: 200000
+ }
+ cpus {
+ processor: "unknown"
+ frequencies: 300000
+ frequencies: 400000
+ }
+ cpus {
+ processor: "unknown"
+ frequencies: 500000
+ frequencies: 574000
+ }
+ }
+ }
+ """),
+ query="""
+ INCLUDE PERFETTO MODULE android.cpu.cluster_type;
+
+ SELECT
+ ucpu,
+ cpu,
+ cluster_type
+ FROM
+ android_cpu_cluster_mapping;
+ """,
+ out=Csv("""
+ "ucpu","cpu","cluster_type"
+ 0,0,"little"
+ 1,1,"medium"
+ 2,2,"big"
+ """))
+
+ def test_android_cpu_cluster_type_insufficient_data_to_calculate(self):
+ return DiffTestBlueprint(
+ trace=TextProto(r"""
+ packet {
+ cpu_info {
+ cpus {
+ processor: "unknown"
+ frequencies: 10000
+ }
+ cpus {
+ processor: "unknown"
+ frequencies: 10000
+ }
+ cpus {
+ processor: "unknown"
+ frequencies: 10000
+ }
+ }
+ }
+ """),
+ query="""
+ INCLUDE PERFETTO MODULE android.cpu.cluster_type;
+
+ SELECT
+ ucpu,
+ cpu,
+ cluster_type
+ FROM
+ android_cpu_cluster_mapping;
+ """,
+ out=Csv("""
+ "ucpu","cpu","cluster_type"
+ 0,0,"[NULL]"
+ 1,1,"[NULL]"
+ 2,2,"[NULL]"
+ """))