configs: add option for repeatedly switching back-and-forth between cpu types.
This patch adds a --repeat-switch option that will enable repeat core switching at a user defined period (set with --switch-freq option). currently, a switch can only occur between like CPU types. inorder CPU switching is not supported. *note* this patch simply allows a config that will perform repeat switching, it does not fix drain/switchout functionality. if you run with repeat switching you will hit assertion failures and/or your workload with hang or die.
This commit is contained in:
parent
73e9e923d0
commit
5a648f2074
2 changed files with 93 additions and 19 deletions
|
@ -104,11 +104,12 @@ def addCommonOptions(parser):
|
||||||
# CPU Switching - default switch model goes from a checkpoint
|
# CPU Switching - default switch model goes from a checkpoint
|
||||||
# to a timing simple CPU with caches to warm up, then to detailed CPU for
|
# to a timing simple CPU with caches to warm up, then to detailed CPU for
|
||||||
# data measurement
|
# data measurement
|
||||||
parser.add_option("-s", "--standard-switch", action="store_true",
|
parser.add_option("--repeat-switch", action="store", type="int",
|
||||||
help="switch from timing CPU to Detailed CPU")
|
default=None,
|
||||||
parser.add_option("-w", "--warmup", action="store", type="int",
|
help="switch back and forth between CPUs with period <N>")
|
||||||
help="if -s, then this is the warmup period. else, this is ignored",
|
parser.add_option("-s", "--standard-switch", action="store", type="int",
|
||||||
default=5000000000)
|
default=None,
|
||||||
|
help="switch from timing to Detailed CPU after warmup period of <N>")
|
||||||
parser.add_option("-p", "--prog-interval", type="int",
|
parser.add_option("-p", "--prog-interval", type="int",
|
||||||
help="CPU Progress Interval")
|
help="CPU Progress Interval")
|
||||||
|
|
||||||
|
|
|
@ -214,10 +214,6 @@ def scriptCheckpoints(options):
|
||||||
return exit_cause
|
return exit_cause
|
||||||
|
|
||||||
def benchCheckpoints(options, maxtick, cptdir):
|
def benchCheckpoints(options, maxtick, cptdir):
|
||||||
if options.fast_forward:
|
|
||||||
m5.stats.reset()
|
|
||||||
|
|
||||||
print "**** REAL SIMULATION ****"
|
|
||||||
exit_event = m5.simulate(maxtick)
|
exit_event = m5.simulate(maxtick)
|
||||||
exit_cause = exit_event.getCause()
|
exit_cause = exit_event.getCause()
|
||||||
|
|
||||||
|
@ -236,6 +232,29 @@ def benchCheckpoints(options, maxtick, cptdir):
|
||||||
|
|
||||||
return exit_cause
|
return exit_cause
|
||||||
|
|
||||||
|
def repeatSwitch(testsys, repeat_switch_cpu_list, maxtick, switch_freq):
|
||||||
|
print "starting switch loop"
|
||||||
|
while True:
|
||||||
|
exit_event = m5.simulate(switch_freq)
|
||||||
|
exit_cause = exit_event.getCause()
|
||||||
|
|
||||||
|
if exit_cause != "simulate() limit reached":
|
||||||
|
return exit_cause
|
||||||
|
|
||||||
|
print "draining the system"
|
||||||
|
m5.doDrain(testsys)
|
||||||
|
m5.switchCpus(repeat_switch_cpu_list)
|
||||||
|
m5.resume(testsys)
|
||||||
|
|
||||||
|
tmp_cpu_list = []
|
||||||
|
for old_cpu, new_cpu in repeat_switch_cpu_list:
|
||||||
|
tmp_cpu_list.append((new_cpu, old_cpu))
|
||||||
|
repeat_switch_cpu_list = tmp_cpu_list
|
||||||
|
|
||||||
|
if (maxtick - m5.curTick()) <= switch_freq:
|
||||||
|
exit_event = m5.simulate(maxtick - m5.curTick())
|
||||||
|
return exit_event.getCause()
|
||||||
|
|
||||||
def run(options, root, testsys, cpu_class):
|
def run(options, root, testsys, cpu_class):
|
||||||
if options.maxtick:
|
if options.maxtick:
|
||||||
maxtick = options.maxtick
|
maxtick = options.maxtick
|
||||||
|
@ -259,6 +278,12 @@ def run(options, root, testsys, cpu_class):
|
||||||
if options.standard_switch and not options.caches:
|
if options.standard_switch and not options.caches:
|
||||||
fatal("Must specify --caches when using --standard-switch")
|
fatal("Must specify --caches when using --standard-switch")
|
||||||
|
|
||||||
|
if options.standard_switch and options.repeat_switch:
|
||||||
|
fatal("Can't specify both --standard-switch and --repeat-switch")
|
||||||
|
|
||||||
|
if options.repeat_switch and options.take_checkpoints:
|
||||||
|
fatal("Can't specify both --repeat-switch and --take-checkpoints")
|
||||||
|
|
||||||
np = options.num_cpus
|
np = options.num_cpus
|
||||||
switch_cpus = None
|
switch_cpus = None
|
||||||
|
|
||||||
|
@ -271,7 +296,7 @@ def run(options, root, testsys, cpu_class):
|
||||||
testsys.cpu[i].max_insts_any_thread = options.maxinsts
|
testsys.cpu[i].max_insts_any_thread = options.maxinsts
|
||||||
|
|
||||||
if cpu_class:
|
if cpu_class:
|
||||||
switch_cpus = [cpu_class(defer_registration=True, cpu_id=(np+i))
|
switch_cpus = [cpu_class(defer_registration=True, cpu_id=(i))
|
||||||
for i in xrange(np)]
|
for i in xrange(np)]
|
||||||
|
|
||||||
for i in xrange(np):
|
for i in xrange(np):
|
||||||
|
@ -290,15 +315,55 @@ def run(options, root, testsys, cpu_class):
|
||||||
testsys.switch_cpus = switch_cpus
|
testsys.switch_cpus = switch_cpus
|
||||||
switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)]
|
switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)]
|
||||||
|
|
||||||
if options.standard_switch:
|
if options.repeat_switch:
|
||||||
if not options.caches:
|
if options.cpu_type == "arm_detailed":
|
||||||
# O3 CPU must have a cache to work.
|
if not options.caches:
|
||||||
print "O3 CPU must be used with caches"
|
print "O3 CPU must be used with caches"
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
switch_cpus = [TimingSimpleCPU(defer_registration=True, cpu_id=(np+i))
|
repeat_switch_cpus = [O3_ARM_v7a_3(defer_registration=True, \
|
||||||
|
cpu_id=(i)) for i in xrange(np)]
|
||||||
|
elif options.cpu_type == "detailed":
|
||||||
|
if not options.caches:
|
||||||
|
print "O3 CPU must be used with caches"
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
repeat_switch_cpus = [DerivO3CPU(defer_registration=True, \
|
||||||
|
cpu_id=(i)) for i in xrange(np)]
|
||||||
|
elif options.cpu_type == "inorder":
|
||||||
|
print "inorder CPU switching not supported"
|
||||||
|
sys.exit(1)
|
||||||
|
elif options.cpu_type == "timing":
|
||||||
|
repeat_switch_cpus = [TimingSimpleCPU(defer_registration=True, \
|
||||||
|
cpu_id=(i)) for i in xrange(np)]
|
||||||
|
else:
|
||||||
|
repeat_switch_cpus = [AtomicSimpleCPU(defer_registration=True, \
|
||||||
|
cpu_id=(i)) for i in xrange(np)]
|
||||||
|
|
||||||
|
for i in xrange(np):
|
||||||
|
repeat_switch_cpus[i].system = testsys
|
||||||
|
repeat_switch_cpus[i].workload = testsys.cpu[i].workload
|
||||||
|
repeat_switch_cpus[i].clock = testsys.cpu[i].clock
|
||||||
|
|
||||||
|
if options.maxinsts:
|
||||||
|
repeat_switch_cpus[i].max_insts_any_thread = options.maxinsts
|
||||||
|
|
||||||
|
if options.checker:
|
||||||
|
repeat_switch_cpus[i].addCheckerCpu()
|
||||||
|
|
||||||
|
testsys.repeat_switch_cpus = repeat_switch_cpus
|
||||||
|
|
||||||
|
if cpu_class:
|
||||||
|
repeat_switch_cpu_list = [(switch_cpus[i], repeat_switch_cpus[i])
|
||||||
|
for i in xrange(np)]
|
||||||
|
else:
|
||||||
|
repeat_switch_cpu_list = [(testsys.cpu[i], repeat_switch_cpus[i])
|
||||||
|
for i in xrange(np)]
|
||||||
|
|
||||||
|
if options.standard_switch:
|
||||||
|
switch_cpus = [TimingSimpleCPU(defer_registration=True, cpu_id=(i))
|
||||||
for i in xrange(np)]
|
for i in xrange(np)]
|
||||||
switch_cpus_1 = [DerivO3CPU(defer_registration=True, cpu_id=(2*np+i))
|
switch_cpus_1 = [DerivO3CPU(defer_registration=True, cpu_id=(i))
|
||||||
for i in xrange(np)]
|
for i in xrange(np)]
|
||||||
|
|
||||||
for i in xrange(np):
|
for i in xrange(np):
|
||||||
|
@ -400,7 +465,7 @@ def run(options, root, testsys, cpu_class):
|
||||||
if options.warmup_insts:
|
if options.warmup_insts:
|
||||||
exit_event = m5.simulate()
|
exit_event = m5.simulate()
|
||||||
else:
|
else:
|
||||||
exit_event = m5.simulate(options.warmup)
|
exit_event = m5.simulate(options.standard_switch)
|
||||||
print "Switching CPUS @ tick %s" % (m5.curTick())
|
print "Switching CPUS @ tick %s" % (m5.curTick())
|
||||||
print "Simulation ends instruction count:%d" % \
|
print "Simulation ends instruction count:%d" % \
|
||||||
(testsys.switch_cpus_1[0].max_insts_any_thread)
|
(testsys.switch_cpus_1[0].max_insts_any_thread)
|
||||||
|
@ -425,9 +490,17 @@ def run(options, root, testsys, cpu_class):
|
||||||
# favor of command line checkpoint instructions.
|
# favor of command line checkpoint instructions.
|
||||||
exit_cause = scriptCheckpoints(options)
|
exit_cause = scriptCheckpoints(options)
|
||||||
else:
|
else:
|
||||||
|
if options.fast_forward:
|
||||||
|
m5.stats.reset()
|
||||||
|
print "**** REAL SIMULATION ****"
|
||||||
|
|
||||||
# If checkpoints are being taken, then the checkpoint instruction
|
# If checkpoints are being taken, then the checkpoint instruction
|
||||||
# will occur in the benchmark code it self.
|
# will occur in the benchmark code it self.
|
||||||
exit_cause = benchCheckpoints(options, maxtick, cptdir)
|
if options.repeat_switch and maxtick > options.repeat_switch:
|
||||||
|
exit_cause = repeatSwitch(testsys, repeat_switch_cpu_list,
|
||||||
|
maxtick, options.repeat_switch)
|
||||||
|
else:
|
||||||
|
exit_cause = benchCheckpoints(options, maxtick, cptdir)
|
||||||
|
|
||||||
print 'Exiting @ tick %i because %s' % (m5.curTick(), exit_cause)
|
print 'Exiting @ tick %i because %s' % (m5.curTick(), exit_cause)
|
||||||
if options.checkpoint_at_end:
|
if options.checkpoint_at_end:
|
||||||
|
|
Loading…
Reference in a new issue