diff options
-rwxr-xr-x | bin/generate-dfa-benchmark.py | 7 | ||||
-rw-r--r-- | lib/codegen.py | 37 |
2 files changed, 41 insertions, 3 deletions
diff --git a/bin/generate-dfa-benchmark.py b/bin/generate-dfa-benchmark.py index 3e4b9a2..640f4a1 100755 --- a/bin/generate-dfa-benchmark.py +++ b/bin/generate-dfa-benchmark.py @@ -36,7 +36,7 @@ import io import yaml from aspectc import Repo from automata import PTA -from codegen import MultipassDriver, StaticStateOnlyAccounting +from codegen import * from harness import OnboardTimerHarness opt = dict() @@ -102,7 +102,8 @@ def benchmark_from_runs(pta: PTA, runs: list, harness: OnboardTimerHarness, benc outbuf.write('arch.delay_ms({:d}); // {}\n'.format(opt['sleep'], transition.destination.name)) outbuf.write(harness.stop_run(num_traces)) - outbuf.write('{}getEnergy();\n'.format(class_prefix)) + if dummy: + outbuf.write('kout << "[Energy] " << {}getEnergy() << endl;\n'.format(class_prefix)) outbuf.write('\n') num_traces += 1 @@ -241,6 +242,8 @@ if __name__ == '__main__': repo = Repo('/home/derf/var/projects/multipass/build/repo.acp') + pta.set_random_energy_model() + drv = MultipassDriver(opt['dummy'], pta, repo.class_by_name[opt['dummy']], enum=enum, accounting=StaticStateOnlyAccounting(opt['dummy'], pta)) with open('/home/derf/var/projects/multipass/src/driver/dummy.cc', 'w') as f: f.write(drv.impl) diff --git a/lib/codegen.py b/lib/codegen.py index fd1b24e..a8cb431 100644 --- a/lib/codegen.py +++ b/lib/codegen.py @@ -82,6 +82,39 @@ class AccountingMethod: def get_includes(self): return map(lambda x: '#include "{}"'.format(x), self.include_paths) +class StaticStateOnlyAccountingImmediateCalculation(AccountingMethod): + def __init__(self, class_name: str, pta: PTA, ts_type = 'unsigned int', power_type = 'unsigned int', energy_type = 'unsigned long'): + super().__init__(class_name, pta) + self.ts_type = ts_type + self.include_paths.append('driver/uptime.h') + self.private_variables.append('unsigned char lastState;') + self.private_variables.append('{} lastStateChange;'.format(ts_type)) + self.private_variables.append('{} totalEnergy;'.format(energy_type)) + self.private_variables.append(array_template.format( + type = power_type, + name = 'state_power', + length = len(pta.state), + elements = ', '.join(map(lambda state_name: '{:.0f}'.format(pta.state[state_name].power), pta.get_state_names())) + )) + + get_energy_function = """return totalEnergy;""" + self.public_functions.append(ClassFunction(class_name, energy_type, 'getEnergy', list(), get_energy_function)) + + def pre_transition_hook(self, transition): + return """ + unsigned int now = uptime.get_us(); + totalEnergy += (now - lastStateChange) * state_power[lastState]; + lastStateChange = now; + lastState = {}; + """.format(self.pta.get_state_id(transition.destination)) + + def init_code(self): + return """ + totalEnergy = 0; + lastStateChange = 0; + lastState = 0; + """.format(num_states = len(self.pta.state)) + class StaticStateOnlyAccounting(AccountingMethod): def __init__(self, class_name: str, pta: PTA, ts_type = 'unsigned int', power_type = 'unsigned int', energy_type = 'unsigned long'): super().__init__(class_name, pta) @@ -93,7 +126,7 @@ class StaticStateOnlyAccounting(AccountingMethod): type = power_type, name = 'state_power', length = len(pta.state), - elements = ', '.join(map(lambda state_name: str(pta.state[state_name].power), pta.get_state_names())) + elements = ', '.join(map(lambda state_name: '{:.0f}'.format(pta.state[state_name].power), pta.get_state_names())) )) self.private_variables.append('{} timeInState[{}];'.format(ts_type, len(pta.state))) @@ -119,6 +152,8 @@ class StaticStateOnlyAccounting(AccountingMethod): for (unsigned char i = 0; i < {num_states}; i++) {{ timeInState[i] = 0; }} + lastState = 0; + lastStateChange = 0; """.format(num_states = len(self.pta.state)) |