OLD | NEW |
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 | 5 import time |
6 | 6 |
7 from telemetry.util import process_statistic_timeline_data | 7 from telemetry.util import process_statistic_timeline_data |
8 from telemetry.value import scalar | 8 from telemetry.value import scalar |
9 | 9 |
10 from metrics import Metric | 10 from metrics import Metric |
11 | 11 |
12 | 12 |
13 MONSOON_POWER_LABEL = 'monsoon_energy_consumption_mwh' | |
14 FUELGAUGE_POWER_LABEL = 'fuel_gauge_energy_consumption_mwh' | |
15 APP_POWER_LABEL = 'application_energy_consumption_mwh' | |
16 TOTAL_POWER_LABEL = 'energy_consumption_mwh' | |
17 | |
18 class PowerMetric(Metric): | 13 class PowerMetric(Metric): |
19 """A metric for measuring power usage.""" | 14 """A metric for measuring power usage.""" |
20 | 15 |
21 # System power draw while idle. | 16 # System power draw while idle. |
22 _quiescent_power_draw_mwh = 0 | 17 _quiescent_power_draw_mwh = 0 |
23 | 18 |
24 def __init__(self, platform, quiescent_measurement_time_s=0): | 19 def __init__(self, platform, quiescent_measurement_time_s=0): |
25 """PowerMetric Constructor. | 20 """PowerMetric Constructor. |
26 | 21 |
27 Args: | 22 Args: |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
63 return | 58 return |
64 | 59 |
65 # Only perform quiescent measurement once per run. | 60 # Only perform quiescent measurement once per run. |
66 if PowerMetric._quiescent_power_draw_mwh: | 61 if PowerMetric._quiescent_power_draw_mwh: |
67 return | 62 return |
68 | 63 |
69 self._platform.StartMonitoringPower(self._browser) | 64 self._platform.StartMonitoringPower(self._browser) |
70 time.sleep(measurement_time_s) | 65 time.sleep(measurement_time_s) |
71 power_results = self._platform.StopMonitoringPower() | 66 power_results = self._platform.StopMonitoringPower() |
72 PowerMetric._quiescent_power_draw_mwh = ( | 67 PowerMetric._quiescent_power_draw_mwh = ( |
73 power_results.get(TOTAL_POWER_LABEL, 0)) | 68 power_results.get('energy_consumption_mwh', 0)) |
74 | 69 |
75 def Start(self, _, tab): | 70 def Start(self, _, tab): |
76 self._browser = tab.browser | 71 self._browser = tab.browser |
77 | 72 |
78 if not self._platform.CanMonitorPower(): | 73 if not self._platform.CanMonitorPower(): |
79 return | 74 return |
80 | 75 |
81 self._results = None | 76 self._results = None |
82 self._StopInternal() | 77 self._StopInternal() |
83 | 78 |
(...skipping 13 matching lines...) Expand all Loading... |
97 | 92 |
98 This function needs to be robust in the face of differing power data on | 93 This function needs to be robust in the face of differing power data on |
99 various platforms. Therefore data existence needs to be checked when | 94 various platforms. Therefore data existence needs to be checked when |
100 building up the results. Additionally 0 is a valid value for many of the | 95 building up the results. Additionally 0 is a valid value for many of the |
101 metrics here which is why there are plenty of checks for 'is not None' | 96 metrics here which is why there are plenty of checks for 'is not None' |
102 below. | 97 below. |
103 """ | 98 """ |
104 if not self._results: | 99 if not self._results: |
105 return | 100 return |
106 | 101 |
107 application_energy_consumption_mwh = self._results.get(APP_POWER_LABEL) | 102 application_energy_consumption_mwh = ( |
108 total_energy_consumption_mwh = self._results.get(TOTAL_POWER_LABEL) | 103 self._results.get('application_energy_consumption_mwh')) |
109 fuel_gauge_energy_consumption_mwh = self._results.get(FUELGAUGE_POWER_LABEL) | 104 total_energy_consumption_mwh = self._results.get('energy_consumption_mwh') |
110 monsoon_energy_consumption_mwh = self._results.get(MONSOON_POWER_LABEL) | 105 fuel_gauge_energy_consumption_mwh = ( |
| 106 self._results.get('fuel_gauge_energy_consumption_mwh')) |
111 | 107 |
112 if (PowerMetric._quiescent_power_draw_mwh and | 108 if (PowerMetric._quiescent_power_draw_mwh and |
113 application_energy_consumption_mwh is None and | 109 application_energy_consumption_mwh is None and |
114 total_energy_consumption_mwh is not None): | 110 total_energy_consumption_mwh is not None): |
115 application_energy_consumption_mwh = max( | 111 application_energy_consumption_mwh = max( |
116 total_energy_consumption_mwh - PowerMetric._quiescent_power_draw_mwh, | 112 total_energy_consumption_mwh - PowerMetric._quiescent_power_draw_mwh, |
117 0) | 113 0) |
118 | 114 |
119 if fuel_gauge_energy_consumption_mwh is not None: | 115 if fuel_gauge_energy_consumption_mwh is not None: |
120 results.AddValue(scalar.ScalarValue( | 116 results.AddValue(scalar.ScalarValue( |
121 results.current_page, FUELGAUGE_POWER_LABEL, 'mWh', | 117 results.current_page, 'fuel_gauge_energy_consumption_mwh', 'mWh', |
122 fuel_gauge_energy_consumption_mwh)) | 118 fuel_gauge_energy_consumption_mwh)) |
123 | 119 |
124 if monsoon_energy_consumption_mwh is not None: | |
125 results.AddValue(scalar.ScalarValue( | |
126 results.current_page, MONSOON_POWER_LABEL, 'mWh', | |
127 monsoon_energy_consumption_mwh)) | |
128 | |
129 if total_energy_consumption_mwh is not None: | 120 if total_energy_consumption_mwh is not None: |
130 results.AddValue(scalar.ScalarValue( | 121 results.AddValue(scalar.ScalarValue( |
131 results.current_page, TOTAL_POWER_LABEL, 'mWh', | 122 results.current_page, 'energy_consumption_mwh', 'mWh', |
132 total_energy_consumption_mwh)) | 123 total_energy_consumption_mwh)) |
133 | 124 |
134 if application_energy_consumption_mwh is not None: | 125 if application_energy_consumption_mwh is not None: |
135 results.AddValue(scalar.ScalarValue( | 126 results.AddValue(scalar.ScalarValue( |
136 results.current_page, APP_POWER_LABEL, 'mWh', | 127 results.current_page, 'application_energy_consumption_mwh', 'mWh', |
137 application_energy_consumption_mwh)) | 128 application_energy_consumption_mwh)) |
138 | 129 |
139 component_utilization = self._results.get('component_utilization', {}) | 130 component_utilization = self._results.get('component_utilization', {}) |
140 # GPU Frequency. | 131 # GPU Frequency. |
141 gpu_power = component_utilization.get('gpu', {}) | 132 gpu_power = component_utilization.get('gpu', {}) |
142 gpu_freq_hz = gpu_power.get('average_frequency_hz') | 133 gpu_freq_hz = gpu_power.get('average_frequency_hz') |
143 if gpu_freq_hz is not None: | 134 if gpu_freq_hz is not None: |
144 results.AddValue(scalar.ScalarValue( | 135 results.AddValue(scalar.ScalarValue( |
145 results.current_page, 'gpu_average_frequency_hz', 'hz', gpu_freq_hz, | 136 results.current_page, 'gpu_average_frequency_hz', 'hz', gpu_freq_hz, |
146 important=False)) | 137 important=False)) |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
203 continue | 194 continue |
204 | 195 |
205 assert isinstance(cpu_stats[process_type]['IdleWakeupCount'], | 196 assert isinstance(cpu_stats[process_type]['IdleWakeupCount'], |
206 process_statistic_timeline_data.IdleWakeupTimelineData) | 197 process_statistic_timeline_data.IdleWakeupTimelineData) |
207 idle_wakeup_delta = (cpu_stats[process_type]['IdleWakeupCount'] - | 198 idle_wakeup_delta = (cpu_stats[process_type]['IdleWakeupCount'] - |
208 start_cpu_stats[process_type]['IdleWakeupCount']) | 199 start_cpu_stats[process_type]['IdleWakeupCount']) |
209 cpu_delta[process_type] = idle_wakeup_delta.total_sum() | 200 cpu_delta[process_type] = idle_wakeup_delta.total_sum() |
210 total = total + cpu_delta[process_type] | 201 total = total + cpu_delta[process_type] |
211 cpu_delta['Total'] = total | 202 cpu_delta['Total'] = total |
212 return cpu_delta | 203 return cpu_delta |
OLD | NEW |