Commit 255d4a9c authored by jeremy@chromium.org's avatar jeremy@chromium.org

[Telemetry] Have powermetrics summarize power usage rather than doing it by ourselves

Tell `powermetrics` to print a summary instead of telling it to sample and summing ourselves.

Aim is to try to get more accurate measurements.

BUG=None

Review URL: https://codereview.chromium.org/330543008

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@276881 0039d316-1c4b-4281-b951-d872f2087c98
parent b0fb03b2
...@@ -7,7 +7,6 @@ import logging ...@@ -7,7 +7,6 @@ import logging
import os import os
import plistlib import plistlib
import shutil import shutil
import signal
import tempfile import tempfile
import xml.parsers.expat import xml.parsers.expat
...@@ -42,7 +41,9 @@ class PowerMetricsPowerMonitor(power_monitor.PowerMonitor): ...@@ -42,7 +41,9 @@ class PowerMetricsPowerMonitor(power_monitor.PowerMonitor):
self._output_filename = os.path.join(self._output_directory, self._output_filename = os.path.join(self._output_directory,
'powermetrics.output') 'powermetrics.output')
args = ['-f', 'plist', args = ['-f', 'plist',
'-u', self._output_filename] '-u', self._output_filename,
'-i0',
'--show-usage-summary']
self._powermetrics_process = self._backend.LaunchApplication( self._powermetrics_process = self._backend.LaunchApplication(
self.binary_path, args, elevate_privilege=True) self.binary_path, args, elevate_privilege=True)
...@@ -130,6 +131,7 @@ class PowerMetricsPowerMonitor(power_monitor.PowerMonitor): ...@@ -130,6 +131,7 @@ class PowerMetricsPowerMonitor(power_monitor.PowerMonitor):
# powermetrics outputs multiple plists separated by null terminators. # powermetrics outputs multiple plists separated by null terminators.
raw_plists = powermetrics_output.split('\0') raw_plists = powermetrics_output.split('\0')
raw_plists = [x for x in raw_plists if len(x) > 0] raw_plists = [x for x in raw_plists if len(x) > 0]
assert(len(raw_plists) == 1)
# -------- Examine contents of first plist for systems specs. -------- # -------- Examine contents of first plist for systems specs. --------
plist = PowerMetricsPowerMonitor._ParsePlistString(raw_plists[0]) plist = PowerMetricsPowerMonitor._ParsePlistString(raw_plists[0])
...@@ -171,28 +173,29 @@ class PowerMetricsPowerMonitor(power_monitor.PowerMonitor): ...@@ -171,28 +173,29 @@ class PowerMetricsPowerMonitor(power_monitor.PowerMonitor):
cpu_num += 1 cpu_num += 1
# -------- Parse Data Out of Plists -------- # -------- Parse Data Out of Plists --------
for raw_plist in raw_plists: plist = PowerMetricsPowerMonitor._ParsePlistString(raw_plists[0])
plist = PowerMetricsPowerMonitor._ParsePlistString(raw_plist) if not plist:
if not plist: logging.error("Error parsing plist.")
continue return
# Duration of this sample. # Duration of this sample.
sample_duration_ms = int(plist['elapsed_ns']) / 10**6 sample_duration_ms = int(plist['elapsed_ns']) / 10**6
sample_durations.append(sample_duration_ms) sample_durations.append(sample_duration_ms)
if 'processor' not in plist: if 'processor' not in plist:
continue logging.error("'processor' field not found in plist.")
processor = plist['processor'] return
processor = plist['processor']
energy_consumption_mw = int(processor.get('package_watts', 0)) * 10**3 energy_consumption_mw = int(processor.get('package_watts', 0)) * 10**3
total_energy_consumption_mwh += (energy_consumption_mw * total_energy_consumption_mwh += (energy_consumption_mw *
(sample_duration_ms / 3600000.)) (sample_duration_ms / 3600000.))
power_samples.append(energy_consumption_mw) power_samples.append(energy_consumption_mw)
for m in metrics: for m in metrics:
m.samples.append(DataWithMetricKeyPath(m, plist)) m.samples.append(DataWithMetricKeyPath(m, plist))
# -------- Collect and Process Data -------- # -------- Collect and Process Data --------
out_dict = {} out_dict = {}
...@@ -238,8 +241,7 @@ class PowerMetricsPowerMonitor(power_monitor.PowerMonitor): ...@@ -238,8 +241,7 @@ class PowerMetricsPowerMonitor(power_monitor.PowerMonitor):
"StartMonitoringPower() not called.") "StartMonitoringPower() not called.")
# Tell powermetrics to take an immediate sample. # Tell powermetrics to take an immediate sample.
try: try:
self._powermetrics_process.send_signal(signal.SIGINFO) self._powermetrics_process.terminate()
self._powermetrics_process.send_signal(signal.SIGTERM)
(power_stdout, power_stderr) = self._powermetrics_process.communicate() (power_stdout, power_stderr) = self._powermetrics_process.communicate()
returncode = self._powermetrics_process.returncode returncode = self._powermetrics_process.returncode
assert returncode in [0, -15], ( assert returncode in [0, -15], (
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment