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
3 # found in the LICENSE file.
9 from telemetry
import decorators
10 from telemetry
.internal
.platform
import power_monitor
13 MSR_RAPL_POWER_UNIT
= 0x606
14 MSR_PKG_ENERGY_STATUS
= 0x611 # Whole package
15 MSR_PP0_ENERGY_STATUS
= 0x639 # Core
16 MSR_PP1_ENERGY_STATUS
= 0x641 # Uncore
17 MSR_DRAM_ENERGY_STATUS
= 0x619
18 IA32_PACKAGE_THERM_STATUS
= 0x1b1
19 IA32_TEMPERATURE_TARGET
= 0x1a2
22 def _JoulesToMilliwattHours(value_joules
):
23 return value_joules
* 1000 / 3600.
26 def _IsSandyBridgeOrLater(vendor
, family
, model
):
28 # https://software.intel.com/en-us/articles/intel-architecture-and-processor-identification-with-cpuid-model-and-family-numbers
29 # http://www.speedtraq.com
30 return ('Intel' in vendor
and family
== 6 and
31 (model
in (0x2A, 0x2D) or model
>= 0x30))
34 class MsrPowerMonitor(power_monitor
.PowerMonitor
):
35 def __init__(self
, backend
):
36 super(MsrPowerMonitor
, self
).__init
__()
37 self
._backend
= backend
38 self
._start
_energy
_j
= None
39 self
._start
_temp
_c
= None
41 def CanMonitorPower(self
):
42 raise NotImplementedError()
44 def StartMonitoringPower(self
, browser
):
46 self
._start
_energy
_j
= self
._PackageEnergyJoules
()
47 self
._start
_temp
_c
= self
._TemperatureCelsius
()
49 def StopMonitoringPower(self
):
51 energy_consumption_j
= self
._PackageEnergyJoules
() - self
._start
_energy
_j
52 average_temp_c
= (self
._TemperatureCelsius
() + self
._start
_temp
_c
) / 2.
53 if energy_consumption_j
< 0: # Correct overflow.
54 # The energy portion of the MSR is 4 bytes.
55 energy_consumption_j
+= 2 ** 32 * self
._EnergyMultiplier
()
57 self
._start
_energy
_j
= None
58 self
._start
_temp
_c
= None
62 'energy_consumption_mwh': _JoulesToMilliwattHours(energy_consumption_j
),
64 'average_temperature_c': average_temp_c
,
69 def _EnergyMultiplier(self
):
70 return 0.5 ** self
._backend
.ReadMsr(MSR_RAPL_POWER_UNIT
, 8, 5)
72 def _PackageEnergyJoules(self
):
73 return (self
._backend
.ReadMsr(MSR_PKG_ENERGY_STATUS
, 0, 32) *
74 self
._EnergyMultiplier
())
76 def _TemperatureCelsius(self
):
77 tcc_activation_temp
= self
._backend
.ReadMsr(IA32_TEMPERATURE_TARGET
, 16, 7)
78 if tcc_activation_temp
<= 0:
79 tcc_activation_temp
= 105
80 package_temp_headroom
= self
._backend
.ReadMsr(
81 IA32_PACKAGE_THERM_STATUS
, 16, 7)
82 return tcc_activation_temp
- package_temp_headroom
86 if self
._PackageEnergyJoules
() <= 0:
87 logging
.info('Cannot monitor power: no energy readings.')
90 if self
._TemperatureCelsius
() <= 0:
91 logging
.info('Cannot monitor power: no temperature readings.')
94 logging
.info('Cannot monitor power: %s' % e
)
99 class MsrPowerMonitorLinux(MsrPowerMonitor
):
100 def CanMonitorPower(self
):
104 cpuinfo
= open('/proc/cpuinfo').read().splitlines()
106 if vendor
and family
and model
:
108 if line
.startswith('vendor_id'):
109 vendor
= line
.split('\t')[1]
110 elif line
.startswith('cpu family'):
111 family
= int(line
.split(' ')[2])
112 elif line
.startswith('model\t\t'):
113 model
= int(line
.split(' ')[1])
114 if not _IsSandyBridgeOrLater(vendor
, family
, model
):
115 logging
.info('Cannot monitor power: pre-Sandy Bridge CPU.')
118 if not self
._CheckMSRs
():
119 logging
.info('Try running tools/telemetry/build/linux_setup_msr.py.')
125 class MsrPowerMonitorWin(MsrPowerMonitor
):
126 def CanMonitorPower(self
):
127 family
, model
= map(int, re
.match('.+ Family ([0-9]+) Model ([0-9]+)',
128 platform
.processor()).groups())
129 if not _IsSandyBridgeOrLater(platform
.processor(), family
, model
):
130 logging
.info('Cannot monitor power: pre-Sandy Bridge CPU.')
134 return self
._CheckMSRs
()
136 # Since _CheckMSRs() starts the MSR server on win platform, we must close
137 # it after checking to avoid leaking msr server process.
138 self
._backend
.CloseMsrServer()
140 def StopMonitoringPower(self
):
141 power_statistics
= super(MsrPowerMonitorWin
, self
).StopMonitoringPower()
142 self
._backend
.CloseMsrServer()
143 return power_statistics