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

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

Issue 73173005: Telemetry: manage CPU core online state for some device types (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: . Created 7 years, 1 month 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright 2013 The Chromium Authors. All rights reserved. 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 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 5
6 import logging 6 import logging
7 import time
7 8
8 9
9 class PerfControl(object): 10 class PerfControl(object):
10 """Provides methods for setting the performance mode of a device.""" 11 """Provides methods for setting the performance mode of a device."""
11 _SCALING_GOVERNOR_FMT = ( 12
12 '/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor')
13 _KERNEL_MAX = '/sys/devices/system/cpu/kernel_max' 13 _KERNEL_MAX = '/sys/devices/system/cpu/kernel_max'
14 _CPU_DIR_FMT = '/sys/devices/system/cpu/cpu%d/'
15 _SCALING_GOVERNOR_FMT = _CPU_DIR_FMT + 'cpufreq/scaling_governor'
16 _CPU_ONLINE_FMT = _CPU_DIR_FMT + 'online'
17 _SCALING_FREQUENCY_STAT_NAMES = [
18 'cpufreq/scaling_min_freq',
19 'cpufreq/scaling_max_freq',
20 'cpufreq/scaling_cur_freq',
21 ]
14 22
15 def __init__(self, adb): 23 def __init__(self, adb):
16 self._adb = adb 24 self._adb = adb
17 kernel_max = self._adb.GetFileContents(PerfControl._KERNEL_MAX, 25 kernel_max = self._adb.GetFileContents(PerfControl._KERNEL_MAX,
18 log_result=False) 26 log_result=False)
19 assert kernel_max, 'Unable to find %s' % PerfControl._KERNEL_MAX 27 assert kernel_max, 'Unable to find %s' % PerfControl._KERNEL_MAX
20 self._kernel_max = int(kernel_max[0]) 28 self._kernel_max = int(kernel_max[0])
21 logging.info('Maximum CPU index: %d', self._kernel_max) 29 logging.info('Maximum CPU index: %d', self._kernel_max)
22 self._original_scaling_governor = self._adb.GetFileContents( 30 self._original_scaling_governor = self._adb.GetFileContents(
23 PerfControl._SCALING_GOVERNOR_FMT % 0, 31 PerfControl._SCALING_GOVERNOR_FMT % 0,
24 log_result=False)[0] 32 log_result=False)[0]
33 self._LogCurrentCpuFrequencyInfo()
34
35 # Bring CPUs online/offline manually on some device types to reduce variance
36 # in performance measurements. Other device types are either hard to manage
37 # properly or we did not decide what settings look 'typical' for them.
38 # 'Galaxy Nexus' and 'Nexus 10' seem to use both cores all time without
39 # hotplugging them manually, but we still may need to manage their frequency
40 # later. TODO(pasko): manage Nexus 7 CPUs with PerfControl, v1 and v2 differ
41 # significantly.
42 #
43 # *Not managing* CPUs manually means that only a subset of CPU properties
44 # are updated (scaling governor only now) and only for those CPUs
45 # represented by sysfs at the moment (/sys/devices/system/cpu/cpuX/...)
46 self._manage_cpus_manually = False
47 cpu_indexes_to_manage_manually = {
48 'Nexus 4': [0, 1],
49 'Nexus 5': [0, 1],
50 }
51 device_model = self._adb.GetProductModel()
52 if device_model in cpu_indexes_to_manage_manually:
53 self._manage_cpus_manually = True
54 self._cpus_to_manage = cpu_indexes_to_manage_manually[device_model]
55 self._cpus_on_originally = []
56 for cpu in xrange(self._kernel_max + 1):
57 if '1' in self._ReadProtectedFile(PerfControl._CPU_ONLINE_FMT % cpu):
58 self._cpus_on_originally.append(cpu)
59
60 def _BringCpuOffline(self, cpu_index):
61 logging.info('Bringing CPU #%d offline.', cpu_index)
62 self._adb.SetProtectedFileContents(
63 PerfControl._CPU_ONLINE_FMT % cpu_index, '0')
64
65 def _BringCpuOnline(self, cpu_index):
66 "Brings a CPU core online, waits for it to show up in sysfs."
67
68 logging.info('Bringing CPU #%d online.' %cpu_index)
69 times_to_wait_left = 5
70 cpu_online_file = PerfControl._CPU_ONLINE_FMT % cpu_index
71 while (True):
72 self._adb.SetProtectedFileContents(cpu_online_file, '1')
73 if '1' in self._ReadProtectedFile(cpu_online_file):
74 break
75 if times_to_wait_left == 0:
76 logging.warning('Gave up bringing CPU %d online', cpu_index)
77 break
78 times_to_wait_left -= 1
79 logging.warning('Could not bring CPU %d online, retrying..',
80 cpu_index)
81 time.sleep(0.1)
82
83 def _ReadProtectedFile(self, file_name):
84 return '\n'.join(self._adb.GetProtectedFileContents(file_name))
85
86 def _LogCurrentCpuFrequencyInfo(self):
87 for cpu in xrange(self._kernel_max + 1):
88 for stat_name in PerfControl._SCALING_FREQUENCY_STAT_NAMES:
89 stat_file_name = (PerfControl._CPU_DIR_FMT + stat_name) % cpu;
90 if self._adb.FileExistsOnDevice(stat_file_name):
91 info = self._ReadProtectedFile(stat_file_name)
92 logging.info('CPU #%d frequency info: %s: %s', cpu, stat_name, info)
25 93
26 def SetHighPerfMode(self): 94 def SetHighPerfMode(self):
27 """Sets the highest possible performance mode for the device.""" 95 """Sets the highest possible performance mode for the device."""
28 self._SetScalingGovernorInternal('performance') 96
97 if not self._manage_cpus_manually:
98 for cpu in xrange(self._kernel_max + 1):
99 self._SetScalingGovernorInternal(cpu, 'performance')
100 else:
101 # Stop the 'mpdecision' hotplug manager to get a constant number of CPUs
102 # online when running tests. TODO(pasko): stop 'thermald'.
bulach 2013/11/19 15:13:57 make sure you send a heads up to chrome-perf-sheri
pasko 2013/11/19 18:00:08 Yes, I am planning to let sheriffs know, this can
103 self._adb.RunShellCommandWithSU('stop mpdecision')
104 for cpu in xrange(self._kernel_max + 1):
105 if cpu in self._cpus_to_manage:
106 self._BringCpuOnline(cpu)
107 self._SetScalingGovernorInternal(cpu, 'performance')
108 else:
109 self._BringCpuOffline(cpu)
29 110
30 def SetDefaultPerfMode(self): 111 def SetDefaultPerfMode(self):
31 """Sets the performance mode for the device to its default mode.""" 112 """Sets the performance mode for the device to its default mode."""
113
114 self._LogCurrentCpuFrequencyInfo()
32 product_model = self._adb.GetProductModel() 115 product_model = self._adb.GetProductModel()
33 governor_mode = { 116 governor_mode = {
34 'GT-I9300': 'pegasusq', 117 'GT-I9300': 'pegasusq',
35 'Galaxy Nexus': 'interactive', 118 'Galaxy Nexus': 'interactive',
36 'Nexus 4': 'ondemand', 119 'Nexus 4': 'ondemand',
120 'Nexus 5': 'ondemand',
37 'Nexus 7': 'interactive', 121 'Nexus 7': 'interactive',
38 'Nexus 10': 'interactive' 122 'Nexus 10': 'interactive'
39 }.get(product_model, 'ondemand') 123 }.get(product_model, 'ondemand')
40 self._SetScalingGovernorInternal(governor_mode) 124 if not self._manage_cpus_manually:
125 # Set the default perf mode only if no CPUs were forced online.
126 for cpu in xrange(self._kernel_max + 1):
127 self._SetScalingGovernorInternal(cpu, governor_mode)
128 # If 'mpdecision' is present on the system, it will manage CPU
129 # online/offline state, otherwise it is a no-op.
130 self._adb.RunShellCommandWithSU('start mpdecision')
41 131
42 def RestoreOriginalPerfMode(self): 132 def RestoreOriginalPerfMode(self):
43 """Resets the original performance mode of the device.""" 133 """Resets the original performance mode of the device."""
44 self._SetScalingGovernorInternal(self._original_scaling_governor)
45 134
46 def _SetScalingGovernorInternal(self, value): 135 self._LogCurrentCpuFrequencyInfo()
47 for cpu in range(self._kernel_max + 1): 136 if not self._manage_cpus_manually:
48 scaling_governor_file = PerfControl._SCALING_GOVERNOR_FMT % cpu 137 for cpu in xrange(self._kernel_max + 1):
49 if self._adb.FileExistsOnDevice(scaling_governor_file): 138 self._SetScalingGovernorInternal(cpu, self._original_scaling_governor)
50 logging.info('Writing scaling governor mode \'%s\' -> %s', 139 else:
51 value, scaling_governor_file) 140 for cpu in xrange(self._kernel_max + 1):
52 self._adb.SetProtectedFileContents(scaling_governor_file, value) 141 if cpu in self._cpus_on_originally:
142 self._BringCpuOnline(cpu)
143 self._SetScalingGovernorInternal(cpu, self._original_scaling_governor)
144 else:
145 self._SetScalingGovernorInternal(cpu, self._original_scaling_governor)
146 self._BringCpuOffline(cpu)
147 self._adb.RunShellCommandWithSU('start mpdecision')
148
149 def _SetScalingGovernorInternal(self, cpu, value):
150 scaling_governor_file = PerfControl._SCALING_GOVERNOR_FMT % cpu
151 if (self._manage_cpus_manually or
152 self._adb.FileExistsOnDevice(scaling_governor_file)):
153 logging.info('Writing scaling governor mode "%s" -> %s',
154 value, scaling_governor_file)
155 self._adb.SetProtectedFileContents(scaling_governor_file, value)
OLDNEW
« 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