Skip to content
Snippets Groups Projects
Commit dd37c233 authored by Christian Dietrich's avatar Christian Dietrich
Browse files

improve manual wcpt calculation

parent 6d734253
No related branches found
No related tags found
No related merge requests found
......@@ -12,11 +12,17 @@ DeclareEvent(ComputationAborted);
GENERATE_TIME_CONSUMER(computation, 5000)
extern "C" {
void timing_entry() {
ActivateTask(Computation);
WaitEvent(ComputationFinished | ComputationAborted);
}
}
TASK(Control) {
timing_start(0);
ActivateTask(Computation);
WaitEvent(ComputationFinished | ComputationAborted);
timing_entry();
timing_end(TIMING_POINT_NO_INTERRUPTS_IN_BLOCK | 0);
/* ABB Split Point */
......
......@@ -10,6 +10,8 @@ import shlex
import subprocess
import threading
import re
import logging
import tempfile
class Execution:
def __init__(self, command, proc):
......@@ -76,16 +78,20 @@ def run_wait_timeout(cmd, stdin_data, timeout):
return proc
RELATIVE_BUILD_DIR = '../../../build'
DREF_KEY = 'app/benchmark/timing/'
DREF_KEY = 'MANUAL/cycles'
def parse_args():
parser = ArgumentParser(description="script for manual evaluation of sysbench")
parser.add_argument('-b', '--bench', dest='bench',
help='the benchmark under analysis',
choices=['tmr','computation_irq','aborted_computation'],
choices=['tmr','computation_alarm','aborted_computation'],
required=False, default=None)
parser.add_argument('-d', '--dref', dest='dref_file',
help='file for the manual results',
required=False, default="bench-timing-manual.dref")
parser.add_argument('-a', '--all', dest='all', action='store_true',
help='process all benchmarks',
required=False, default=False)
......@@ -121,40 +127,75 @@ def get_elf(args_bench):
def setup_paths(args_bench):
elf = get_elf(args_bench)
build_dir = os.path.abspath(RELATIVE_BUILD_DIR)
cmake_binary_dir = os.path.join(build_dir, DREF_KEY)
bench_out_dir = os.path.join(cmake_binary_dir, 'bench-timing-' + args_bench)
system_pml = os.path.join(bench_out_dir, 'system.pml')
gcfg_pml = os.path.join(bench_out_dir, 'gcfg.pml')
bench_out_dir = os.path.join(build_dir, )
system_pml = os.path.join(build_dir, 'bench-timing-%s-system.pml'%(args_bench))
gcfg_pml = os.path.join(build_dir, 'bench-timing-%s-gcfg.pml'%(args_bench))
return (elf, system_pml, gcfg_pml)
def write_result_file(elf, cycles):
result_file = elf + '-' + 'manual.dref'
f = open(result_file, 'w')
f.write('\drefset{' + DREF_KEY + '}' + '{' + str(cycles) + '}')
f.close()
print('written: ' + result_file)
def get_cycles_from_entry(entry, bench):
def dref_key(dref_file, key, value):
logging.info("drefset: %s = %d", key, value)
content = []
if os.path.exists(dref_file):
with open(dref_file) as fd:
content += [x.strip() for x in fd.readlines()]
line = '\\drefset{/%s/%s}{%s}' %(key, DREF_KEY, value)
found = False
for idx in range(0, len(content)):
if content[idx].startswith("\\drefset{%s}" % key):
content[idx] = line
found = True
break
if not found:
content.append(line)
with open(dref_file, "w+") as fd:
fd.write("\n".join(content) + "\n")
def get_cycles_from_entry(entry, bench, flow_facts = []):
elf, system_pml, gcfg_pml = setup_paths(bench)
dref= elf + '-' + 'entry=' + entry + '.dref'
(fd, dref) = tempfile.mkstemp()
cmd = 'platin wcet -i ' + system_pml + ' -i ' + gcfg_pml + \
' --binary ' + elf + ' --wca-count-instructions ' + \
' --disable-ait --wca-detect-gurobi --dref-stats ' + dref + \
' -e ' + entry # GCFG:timing-' + str(circuit)
for ff in flow_facts:
cmd += " --add-flowfact " + repr(ff)
proc = run_wait(cmd, None)
proc.assert_retcode(0)
cy_entry = int(dref_get_value('/WCA/cycles', dref))
logging.info("%s, %s = %d", bench, entry, cy_entry)
os.unlink(dref)
os.close(fd)
return cy_entry
def add_events_with_iat(cy_base, events = []):
cy_total = cy_base
cy_total_last = None
occurences = {}
while cy_total != cy_total_last:
cy_total_last = cy_total
cy_total = cy_base
for (iat, cyc, name) in events:
occ = (int(cy_total) // int(iat)) + 1
cy_total += occ * cyc
occurences[name] = occ
return cy_total, occurences
def main():
parser, args = parse_args()
if "VERBOSE" in os.environ:
args.verbose = True
if args.verbose:
logging.basicConfig(level=logging.DEBUG)
logging.info("Updating %s", args.dref_file)
args.dref_file = os.path.abspath(args.dref_file)
# cd "$(dirname "$0")"
dirname = os.path.dirname(os.path.realpath(__file__))
os.chdir(dirname)
......@@ -162,35 +203,46 @@ def main():
# 1. tmr (non-hierarchical call chains)
if args.all or args.bench == 'tmr':
args.bench = 'tmr'
cy_entry = get_cycles_from_entry('timing_entry', args.bench)
cy_timing_entry = get_cycles_from_entry('timing_entry', args.bench)
cy_computation = get_cycles_from_entry('OSEKOS_TASK_FUNC_Calculation', args.bench)
# take three times the entry
cy_total = cy_entry * 3
cy_total = cy_timing_entry + cy_computation * 3
write_result_file(get_elf(args.bench), int(cy_total))
dref_key(args.dref_file, "tmr", int(cy_total))
# 2. computation IRQ (operating system semantic)
if args.all or args.bench == 'computation_irq':
args.bench = 'computation_irq'
cy_timing_0 = get_cycles_from_entry('timing_0', args.bench)
cy_isr = get_cycles_from_entry('OSEKOS_ISR_ISR1', args.bench)
if args.all or args.bench == 'computation_alarm':
args.bench = 'computation_alarm'
cy_timing_entry = get_cycles_from_entry('timing_entry', args.bench)
cy_task4 = get_cycles_from_entry('OSEKOS_TASK_FUNC_Task4', args.bench)
cy_isr = get_cycles_from_entry('irq_entry', args.bench, ["irq_entry : <> : timer_isr = 1"])
iat_timer = 100000
iat_task4 = 3 * iat_timer
cy_total, occurences = add_events_with_iat(
cy_timing_entry, [(iat_timer, cy_isr, "timer"), (iat_task4, cy_task4, "alarms")])
occurences = (cy_timing_0 / cy_isr) + 1 # +1 => worst case
cy_total = (occurences * cy_isr) + cy_timing_0
logging.info("%s = %d", occurences, cy_total)
write_result_file(get_elf(args.bench), int(cy_total))
dref_key(args.dref_file, "computation alarm", int(cy_total))
# 3 aborted computation (interrupt handling)
if args.all or args.bench == 'aborted_computation':
args.bench = 'aborted_computation'
cy_timing_entry = get_cycles_from_entry('timing_entry', args.bench)
cy_computation = get_cycles_from_entry('OSEKOS_TASK_FUNC_Computation', args.bench)
cy_activate_task = get_cycles_from_entry('OSEKOS_ActivateTask_BB8', args.bench)
cy_ISR_abort = get_cycles_from_entry('OSEKOS_ISR_Abort', args.bench)
cy_ISR_abort = get_cycles_from_entry('irq_entry', args.bench, ["irq_entry : <> : OSEKOS_ISR_Abort = 1"])
iat_isr = 10000
cy_total, occurences = add_events_with_iat(
cy_timing_entry + cy_computation, [(iat_isr, cy_ISR_abort, "isr")])
cy_total = cy_computation + cy_activate_task + cy_ISR_abort
dref_key(args.dref_file, "aborted computation", int(cy_total))
write_result_file(get_elf(args.bench), int(cy_total))
if __name__=='__main__':
main()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment