?? postprocess.py
字號:
#!/usr/bin/python# postprocess.py# Author: Victor Shnayder <shnayder at eecs.harvard.edu># Postprocessing script that reads PowerTOSSIM state transition log and# computes power and energy numbers.from sys import argvimport sysusage = """USAGE: postprocess.py [--help] [--debug] [--nosummary][--detail[=basename]] [--maxmotes N][--simple] [--sb={0|1}] --em file trace_file--help: print this help message--debug: turn on debugging output--nosummary: avoid printing the summary to stdout--detail[=basename]: for each mote, print a list of 'time\\tcurrent' pairs to the file basename$moteid.dat (default basename='mote')--em file: use the energy model in file--sb={0|1}: Whether the motes have a sensor board or not. (default: 0)--maxmotes: The maximum of number of motes to support. 1000 by default.--simple: Use a simple output format, suitable for machine parsingBy default, uses energy model from energy_model.txt in the current directory,prints summary."""summary = 1prettyprint = 1detail = 0lineno = 0 # The line number in the trace fileemfile = "energy_model.txt"tracefile = ""model = {} # The energy model (mappings such as CPU_ACTIVE->8.0)state = [{}] # The current state of execution ([mote][component])total = [{}] # The energy totals# Hmm... might not actually want 1000 open files. I guess I could# open and close each one after each write. Or just keep all the# logs in memory and then write them out one at a time. For now, just# open each file when necessary and leave it at thatdata_file = [] basename = 'mote'voltage = Noneprev_current = []prev_time = []maxmotes = 1000maxseen = 0debug = 0em = {} # The energy modelsb = 0 # Whether there's a sensor board#components = ["radio", "cpu", "cpu_cycles", "adc", "sensor", "led", "eeprom"]# Types of total we want to tracktotals = ["cpu", "radio", "adc", "leds", "sensor", "eeprom"]def quit(showusage=0, error="Illegal arguments"): if error: print >> sys.stderr, "Error: ", error, "\n" if showusage: print >> sys.stderr, usage sys.exit()# Handle arguments-this can be rewritten with a dictionary of lambdas, but# that's for later (or I can just use an existing module)def parse_args(): global summary, maxmotes, emfile, tracefile, trace, argv, debug, basename global detail, prettyprint, sb argv = argv[1:] while argv: a=argv[0] if a == "--help": quit(1,"") elif a == "--nosummary": summary = 0 elif a == "--simple": prettyprint = 0 elif a.startswith("--detail"): detail = 1 x=a.rfind('=') if x != -1: basename = a[x+1:] elif a.startswith("--sb="): t = a[5:] if t == "1": sb = 1 elif t == "0": sb = 0 else: quit(1) elif a == "--debug": debug = 1 elif a == "--maxmotes": argv = argv[1:] # Consume this argument if not argv: quit(1) maxmotes = int(argv[0]) elif a == "--em": argv=argv[1:] # Consume this argument if not argv: quit(1) emfile = argv[0] # Get the filename parameter else: tracefile = a argv = argv[1:] if tracefile == "": quit(1,"No tracefile specified") try: trace = open(tracefile) except IOError: quit(0,"Couldn't open trace file '"+tracefile+"'")######### State initialization functions ############### Read energy model from filedef read_em(): global model,lineno,em # Reads and parses the energy model file try: model = open(emfile) except IOError: quit(0,"Couldn't open energy model file '"+emfile+"'") l = model.readline() lineno += 1 while l: l=l.strip() # Parse the line, skipping comments, blank lines if l == '' or l[0] == '#': l = model.readline() continue# print "splitting line '%s'" % l (k,v) = l.split() em[k]=float(v) l = model.readline() lineno += 1 def initstate(): global state, total, voltage, prev_current, prev_time, data_file read_em() # initialize the various lists... state = [None] * maxmotes total = [None] * maxmotes prev_current = [None] * maxmotes prev_time = [0] * maxmotes data_file = [None] * maxmotes voltage = em['VOLTAGE'] for mote in range(maxmotes): # Init each mote with base values state[mote] = {'radio':{'on':0, 'tx':0, 'txpower':em['RADIO_DEFAULT_POWER']}, 'cpu': 'IDLE', 'cpu_cycles':0, 'adc': 0, 'adc_on': 0, # For the moment, all the same, but can be changed later 'sensor_board': sb, 'sensor': {}, 'led': {}, 'eeprom': {'read':0, 'write':0}} total[mote] = {} prev_current[mote]={} for k in totals: prev_current[mote][k] = 0 prev_current[mote]['total']=0 for t in totals: total[mote][t] = 0######################## Current computation #######################def get_cpu_current(mote): return em["CPU_"+state[mote]["cpu"]]def get_sensor_current(mote): mystate = state[mote]['sensor'] total = 0 # If the sensor board is plugged it draws a constant base current if state[mote]['sensor_board']: total += em.get('SENSOR_BOARD') for (type,value) in mystate.items(): if value==1: total += em.get("SENSOR_"+type, 0) return totaldef get_adc_current(mote): # FIXME: if we discover that sampling actually takes energy # in addition to the base cost, add it in if sampling. if state[mote]['adc_on']: return em['ADC'] else: return 0def tx_current(x): """ Return the radio current for transmit power x """ return em["RADIO_TX_"+("%02X" % x)]def get_radio_current(mote): #the state is: {'on':ON/OFF,'tx': TX/RX,'txpower':PowerLevel} mystate = state[mote]['radio'] if mystate['on']: if mystate['tx']: return tx_current(mystate['txpower']) else: return em['RADIO_RX'] else: return 0 def get_leds_current(mote): # Count how many leds are on: numon = state[mote]['led'].values().count(1) return numon * em['LED']def get_eeprom_current(mote): # Assumes that EEPROM can't read and write at the same time # I believe that's correct if state[mote]['eeprom']['read']: return em['EEPROM_READ'] if state[mote]['eeprom']['write']: return em['EEPROM_WRITE'] return 0 # There should probably be one entry for each key of the totals# defined abovecurrent_fn_map = { 'cpu': get_cpu_current, 'radio': get_radio_current, 'adc': get_adc_current, 'leds':get_leds_current, 'sensor':get_sensor_current, 'eeprom':get_eeprom_current}def get_current(mote): total = 0 for k in current_fn_map.keys(): total += current_fn_map[k](mote) return totaldef print_currents(): for m in range(maxseen+1): print "mote %d: current %f" % (m, get_current(m))######################## Event processing ########################### Add together a mote time from the trace (in CPU cycles)# and a energy model time (in ms)def time_add(motetime, emtime): return motetime + emtime / 1000.0 * em.get("CPU_FREQ",7370000)# The handlers should just update the state. Other functions are# responsible for keeping track of totals.def cpu_cycle_handler(mote, time, newstate): # the cpu cycle messages always have a single number, which is # the total since beginning of execution global state state[mote]['cpu_cycles'] = float(newstate[1])def cpu_state_handler(mote, time, newstate): # Here are the possible states, from PowerStateM.nc: # char cpu_power_state[8][20] = {"IDLE", \
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -