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

Side by Side Diff: build/android/pylib/perf/perf_control.py

Issue 2101243005: Add a snapshot of flutter/engine/src/build to our sdk (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: add README.dart Created 4 years, 5 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 unified diff | Download patch
OLDNEW
(Empty)
1 # Copyright 2013 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4
5 import atexit
6 import logging
7
8 from pylib import android_commands
9 from pylib.device import device_errors
10 from pylib.device import device_utils
11
12
13 class PerfControl(object):
14 """Provides methods for setting the performance mode of a device."""
15 _CPU_PATH = '/sys/devices/system/cpu'
16 _KERNEL_MAX = '/sys/devices/system/cpu/kernel_max'
17
18 def __init__(self, device):
19 # TODO(jbudorick) Remove once telemetry gets switched over.
20 if isinstance(device, android_commands.AndroidCommands):
21 device = device_utils.DeviceUtils(device)
22 self._device = device
23 # this will raise an AdbCommandFailedError if no CPU files are found
24 self._cpu_files = self._device.RunShellCommand(
25 'ls -d cpu[0-9]*', cwd=self._CPU_PATH, check_return=True, as_root=True)
26 assert self._cpu_files, 'Failed to detect CPUs.'
27 self._cpu_file_list = ' '.join(self._cpu_files)
28 logging.info('CPUs found: %s', self._cpu_file_list)
29 self._have_mpdecision = self._device.FileExists('/system/bin/mpdecision')
30
31 def SetHighPerfMode(self):
32 """Sets the highest stable performance mode for the device."""
33 try:
34 self._device.EnableRoot()
35 except device_errors.CommandFailedError:
36 message = 'Need root for performance mode. Results may be NOISY!!'
37 logging.warning(message)
38 # Add an additional warning at exit, such that it's clear that any results
39 # may be different/noisy (due to the lack of intended performance mode).
40 atexit.register(logging.warning, message)
41 return
42
43 product_model = self._device.product_model
44 # TODO(epenner): Enable on all devices (http://crbug.com/383566)
45 if 'Nexus 4' == product_model:
46 self._ForceAllCpusOnline(True)
47 if not self._AllCpusAreOnline():
48 logging.warning('Failed to force CPUs online. Results may be NOISY!')
49 self._SetScalingGovernorInternal('performance')
50 elif 'Nexus 5' == product_model:
51 self._ForceAllCpusOnline(True)
52 if not self._AllCpusAreOnline():
53 logging.warning('Failed to force CPUs online. Results may be NOISY!')
54 self._SetScalingGovernorInternal('performance')
55 self._SetScalingMaxFreq(1190400)
56 self._SetMaxGpuClock(200000000)
57 else:
58 self._SetScalingGovernorInternal('performance')
59
60 def SetPerfProfilingMode(self):
61 """Enables all cores for reliable perf profiling."""
62 self._ForceAllCpusOnline(True)
63 self._SetScalingGovernorInternal('performance')
64 if not self._AllCpusAreOnline():
65 if not self._device.HasRoot():
66 raise RuntimeError('Need root to force CPUs online.')
67 raise RuntimeError('Failed to force CPUs online.')
68
69 def SetDefaultPerfMode(self):
70 """Sets the performance mode for the device to its default mode."""
71 if not self._device.HasRoot():
72 return
73 product_model = self._device.product_model
74 if 'Nexus 5' == product_model:
75 if self._AllCpusAreOnline():
76 self._SetScalingMaxFreq(2265600)
77 self._SetMaxGpuClock(450000000)
78
79 governor_mode = {
80 'GT-I9300': 'pegasusq',
81 'Galaxy Nexus': 'interactive',
82 'Nexus 4': 'ondemand',
83 'Nexus 5': 'ondemand',
84 'Nexus 7': 'interactive',
85 'Nexus 10': 'interactive'
86 }.get(product_model, 'ondemand')
87 self._SetScalingGovernorInternal(governor_mode)
88 self._ForceAllCpusOnline(False)
89
90 def GetCpuInfo(self):
91 online = (output.rstrip() == '1' and status == 0
92 for (_, output, status) in self._ForEachCpu('cat "$CPU/online"'))
93 governor = (output.rstrip() if status == 0 else None
94 for (_, output, status)
95 in self._ForEachCpu('cat "$CPU/cpufreq/scaling_governor"'))
96 return zip(self._cpu_files, online, governor)
97
98 def _ForEachCpu(self, cmd):
99 script = '; '.join([
100 'for CPU in %s' % self._cpu_file_list,
101 'do %s' % cmd,
102 'echo -n "%~%$?%~%"',
103 'done'
104 ])
105 output = self._device.RunShellCommand(
106 script, cwd=self._CPU_PATH, check_return=True, as_root=True)
107 output = '\n'.join(output).split('%~%')
108 return zip(self._cpu_files, output[0::2], (int(c) for c in output[1::2]))
109
110 def _WriteEachCpuFile(self, path, value):
111 results = self._ForEachCpu(
112 'test -e "$CPU/{path}" && echo {value} > "$CPU/{path}"'.format(
113 path=path, value=value))
114 cpus = ' '.join(cpu for (cpu, _, status) in results if status == 0)
115 if cpus:
116 logging.info('Successfully set %s to %r on: %s', path, value, cpus)
117 else:
118 logging.warning('Failed to set %s to %r on any cpus')
119
120 def _SetScalingGovernorInternal(self, value):
121 self._WriteEachCpuFile('cpufreq/scaling_governor', value)
122
123 def _SetScalingMaxFreq(self, value):
124 self._WriteEachCpuFile('cpufreq/scaling_max_freq', '%d' % value)
125
126 def _SetMaxGpuClock(self, value):
127 self._device.WriteFile('/sys/class/kgsl/kgsl-3d0/max_gpuclk',
128 str(value),
129 as_root=True)
130
131 def _AllCpusAreOnline(self):
132 results = self._ForEachCpu('cat "$CPU/online"')
133 # TODO(epenner): Investigate why file may be missing
134 # (http://crbug.com/397118)
135 return all(output.rstrip() == '1' and status == 0
136 for (cpu, output, status) in results
137 if cpu != 'cpu0')
138
139 def _ForceAllCpusOnline(self, force_online):
140 """Enable all CPUs on a device.
141
142 Some vendors (or only Qualcomm?) hot-plug their CPUs, which can add noise
143 to measurements:
144 - In perf, samples are only taken for the CPUs that are online when the
145 measurement is started.
146 - The scaling governor can't be set for an offline CPU and frequency scaling
147 on newly enabled CPUs adds noise to both perf and tracing measurements.
148
149 It appears Qualcomm is the only vendor that hot-plugs CPUs, and on Qualcomm
150 this is done by "mpdecision".
151
152 """
153 if self._have_mpdecision:
154 script = 'stop mpdecision' if force_online else 'start mpdecision'
155 self._device.RunShellCommand(script, check_return=True, as_root=True)
156
157 if not self._have_mpdecision and not self._AllCpusAreOnline():
158 logging.warning('Unexpected cpu hot plugging detected.')
159
160 if force_online:
161 self._ForEachCpu('echo 1 > "$CPU/online"')
OLDNEW
« no previous file with comments | « build/android/pylib/perf/cache_control.py ('k') | build/android/pylib/perf/perf_control_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698