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

Side by Side Diff: tools/perf/metrics/power.py

Issue 350763005: [Telemetry] Power metric: subtract quiescent power draw from result (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « tools/perf/measurements/webrtc.py ('k') | 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 2014 The Chromium Authors. All rights reserved. 1 # Copyright 2014 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 import time
6
5 from metrics import Metric 7 from metrics import Metric
6 from telemetry.value import scalar 8 from telemetry.value import scalar
7 9
10
8 class PowerMetric(Metric): 11 class PowerMetric(Metric):
9 """A metric for measuring power usage.""" 12 """A metric for measuring power usage."""
10 13
11 def __init__(self): 14 def __init__(self, browser, quiescent_measurement_time_s=0):
15 """PowerMetric Constructor.
16
17 Args:
18 browser: browser object to use.
19 quiescent_measurement_time_s: time to measure quiescent power,
20 in seconds."""
12 super(PowerMetric, self).__init__() 21 super(PowerMetric, self).__init__()
13 self._browser = None 22 self._browser = browser
14 self._running = False 23 self._running = False
15 self._starting_cpu_stats = None 24 self._starting_cpu_stats = None
16 self._results = None 25 self._results = None
26 self._quiescent_power_draw_mwh = 0
27 self._MeasureQuiescentPower(quiescent_measurement_time_s)
17 28
18 def __del__(self): 29 def __del__(self):
19 # TODO(jeremy): Remove once crbug.com/350841 is fixed. 30 # TODO(jeremy): Remove once crbug.com/350841 is fixed.
20 # Don't leave power monitoring processes running on the system. 31 # Don't leave power monitoring processes running on the system.
21 self._StopInternal() 32 self._StopInternal()
22 parent = super(PowerMetric, self) 33 parent = super(PowerMetric, self)
23 if hasattr(parent, '__del__'): 34 if hasattr(parent, '__del__'):
24 parent.__del__() 35 parent.__del__()
25 36
26 def _StopInternal(self): 37 def _StopInternal(self):
27 """ Stop monitoring power if measurement is running. This function is 38 """Stop monitoring power if measurement is running. This function is
28 idempotent.""" 39 idempotent."""
29 if not self._running: 40 if not self._running:
30 return 41 return
31 self._running = False 42 self._running = False
32 self._results = self._browser.platform.StopMonitoringPower() 43 self._results = self._browser.platform.StopMonitoringPower()
33 if self._results: # StopMonitoringPower() can return None. 44 if self._results: # StopMonitoringPower() can return None.
34 self._results['cpu_stats'] = ( 45 self._results['cpu_stats'] = (
35 _SubtractCpuStats(self._browser.cpu_stats, self._starting_cpu_stats)) 46 _SubtractCpuStats(self._browser.cpu_stats, self._starting_cpu_stats))
36 47
48 def _MeasureQuiescentPower(self, measurement_time_s):
49 """Measure quiescent power draw for the system."""
50 # TODO(jeremy): This only makes sense for systems where we can only measure
51 # power globally. Don't do this where power measurement is per-process.
52 if not self._browser.platform.CanMonitorPower() or not measurement_time_s:
53 return
54
55 self._browser.platform.StartMonitoringPower(self._browser)
56 time.sleep(measurement_time_s)
57 power_results = self._browser.platform.StopMonitoringPower()
58 self._quiescent_power_draw_mwh = (
59 power_results.get('energy_consumption_mwh', 0))
60
37 def Start(self, _, tab): 61 def Start(self, _, tab):
38 if not tab.browser.platform.CanMonitorPower(): 62 if not tab.browser.platform.CanMonitorPower():
39 return 63 return
40 64
41 self._results = None 65 self._results = None
42 self._browser = tab.browser
43 self._StopInternal() 66 self._StopInternal()
44 67
45 # This line invokes top a few times, call before starting power measurement. 68 # This line invokes top a few times, call before starting power measurement.
46 self._starting_cpu_stats = self._browser.cpu_stats 69 self._starting_cpu_stats = self._browser.cpu_stats
47 self._browser.platform.StartMonitoringPower(self._browser) 70 self._browser.platform.StartMonitoringPower(self._browser)
48 self._running = True 71 self._running = True
49 72
50 def Stop(self, _, tab): 73 def Stop(self, _, tab):
51 if not tab.browser.platform.CanMonitorPower(): 74 if not tab.browser.platform.CanMonitorPower():
52 return 75 return
53 76
54 self._StopInternal() 77 self._StopInternal()
55 78
56 def AddResults(self, _, results): 79 def AddResults(self, _, results):
57 """Add the collected power data into the results object. 80 """Add the collected power data into the results object.
58 81
59 This function needs to be robust in the face of differing power data on 82 This function needs to be robust in the face of differing power data on
60 various platforms. Therefore data existence needs to be checked when 83 various platforms. Therefore data existence needs to be checked when
61 building up the results. Additionally 0 is a valid value for many of the 84 building up the results. Additionally 0 is a valid value for many of the
62 metrics here which is why there are plenty of checks for 'is not None' 85 metrics here which is why there are plenty of checks for 'is not None'
63 below. 86 below.
64 """ 87 """
65 if not self._results: 88 if not self._results:
66 return 89 return
67 90
68 energy_consumption_mwh = self._results.get('energy_consumption_mwh') 91 raw_energy_consumption_mwh = self._results.get('energy_consumption_mwh')
69 if energy_consumption_mwh is not None: 92 if raw_energy_consumption_mwh is not None:
93 energy_consumption_mwh = max(
94 raw_energy_consumption_mwh - self._quiescent_power_draw_mwh, 0)
95
70 results.AddValue(scalar.ScalarValue( 96 results.AddValue(scalar.ScalarValue(
71 results.current_page, 'energy_consumption_mwh', 'mWh', 97 results.current_page, 'energy_consumption_mwh', 'mWh',
72 energy_consumption_mwh)) 98 energy_consumption_mwh))
73 99
100 results.AddValue(scalar.ScalarValue(
tonyg 2014/06/26 16:19:04 WDYT about just reporting two things: energy_cons
101 results.current_page, 'raw_energy_consumption_mwh', 'mWh',
102 raw_energy_consumption_mwh))
103
104 results.AddValue(scalar.ScalarValue(
105 results.current_page, 'quiescent_energy_consumption_mwh', 'mWh',
106 self._quiescent_power_draw_mwh))
107
74 component_utilization = self._results.get('component_utilization', {}) 108 component_utilization = self._results.get('component_utilization', {})
75 # GPU Frequency. 109 # GPU Frequency.
76 gpu_power = component_utilization.get('gpu', {}) 110 gpu_power = component_utilization.get('gpu', {})
77 gpu_freq_hz = gpu_power.get('average_frequency_hz') 111 gpu_freq_hz = gpu_power.get('average_frequency_hz')
78 if gpu_freq_hz is not None: 112 if gpu_freq_hz is not None:
79 results.AddValue(scalar.ScalarValue( 113 results.AddValue(scalar.ScalarValue(
80 results.current_page, 'gpu_average_frequency_hz', 'hz', gpu_freq_hz, 114 results.current_page, 'gpu_average_frequency_hz', 'hz', gpu_freq_hz,
81 important=False)) 115 important=False))
82 116
83 # Add idle wakeup numbers for all processes. 117 # Add idle wakeup numbers for all processes.
(...skipping 30 matching lines...) Expand all
114 if (not cpu_stats[process_type]) or (not start_cpu_stats[process_type]): 148 if (not cpu_stats[process_type]) or (not start_cpu_stats[process_type]):
115 continue 149 continue
116 # Skip if IdleWakeupCount is not present. 150 # Skip if IdleWakeupCount is not present.
117 if (('IdleWakeupCount' not in cpu_stats[process_type]) or 151 if (('IdleWakeupCount' not in cpu_stats[process_type]) or
118 ('IdleWakeupCount' not in start_cpu_stats[process_type])): 152 ('IdleWakeupCount' not in start_cpu_stats[process_type])):
119 continue 153 continue
120 idle_wakeup_delta = (cpu_stats[process_type]['IdleWakeupCount'] - 154 idle_wakeup_delta = (cpu_stats[process_type]['IdleWakeupCount'] -
121 start_cpu_stats[process_type]['IdleWakeupCount']) 155 start_cpu_stats[process_type]['IdleWakeupCount'])
122 cpu_delta[process_type] = idle_wakeup_delta 156 cpu_delta[process_type] = idle_wakeup_delta
123 return cpu_delta 157 return cpu_delta
OLDNEW
« no previous file with comments | « tools/perf/measurements/webrtc.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698