bug fix, change unit to only watt or joule, modulate analyzer
This commit is contained in:
parent
42cb13f14d
commit
7779251e5a
|
|
@ -8,72 +8,110 @@ except:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
def read_cpu_log(filepath, startT=None, endT=None, isDelta=True):
|
class EnergyAnalyzer():
|
||||||
contents = []
|
'''
|
||||||
results = []
|
Energy analyzer
|
||||||
deltas = []
|
'''
|
||||||
skipFirstTime = True
|
def __init__(self, productname, isDebugging=False, unit="mW"):
|
||||||
with open(filepath, 'rU') as f:
|
self.myModel = Model(isDebugging=isDebugging, unit=unit)
|
||||||
contents = f.readlines()
|
self.myModel.load(productname)
|
||||||
for line in contents:
|
self.results = []
|
||||||
tmp = line.rstrip().split(' ')
|
self.deltas = []
|
||||||
if len(tmp) < 3:
|
self.instant_power = []
|
||||||
print "something is wrong at splitting the line for cpu_log"
|
self.total_energy = 0 # unit as defined in unit
|
||||||
sys.exit(-1)
|
self.avg_power = 0
|
||||||
timestamp = int(tmp[0]) # ms
|
self.total_time = 0
|
||||||
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
|
|
||||||
|
|
||||||
|
self.DEBUG = isDebugging
|
||||||
|
if self.DEBUG:
|
||||||
|
self.logger = EmptyLogger(
|
||||||
|
"EnergyAnalyzer", isDebugging=self.DEBUG, printout=True)
|
||||||
|
|
||||||
def get_cpu_energy(results, model):
|
def read_cpu_log(self, filepath,
|
||||||
energy = 0
|
startT=None, endT=None):
|
||||||
if len(results) < 1:
|
self.logger.debug("read_cpu_log started")
|
||||||
return energy
|
contents = []
|
||||||
num_of_cores = len(results[0][3])
|
skipFirstTime = True
|
||||||
for result in results:
|
with open(filepath, 'rU') as f:
|
||||||
freqs = [0 for i in xrange(num_of_cores)]
|
contents = f.readlines()
|
||||||
utils = [0 for i in xrange(num_of_cores + 1)]
|
for line in contents:
|
||||||
for i in xrange(num_of_cores):
|
tmp = line.rstrip().split(' ')
|
||||||
if result[3][i][0] + result[3][i][1] > 0:
|
if len(tmp) < 3:
|
||||||
utils[i] = 1.0 * \
|
print "something is wrong at splitting the line for cpu_log"
|
||||||
result[3][i][1] / (result[3][i][0] + result[3][i][1])
|
sys.exit(-1)
|
||||||
|
timestamp = int(tmp[0]) / 1000.0 # ms -> s
|
||||||
|
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 not skipFirstTime:
|
||||||
|
delta_t = timestamp - self.results[-1][0]
|
||||||
|
delta_total_idle = cpu_total_idle - self.results[-1][1]
|
||||||
|
delta_total_used = cpu_total_used - self.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 len(self.results) != 0:
|
||||||
|
delta_per_core.append(
|
||||||
|
[cpu_i_idle - self.results[-1][3][i / 3 - 1][0],
|
||||||
|
cpu_i_used - self.results[-1][3][i / 3 - 1][1],
|
||||||
|
cpu_i_freq])
|
||||||
|
if not skipFirstTime:
|
||||||
|
self.deltas.append(
|
||||||
|
[delta_t, delta_total_idle,
|
||||||
|
delta_total_used, delta_per_core])
|
||||||
|
self.results.append(
|
||||||
|
[timestamp, cpu_total_idle, cpu_total_used, cpu_per_core])
|
||||||
|
skipFirstTime = False
|
||||||
|
self.logger.debug("read_cpu_log ended")
|
||||||
|
|
||||||
|
def get_cpu_energy(self):
|
||||||
|
if len(self.deltas) < 1:
|
||||||
|
self.logger.error("get_cpu_energy finds delta empty")
|
||||||
|
self.logger.error(self.results)
|
||||||
|
return
|
||||||
|
|
||||||
|
self.logger.debug("get_cpu_energy started")
|
||||||
|
num_of_cores = len(self.deltas[0][3])
|
||||||
|
for result in self.deltas:
|
||||||
|
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:
|
else:
|
||||||
utils[i] = 0
|
utils[-1] = 0
|
||||||
freqs[i] = result[3][i][-1]
|
# get power (only if the unit is in Watts or mWatts)
|
||||||
# calculate total
|
instant_power = self.myModel.get_cpu_energy(
|
||||||
if result[1] + result[2] > 0:
|
result[0], freqs, utils[:-1])
|
||||||
utils[-1] = 1.0 * result[1] / (result[1] + result[2])
|
if self.myModel.using_power:
|
||||||
else:
|
self.instant_power.append(instant_power)
|
||||||
utils[-1] = 0
|
energy = instant_power * result[0]
|
||||||
energy += model.get_cpu_energy(result[0] / 1000.0, freqs, utils[:-1])
|
else:
|
||||||
|
energy = instant_power
|
||||||
|
self.total_time += result[0]
|
||||||
|
self.total_energy += energy
|
||||||
|
self.avg_power = self.total_energy / self.total_time
|
||||||
|
|
||||||
|
self.logger.info(
|
||||||
|
"total energy: {0:.4f}mJ".format(self.total_energy))
|
||||||
|
self.logger.info(
|
||||||
|
"total time: {0:.4f}s".format(self.total_time))
|
||||||
|
self.logger.info(
|
||||||
|
"average power: {0:.4f}mW".format(self.avg_power))
|
||||||
|
self.logger.debug("get_cpu_energy ended")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
@ -82,11 +120,9 @@ if __name__ == "__main__":
|
||||||
if not os.path.isfile(cpuFile):
|
if not os.path.isfile(cpuFile):
|
||||||
print ".....!"
|
print ".....!"
|
||||||
sys.exit(-1)
|
sys.exit(-1)
|
||||||
deltas, results = read_cpu_log(cpuFile, isDelta=True)
|
myObj = EnergyAnalyzer("shamu", isDebugging=True, unit="mW")
|
||||||
myObj = Model(isDebuging=True, unit="mW")
|
myObj.read_cpu_log(cpuFile)
|
||||||
# myObj.load(sys.argv[1])
|
myObj.get_cpu_energy()
|
||||||
myObj.load("shamu")
|
|
||||||
get_cpu_energy(deltas, myObj)
|
|
||||||
# for i in xrange(1, len(myObj.freqs)):
|
# for i in xrange(1, len(myObj.freqs)):
|
||||||
# print myObj.freqs[i] - myObj.freqs[i-1]
|
# print myObj.freqs[i] - myObj.freqs[i-1]
|
||||||
# myObj.get_wifi_tail_energy(1)
|
# myObj.get_wifi_tail_energy(1)
|
||||||
|
|
|
||||||
|
|
@ -33,9 +33,13 @@ class EmptyLogger:
|
||||||
logger base
|
logger base
|
||||||
'''
|
'''
|
||||||
def __init__(
|
def __init__(
|
||||||
self, loggerTag, level=logging.DEBUG, logPath=None, printout=False
|
self, loggerTag, isDebugging=False, logPath=None, printout=True
|
||||||
):
|
):
|
||||||
self.myLogger = logging.getLogger(loggerTag)
|
self.myLogger = logging.getLogger(loggerTag)
|
||||||
|
if isDebugging:
|
||||||
|
level = logging.DEBUG
|
||||||
|
else:
|
||||||
|
level = logging.INFO
|
||||||
self.myLogger.setLevel(level)
|
self.myLogger.setLevel(level)
|
||||||
self.ch_file = None
|
self.ch_file = None
|
||||||
self.ch_stream = None
|
self.ch_stream = None
|
||||||
|
|
@ -43,13 +47,12 @@ class EmptyLogger:
|
||||||
'%(asctime)s %(name)s %(levelname)s, %(message)s')
|
'%(asctime)s %(name)s %(levelname)s, %(message)s')
|
||||||
if logPath is not None:
|
if logPath is not None:
|
||||||
self.ch_file = logging.FileHandler(logPath, 'w')
|
self.ch_file = logging.FileHandler(logPath, 'w')
|
||||||
self.ch_file.setLevel(level)
|
self.ch_file.setLevel(logging.DEBUG)
|
||||||
self.ch_file.setFormatter(formatter)
|
self.ch_file.setFormatter(formatter)
|
||||||
self.myLogger.addHandler(self.ch_file)
|
self.myLogger.addHandler(self.ch_file)
|
||||||
if printout:
|
if printout:
|
||||||
self.ch_stream = logging.StreamHandler()
|
self.ch_stream = logging.StreamHandler()
|
||||||
self.ch_stream.setLevel(level)
|
self.ch_stream.setLevel(level)
|
||||||
# ch_stream.setLevel(level)
|
|
||||||
self.ch_stream.setFormatter(formatter)
|
self.ch_stream.setFormatter(formatter)
|
||||||
self.myLogger.addHandler(self.ch_stream)
|
self.myLogger.addHandler(self.ch_stream)
|
||||||
self.myLogger.info('logging started')
|
self.myLogger.info('logging started')
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ class Model():
|
||||||
The energy model module
|
The energy model module
|
||||||
'''
|
'''
|
||||||
|
|
||||||
def __init__(self, isDebuging=False, unit="mW"):
|
def __init__(self, isDebugging=False, unit="mW"):
|
||||||
self.freqs = []
|
self.freqs = []
|
||||||
self.cpu_single_core = {}
|
self.cpu_single_core = {}
|
||||||
self.cpu_multi_core = {}
|
self.cpu_multi_core = {}
|
||||||
|
|
@ -36,12 +36,26 @@ class Model():
|
||||||
{ 'index': [rssi, current, length], ...},
|
{ 'index': [rssi, current, length], ...},
|
||||||
}
|
}
|
||||||
'''
|
'''
|
||||||
self.DEBUG = isDebuging
|
|
||||||
self.logger = None
|
|
||||||
self.voltage = 1
|
self.voltage = 1
|
||||||
self.unit = unit
|
self.unit = unit
|
||||||
if isDebuging:
|
|
||||||
self.logger = EmptyLogger("Model", printout=True)
|
self.DEBUG = isDebugging
|
||||||
|
if self.DEBUG:
|
||||||
|
self.logger = EmptyLogger(
|
||||||
|
"Model", isDebugging=self.DEBUG, printout=True)
|
||||||
|
|
||||||
|
if 'A' in self.unit:
|
||||||
|
tmp = self.unit.replace('A', 'W')
|
||||||
|
self.logger.info(
|
||||||
|
"Will use power instead: {0} -> {1}".format(tmp, unit))
|
||||||
|
self.unit = tmp
|
||||||
|
if 'W' in self.unit:
|
||||||
|
self.using_power = True
|
||||||
|
else:
|
||||||
|
self.using_power = False
|
||||||
|
self.logger.info(
|
||||||
|
"{0} will cause some loss of info like instant power".format(
|
||||||
|
self.unit))
|
||||||
|
|
||||||
def load(self, productname, dir="./models/"):
|
def load(self, productname, dir="./models/"):
|
||||||
self.voltage = getVoltage(productname)
|
self.voltage = getVoltage(productname)
|
||||||
|
|
@ -150,11 +164,11 @@ class Model():
|
||||||
tmp = current * self.voltage
|
tmp = current * self.voltage
|
||||||
elif 'J' in self.unit:
|
elif 'J' in self.unit:
|
||||||
tmp = current * self.voltage * time
|
tmp = current * self.voltage * time
|
||||||
elif 'A' in self.unit:
|
else:
|
||||||
tmp = current
|
self.logger.error(
|
||||||
|
"Unit {0} not supported!".format(self.unit))
|
||||||
|
sys.exit(-1)
|
||||||
if 'm' == self.unit[0]:
|
if 'm' == self.unit[0]:
|
||||||
if 'h' == self.unit[-1]:
|
|
||||||
return tmp * time / 3600.0
|
|
||||||
return tmp
|
return tmp
|
||||||
else:
|
else:
|
||||||
return tmp / 1000.0
|
return tmp / 1000.0
|
||||||
|
|
@ -195,7 +209,8 @@ class Model():
|
||||||
energy = self.get_final_energy(current, time_diff)
|
energy = self.get_final_energy(current, time_diff)
|
||||||
if self.DEBUG:
|
if self.DEBUG:
|
||||||
self.logger.debug(
|
self.logger.debug(
|
||||||
"cpu_energy: {0:.4f}{1}".format(energy, self.unit))
|
"duration: {0:.4f}s, cpu_energy: {1:.4f}{2}".format(
|
||||||
|
time_diff, 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):
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue