aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2017-11-01 08:15:40 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2017-11-01 08:15:40 +0000
commitf8d0e6306d3f7d60c17db4edf09cfe4465cccea0 (patch)
tree26227aab10928822b22ab43e71eefe40beb67769
parentfc2901cc79453386e9db4e03df1dc3ff6a1b9638 (diff)
parent04b7016e8a090ac8147874bab99041345f312b98 (diff)
downloadlisa-f8d0e6306d3f7d60c17db4edf09cfe4465cccea0.tar.gz
Snap for 4428213 from 04b7016e8a090ac8147874bab99041345f312b98 to pi-release
Change-Id: If0903f9aba40dc45d71dd05b521d32bbef5af761
-rwxr-xr-xexperiments/run_uibench_cgroup.py19
-rw-r--r--libs/utils/analysis/residency_analysis.py19
-rw-r--r--libs/utils/trace.py35
3 files changed, 56 insertions, 17 deletions
diff --git a/experiments/run_uibench_cgroup.py b/experiments/run_uibench_cgroup.py
index 76e91b5..f1d3408 100755
--- a/experiments/run_uibench_cgroup.py
+++ b/experiments/run_uibench_cgroup.py
@@ -58,11 +58,10 @@ parser.add_argument('--serial', dest='serial', action='store',
args = parser.parse_args()
-def experiment():
+def experiment(outdir):
# Get workload
wload = Workload.getInstance(te, 'UiBench')
- outdir=te.res_dir + '_' + args.out_prefix
try:
shutil.rmtree(outdir)
except:
@@ -127,4 +126,18 @@ if args.serial:
te = TestEnv(my_conf, wipe=False)
target = te.target
-results = experiment()
+outdir=te.res_dir + '_' + args.out_prefix
+results = experiment(outdir)
+
+trace_file = os.path.join(outdir, "trace.html")
+tr = Trace(None, trace_file,
+ cgroup_info = {
+ 'cgroups': ['foreground', 'background', 'system-background', 'top-app', 'rt'],
+ 'controller_ids': { 4: 'cpuset', 2: 'schedtune' }
+ },
+ events=[ 'sched_switch', 'cgroup_attach_task_devlib', 'cgroup_attach_task', 'sched_process_fork' ],
+ normalize_time=False)
+
+tr.data_frame.cpu_residencies_cgroup('schedtune')
+tr.analysis.residency.plot_cgroup('schedtune', idle=False)
+tr.analysis.residency.plot_cgroup('schedtune', idle=True)
diff --git a/libs/utils/analysis/residency_analysis.py b/libs/utils/analysis/residency_analysis.py
index 797e2f4..7cfed3d 100644
--- a/libs/utils/analysis/residency_analysis.py
+++ b/libs/utils/analysis/residency_analysis.py
@@ -20,6 +20,8 @@
import matplotlib.gridspec as gridspec
import matplotlib.pyplot as plt
from matplotlib import font_manager as fm
+from matplotlib import __version__ as matplotlib_version
+from packaging import version
import pandas as pd
import pylab as pl
import operator
@@ -214,6 +216,17 @@ class ResidencyAnalysis(AnalysisModule):
controller: name of the controller
idle: Consider idle time?
"""
+ required_version = '1.4'
+ if version.parse(matplotlib_version) >= version.parse(required_version):
+ plt.style.use('ggplot')
+ else:
+ logging.info("matplotlib version ({}) is too old to support ggplot. Upgrade to version {}"\
+ .format(matplotlib_version, required_version))
+
+ suffix = 'with_idle' if idle else 'without_idle'
+ figname = '{}/residency_for_{}_{}_{}.png'\
+ .format(self._trace.plots_dir, cgroup, controller, suffix)
+
df = self._dfg_cpu_residencies_cgroup(controller)
# Plot per-CPU break down for a single CGroup (Single pie plot)
if cgroup != 'all':
@@ -221,7 +234,6 @@ class ResidencyAnalysis(AnalysisModule):
df = df.drop('total', 1)
df = df.apply(lambda x: x*10)
- plt.style.use('ggplot')
colors = plt.rcParams['axes.color_cycle']
fig, axes = plt.subplots(nrows=1, ncols=1, figsize=(8,8))
patches, texts, autotexts = axes.pie(df.loc[cgroup], labels=df.columns, autopct='%.2f', colors=colors)
@@ -233,7 +245,7 @@ class ResidencyAnalysis(AnalysisModule):
plt.setp(autotexts, fontproperties=proptease)
plt.setp(texts, fontproperties=proptease)
- plt.show()
+ pl.savefig(figname, bbox_inches='tight')
return
# Otherwise, Plot per-CGroup of a Controller down for each CPU
@@ -241,7 +253,6 @@ class ResidencyAnalysis(AnalysisModule):
df = df[pd.isnull(df.index) != True]
# Bug in matplot lib causes plotting issues when residency is < 1
df = df.apply(lambda x: x*10)
- plt.style.use('ggplot')
colors = plt.rcParams['axes.color_cycle']
fig, axes = plt.subplots(nrows=5, ncols=2, figsize=(12,30))
@@ -250,7 +261,7 @@ class ResidencyAnalysis(AnalysisModule):
ax.set(ylabel='', title=col, aspect='equal')
axes[0, 0].legend(bbox_to_anchor=(0, 0.5))
- plt.show()
+ pl.savefig(figname, bbox_inches='tight')
diff --git a/libs/utils/trace.py b/libs/utils/trace.py
index c2f81cb..6b4c8b0 100644
--- a/libs/utils/trace.py
+++ b/libs/utils/trace.py
@@ -142,8 +142,7 @@ class Trace(object):
self.cgroup_info = cgroup_info
self.__registerTraceEvents(events) if events else None
- self.__parseTrace(data_dir, tasks, window, normalize_time,
- trace_format)
+ self.__parseTrace(data_dir, tasks, window, trace_format)
# Minimum and Maximum x_time to use for all plots
self.x_min = 0
@@ -216,7 +215,7 @@ class Trace(object):
if 'cpu_frequency' in events:
self.events.append('cpu_frequency_devlib')
- def __parseTrace(self, path, window, trace_format):
+ def __parseTrace(self, path, tasks, window, trace_format):
"""
Internal method in charge of performing the actual parsing of the
trace.
@@ -224,6 +223,9 @@ class Trace(object):
:param path: path to the trace folder (or trace file)
:type path: str
+ :param tasks: filter data for the specified tasks only
+ :type tasks: list(str)
+
:param window: time window to consider when parsing the trace
:type window: tuple(int, int)
@@ -269,7 +271,7 @@ class Trace(object):
'nor function stats')
# Index PIDs and Task names
- self.__loadTasksNames()
+ self.__loadTasksNames(tasks)
self.__computeTimeSpan()
@@ -305,21 +307,26 @@ class Trace(object):
for evt in self.available_events:
self._log.debug(' - %s', evt)
- def __loadTasksNames(self):
+ def __loadTasksNames(self, tasks):
"""
Try to load tasks names using one of the supported events.
+
+ :param tasks: list of task names. If None, load all tasks found.
+ :type tasks: list(str) or NoneType
"""
- def load(event, name_key, pid_key):
+ def load(tasks, event, name_key, pid_key):
df = self._dfg_trace_event(event)
+ if tasks is None:
+ tasks = df[name_key].unique()
self._scanTasks(df, name_key=name_key, pid_key=pid_key)
self._scanTgids(df)
if 'sched_switch' in self.available_events:
- load('sched_switch', 'prev_comm', 'prev_pid')
+ load(tasks, 'sched_switch', 'prev_comm', 'prev_pid')
return
if 'sched_load_avg_task' in self.available_events:
- load('sched_load_avg_task', 'comm', 'pid')
+ load(tasks, 'sched_load_avg_task', 'comm', 'pid')
return
self._log.warning('Failed to load tasks names from trace events')
@@ -415,7 +422,14 @@ class Trace(object):
:param name: task PID
:type name: int
+
+ :return: the list of names of the tasks whose PID matches the required one,
+ the last time they ran in the current trace
"""
+ try:
+ return self._tasks_by_pid.ix[pid].values[0]
+ except KeyError:
+ return None
def getTgidFromPid(self, pid):
return _pid_tgid.ix[pid].values[0]
@@ -590,8 +604,9 @@ class Trace(object):
sdf = sdf.join(self._pid_tgid, on='prev_pid').rename(columns = {'tgid': 'prev_tgid'})
df = self._tasks_by_pid.rename(columns = { 'next_comm': 'comm' })
- sdf = sdf.join(df, on='next_tgid').rename(columns = {'comm': 'next_tgid_comm'})
- sdf = sdf.join(df, on='prev_tgid').rename(columns = {'comm': 'prev_tgid_comm'})
+
+ sdf = sdf.join(df, on='next_tgid').rename(columns = {'TaskName': 'next_tgid_comm'})
+ sdf = sdf.join(df, on='prev_tgid').rename(columns = {'TaskName': 'prev_tgid_comm'})
return sdf
###############################################################################