Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3691)

Unified Diff: build/util/lib/common/perf_tests_helper.py

Issue 23578019: Copy perf_tests_helper.py into build/util/lib (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: build/util/lib/common/perf_tests_helper.py
===================================================================
--- build/util/lib/common/perf_tests_helper.py (revision 0)
+++ build/util/lib/common/perf_tests_helper.py (revision 0)
@@ -0,0 +1,213 @@
+# Copyright (c) 2012 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import re
+import sys
+
+import json
+import logging
+import math
+
+
+sys.path.append(
+ os.path.abspath(os.path.join(os.path.dirname(__file__),
+ os.pardir, os.pardir, os.pardir,
+ 'tools', 'telemetry')))
+
+from telemetry.page import result_data_type
bulach 2013/09/11 11:41:07 can we define the result_data_type here rather tha
+
+
+# Mapping from result type to test output
+RESULT_TYPES = {result_data_type.UNIMPORTANT: 'RESULT ',
+ result_data_type.DEFAULT: '*RESULT ',
+ result_data_type.INFORMATIONAL: '',
+ result_data_type.UNIMPORTANT_HISTOGRAM: 'HISTOGRAM ',
+ result_data_type.HISTOGRAM: '*HISTOGRAM '}
+
+def _EscapePerfResult(s):
+ """Escapes |s| for use in a perf result."""
+ return re.sub('[\:|=/#&,]', '_', s)
+
+
+def _Flatten(values):
+ """Returns a simple list without sub-lists."""
+ ret = []
+ for entry in values:
+ if isinstance(entry, list):
+ ret.extend(_Flatten(entry))
+ else:
+ ret.append(entry)
+ return ret
+
+
+def GeomMeanAndStdDevFromHistogram(histogram_json):
+ histogram = json.loads(histogram_json)
+ # Handle empty histograms gracefully.
+ if not 'buckets' in histogram:
+ return 0.0, 0.0
+ count = 0
+ sum_of_logs = 0
+ for bucket in histogram['buckets']:
+ if 'high' in bucket:
+ bucket['mean'] = (bucket['low'] + bucket['high']) / 2.0
+ else:
+ bucket['mean'] = bucket['low']
+ if bucket['mean'] > 0:
+ sum_of_logs += math.log(bucket['mean']) * bucket['count']
+ count += bucket['count']
+
+ if count == 0:
+ return 0.0, 0.0
+
+ sum_of_squares = 0
+ geom_mean = math.exp(sum_of_logs / count)
+ for bucket in histogram['buckets']:
+ if bucket['mean'] > 0:
+ sum_of_squares += (bucket['mean'] - geom_mean) ** 2 * bucket['count']
+ return geom_mean, math.sqrt(sum_of_squares / count)
+
+
+def _MeanAndStdDevFromList(values):
+ avg = None
+ sd = None
+ if len(values) > 1:
+ try:
+ value = '[%s]' % ','.join([str(v) for v in values])
+ avg = sum([float(v) for v in values]) / len(values)
+ sqdiffs = [(float(v) - avg) ** 2 for v in values]
+ variance = sum(sqdiffs) / (len(values) - 1)
+ sd = math.sqrt(variance)
+ except ValueError:
+ value = ", ".join(values)
+ else:
+ value = values[0]
+ return value, avg, sd
+
+
+def PrintPages(page_list):
+ """Prints list of pages to stdout in the format required by perf tests."""
+ print 'Pages: [%s]' % ','.join([_EscapePerfResult(p) for p in page_list])
+
+
+def PrintPerfResult(measurement, trace, values, units,
+ result_type=result_data_type.DEFAULT,
+ print_to_stdout=True):
+ """Prints numerical data to stdout in the format required by perf tests.
+
+ The string args may be empty but they must not contain any colons (:) or
+ equals signs (=).
+
+ Args:
+ measurement: A description of the quantity being measured, e.g. "vm_peak".
+ trace: A description of the particular data point, e.g. "reference".
+ values: A list of numeric measured values. An N-dimensional list will be
+ flattened and treated as a simple list.
+ units: A description of the units of measure, e.g. "bytes".
+ result_type: Accepts values of result_data_type.ALL_TYPES.
+ print_to_stdout: If True, prints the output in stdout instead of returning
+ the output to caller.
+
+ Returns:
+ String of the formated perf result.
+ """
+ assert (result_data_type.IsValidType(result_type),
+ 'result type: %s is invalid' % result_type)
+
+ trace_name = _EscapePerfResult(trace)
+
+ if (result_type == result_data_type.UNIMPORTANT or
+ result_type == result_data_type.DEFAULT or
+ result_type == result_data_type.INFORMATIONAL):
+ assert isinstance(values, list)
+ assert len(values)
+ assert '/' not in measurement
+ value, avg, sd = _MeanAndStdDevFromList(_Flatten(values))
+ output = '%s%s: %s%s%s %s' % (
+ RESULT_TYPES[result_type],
+ _EscapePerfResult(measurement),
+ trace_name,
+ # Do not show equal sign if the trace is empty. Usually it happens when
+ # measurement is enough clear to describe the result.
+ '= ' if trace_name else '',
+ value,
+ units)
+ else:
+ assert result_data_type.IsHistogram(result_type)
+ assert isinstance(values, list)
+ # The histograms can only be printed individually, there's no computation
+ # across different histograms.
+ assert len(values) == 1
+ value = values[0]
+ output = '%s%s: %s= %s' % (
+ RESULT_TYPES[result_type],
+ _EscapePerfResult(measurement),
+ trace_name,
+ value)
+ avg, sd = GeomMeanAndStdDevFromHistogram(value)
+
+ if avg:
+ output += '\nAvg %s: %f%s' % (measurement, avg, units)
+ if sd:
+ output += '\nSd %s: %f%s' % (measurement, sd, units)
+ if print_to_stdout:
+ print output
+ sys.stdout.flush()
+ return output
+
+
+class CacheControl(object):
bulach 2013/09/11 11:41:07 could you remove both CacheControl and PerfControl
+ _DROP_CACHES = '/proc/sys/vm/drop_caches'
+
+ def __init__(self, adb):
+ self._adb = adb
+
+ def DropRamCaches(self):
+ """Drops the filesystem ram caches for performance testing."""
+ self._adb.RunShellCommand('su -c sync')
+ self._adb.SetProtectedFileContents(CacheControl._DROP_CACHES, '3')
+
+
+class PerfControl(object):
+ """Provides methods for setting the performance mode of a device."""
+ _SCALING_GOVERNOR_FMT = (
+ '/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor')
+
+ def __init__(self, adb):
+ self._adb = adb
+ kernel_max = self._adb.GetFileContents('/sys/devices/system/cpu/kernel_max',
+ log_result=False)
+ assert kernel_max, 'Unable to find /sys/devices/system/cpu/kernel_max'
+ self._kernel_max = int(kernel_max[0])
+ logging.info('Maximum CPU index: %d' % self._kernel_max)
+ self._original_scaling_governor = self._adb.GetFileContents(
+ PerfControl._SCALING_GOVERNOR_FMT % 0,
+ log_result=False)[0]
+
+ def SetHighPerfMode(self):
+ """Sets the highest possible performance mode for the device."""
+ self._SetScalingGovernorInternal('performance')
+
+ def SetDefaultPerfMode(self):
+ """Sets the performance mode for the device to its default mode."""
+ product_model = self._adb.GetProductModel()
+ governor_mode = {
+ "GT-I9300" : 'pegasusq',
+ "Galaxy Nexus" : 'interactive',
+ "Nexus 4" : 'ondemand',
+ "Nexus 7" : 'interactive',
+ "Nexus 10": 'interactive'
+ }.get(product_model, 'ondemand')
+ self._SetScalingGovernorInternal(governor_mode)
+
+ def RestoreOriginalPerfMode(self):
+ """Resets the original performance mode of the device."""
+ self._SetScalingGovernorInternal(self._original_scaling_governor)
+
+ def _SetScalingGovernorInternal(self, value):
+ for cpu in range(self._kernel_max + 1):
+ scaling_governor_file = PerfControl._SCALING_GOVERNOR_FMT % cpu
+ if self._adb.FileExistsOnDevice(scaling_governor_file):
+ logging.info('Writing scaling governor mode \'%s\' -> %s' %
+ (value, scaling_governor_file))
+ self._adb.SetProtectedFileContents(scaling_governor_file, value)
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698