parser for .cpu file added

This commit is contained in:
HappyZ 2017-02-02 17:33:02 -08:00
parent 0802fa24cd
commit 42cb13f14d
2 changed files with 146 additions and 37 deletions

94
energy_model/analyze.py Normal file
View File

@ -0,0 +1,94 @@
import sys
import os
sys.path.append("modules")
try:
from model import *
except:
raise
def read_cpu_log(filepath, startT=None, endT=None, isDelta=True):
contents = []
results = []
deltas = []
skipFirstTime = True
with open(filepath, 'rU') as f:
contents = f.readlines()
for line in contents:
tmp = line.rstrip().split(' ')
if len(tmp) < 3:
print "something is wrong at splitting the line for cpu_log"
sys.exit(-1)
timestamp = int(tmp[0]) # ms
if (startT is not None and timestamp < startT) \
or (endT is not None and timestamp > endT):
continue
cpu_total_idle = int(tmp[1])
cpu_total_used = int(tmp[2])
cpu_per_core = []
if isDelta and not skipFirstTime:
delta_t = timestamp - results[-1][0]
delta_total_idle = cpu_total_idle - results[-1][1]
delta_total_used = cpu_total_used - results[-1][2]
delta_per_core = []
for i in xrange(3, len(tmp), 3):
cpu_i_idle = int(tmp[i])
cpu_i_used = int(tmp[i + 1])
cpu_i_freq = int(tmp[i + 2])
cpu_per_core.append([cpu_i_idle, cpu_i_used, cpu_i_freq])
if isDelta and len(results) != 0:
delta_per_core.append(
[cpu_i_idle - results[-1][3][i / 3 - 1][0],
cpu_i_used - results[-1][3][i / 3 - 1][1],
cpu_i_freq])
if isDelta and not skipFirstTime:
deltas.append(
[delta_t, delta_total_idle, delta_total_used, delta_per_core])
results.append(
[timestamp, cpu_total_idle, cpu_total_used, cpu_per_core])
skipFirstTime = False
if isDelta:
return deltas, results
return results
def get_cpu_energy(results, model):
energy = 0
if len(results) < 1:
return energy
num_of_cores = len(results[0][3])
for result in results:
freqs = [0 for i in xrange(num_of_cores)]
utils = [0 for i in xrange(num_of_cores + 1)]
for i in xrange(num_of_cores):
if result[3][i][0] + result[3][i][1] > 0:
utils[i] = 1.0 * \
result[3][i][1] / (result[3][i][0] + result[3][i][1])
else:
utils[i] = 0
freqs[i] = result[3][i][-1]
# calculate total
if result[1] + result[2] > 0:
utils[-1] = 1.0 * result[1] / (result[1] + result[2])
else:
utils[-1] = 0
energy += model.get_cpu_energy(result[0] / 1000.0, freqs, utils[:-1])
if __name__ == "__main__":
# cpuFile = sys.argv[1]
cpuFile = "1485560673559.cpu"
if not os.path.isfile(cpuFile):
print ".....!"
sys.exit(-1)
deltas, results = read_cpu_log(cpuFile, isDelta=True)
myObj = Model(isDebuging=True, unit="mW")
# myObj.load(sys.argv[1])
myObj.load("shamu")
get_cpu_energy(deltas, myObj)
# for i in xrange(1, len(myObj.freqs)):
# print myObj.freqs[i] - myObj.freqs[i-1]
# myObj.get_wifi_tail_energy(1)
# myObj.get_wifi_active_energy(1, -60, isTX=False)
# myObj.get_cpu_energy(1, [1036800, 422400], [0, 1])

View File

@ -15,7 +15,7 @@ class Model():
The energy model module The energy model module
''' '''
def __init__(self, isDebuging=False, use_uAh=False): def __init__(self, isDebuging=False, unit="mW"):
self.freqs = [] self.freqs = []
self.cpu_single_core = {} self.cpu_single_core = {}
self.cpu_multi_core = {} self.cpu_multi_core = {}
@ -38,14 +38,12 @@ class Model():
''' '''
self.DEBUG = isDebuging self.DEBUG = isDebuging
self.logger = None self.logger = None
self.voltage = 1
self.unit = unit
if isDebuging: if isDebuging:
self.logger = EmptyLogger("Model", printout=True) self.logger = EmptyLogger("Model", printout=True)
if use_uAh:
self._ratio_uAh_over_mAs = 5 / 18.0
else:
self._ratio_uAh_over_mAs = 1.0
def load(self, productname, dir="../models/"): def load(self, productname, dir="./models/"):
self.voltage = getVoltage(productname) self.voltage = getVoltage(productname)
filepath = "{0}/{1}.xml".format(dir, productname) filepath = "{0}/{1}.xml".format(dir, productname)
if not os.path.isfile(filepath): if not os.path.isfile(filepath):
@ -142,10 +140,30 @@ class Model():
# if self.DEBUG: # if self.DEBUG:
# self.logger.debug(self.freqs) # self.logger.debug(self.freqs)
def get_final_energy(self, current, time):
'''
@param current: mA
@param time: s
@return defined energy with unit conversion
'''
if 'W' in self.unit:
tmp = current * self.voltage
elif 'J' in self.unit:
tmp = current * self.voltage * time
elif 'A' in self.unit:
tmp = current
if 'm' == self.unit[0]:
if 'h' == self.unit[-1]:
return tmp * time / 3600.0
return tmp
else:
return tmp / 1000.0
def get_cpu_energy(self, time_diff, freq, util): def get_cpu_energy(self, time_diff, freq, util):
''' '''
@param freq: list of cpu frequencies @param freq: list of cpu frequencies
@param util: list of cpu utilization @param util: list of cpu utilization
@return: energy in desired unit, default is mW
''' '''
if len(freq) != len(util) or len(freq) < 1: if len(freq) != len(util) or len(freq) < 1:
self.logger.error("freq & util have different length!") self.logger.error("freq & util have different length!")
@ -153,29 +171,31 @@ class Model():
current = 0 current = 0
if len(freq) > 1: if len(freq) > 1:
db = self.cpu_multi_core db = self.cpu_multi_core
for i in xrange(len(freq)):
if freq[i] <= 0 or freq[i] not in db[i]:
self.logger.error("freq outlier: {0}".format(freq[i]))
self.logger.debug(db[i])
continue
active_current = db[i][freq[i]][0]
idle_current = db[i][freq[i]][1]
current += util[i] * (active_current - idle_current) + \
idle_current
else: else:
db = self.cpu_single_core db = self.cpu_single_core
if freq[0] <= 0 or freq[0] not in db[0]: for i in xrange(len(freq)):
self.logger.error("freq outlier: {0}".format(f)) if freq[i] <= 0:
self.logger.debug(db[i]) continue
else: if freq[i] not in db[i]:
active_current = db[0][freq[0]][0] minDiff = float("inf")
idle_current = db[0][freq[0]][1] myJ = None
current = util[0] * (active_current - idle_current) + \ for j in xrange(len(self.freqs)):
idle_current tmp = abs(self.freqs[j] - freq[i])
if tmp < minDiff:
minDiff = tmp
myJ = j
closestFreq = self.freqs[j]
self.logger.debug("Freq outlier: {0}. ".format(freq[i]) +
"Use {0} instead.".format(closestFreq))
freq[i] = closestFreq
active_current = db[i][freq[i]][0]
idle_current = db[i][freq[i]][1]
current += util[i] * active_current + (1 - util[i]) * idle_current
# derive energy # derive energy
energy = current * time_diff * self._ratio_uAh_over_mAs energy = self.get_final_energy(current, time_diff)
if self.DEBUG: if self.DEBUG:
self.logger.debug("cpu_energy: {0:.4f}".format(energy)) self.logger.debug(
"cpu_energy: {0:.4f}{1}".format(energy, self.unit))
return energy return energy
def get_lte_prom_energy(self, time_diff, rssi, isTX=True): def get_lte_prom_energy(self, time_diff, rssi, isTX=True):
@ -215,24 +235,19 @@ class Model():
self.logger.error("Current {0} is nothing!".format(current)) self.logger.error("Current {0} is nothing!".format(current))
sys.exit(-1) sys.exit(-1)
# derive energy # derive energy
energy = current * time_diff * self._ratio_uAh_over_mAs energy = self.get_final_energy(current, time_diff)
if self.DEBUG: if self.DEBUG:
self.logger.debug("wifi_active_energy: {0:.4f}".format(energy)) self.logger.debug(
"wifi_active_energy: {0:.4f}{1}".format(energy, self.unit))
return energy return energy
def get_wifi_tail_energy(self, time_diff): def get_wifi_tail_energy(self, time_diff):
energy = (time_diff * self.net_wifi['tail']['0'][1] * current = self.net_wifi['tail']['0'][1]
self._ratio_uAh_over_mAs) energy = self.get_final_energy(current, time_diff)
if self.DEBUG: if self.DEBUG:
self.logger.debug("wifi_tail_energy: {0:.4f}".format(energy)) self.logger.debug(
"wifi_active_energy: {0:.4f}{1}".format(energy, self.unit))
return energy return energy
if __name__ == "__main__": if __name__ == "__main__":
print "Usage: from model import *" print "Usage: from model import *"
# debugging..
myObj = Model(isDebuging=True)
# myObj.load(sys.argv[1])
myObj.load("shamu")
myObj.get_wifi_tail_energy(1)
myObj.get_wifi_active_energy(1, -60, isTX=False)
myObj.get_cpu_energy(1, [1036800, 422400], [0, 1])