Index: build/android/pylib/perf_tests_helper.py |
=================================================================== |
--- build/android/pylib/perf_tests_helper.py (revision 222891) |
+++ build/android/pylib/perf_tests_helper.py (working copy) |
@@ -1,203 +0,0 @@ |
-# 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 android_commands |
-import json |
-import logging |
-import math |
- |
-# Valid values of result type. |
-RESULT_TYPES = {'unimportant': 'RESULT ', |
- 'default': '*RESULT ', |
- 'informational': '', |
- 'unimportant-histogram': 'HISTOGRAM ', |
- '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='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_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_type in RESULT_TYPES, 'result type: %s is invalid' % result_type |
- |
- trace_name = _EscapePerfResult(trace) |
- |
- if result_type in ['unimportant', 'default', '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_type in ['histogram', 'unimportant-histogram']) |
- 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 %s' % ( |
- RESULT_TYPES[result_type], |
- _EscapePerfResult(measurement), |
- trace_name, |
- value, |
- units) |
- 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): |
- _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) |