diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2017-11-01 08:15:40 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2017-11-01 08:15:40 +0000 |
commit | f8d0e6306d3f7d60c17db4edf09cfe4465cccea0 (patch) | |
tree | 26227aab10928822b22ab43e71eefe40beb67769 | |
parent | fc2901cc79453386e9db4e03df1dc3ff6a1b9638 (diff) | |
parent | 04b7016e8a090ac8147874bab99041345f312b98 (diff) | |
download | lisa-f8d0e6306d3f7d60c17db4edf09cfe4465cccea0.tar.gz |
Snap for 4428213 from 04b7016e8a090ac8147874bab99041345f312b98 to pi-release
Change-Id: If0903f9aba40dc45d71dd05b521d32bbef5af761
-rwxr-xr-x | experiments/run_uibench_cgroup.py | 19 | ||||
-rw-r--r-- | libs/utils/analysis/residency_analysis.py | 19 | ||||
-rw-r--r-- | libs/utils/trace.py | 35 |
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 ############################################################################### |