diff --git a/configs/common/Options.py b/configs/common/Options.py --- a/configs/common/Options.py +++ b/configs/common/Options.py @@ -104,6 +104,11 @@ # CPU Switching - default switch model goes from a checkpoint # to a timing simple CPU with caches to warm up, then to detailed CPU for # data measurement + parser.add_option("--repeat-switch", action="store_true", + help="switch back and forth between CPUs periodically.") + parser.add_option("--switch-freq", action="store", type="int", + help="if --repeat-switch, the switch period. else, it's ignored", + default=5000000000) parser.add_option("-s", "--standard-switch", action="store_true", help="switch from timing CPU to Detailed CPU") parser.add_option("-w", "--warmup", action="store", type="int", diff --git a/configs/common/Simulation.py b/configs/common/Simulation.py --- a/configs/common/Simulation.py +++ b/configs/common/Simulation.py @@ -119,9 +119,16 @@ if options.standard_switch and not options.caches: 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 != None: + fatal("Can't specify both --repeat-switch and --take-checkpoints") + np = options.num_cpus max_checkpoints = options.max_checkpoints switch_cpus = None + repeat_switch_cpus = None if options.prog_interval: for i in xrange(np): @@ -151,12 +158,42 @@ testsys.switch_cpus = switch_cpus switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)] + if options.repeat_switch: + if options.cpu_type == "arm_detailed": + if not options.caches: + print "O3 CPU must be used with caches" + sys.exit(1) + repeat_switch_cpus = [O3_ARM_v7a_3(defer_registration=True, \ + cpu_id=(np+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=(np+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=(np+i)) for i in xrange(np)] + else: + repeat_switch_cpus = [AtomicSimpleCPU(defer_registration=True, \ + cpu_id=(np+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 + + testsys.repeat_switch_cpus = repeat_switch_cpus + repeat_switch_cpu_list = [(testsys.cpu[i], repeat_switch_cpus[i]) + for i in xrange(np)] + if options.standard_switch: - if not options.caches: - # O3 CPU must have a cache to work. - print "O3 CPU must be used with caches" - sys.exit(1) - switch_cpus = [TimingSimpleCPU(defer_registration=True, cpu_id=(np+i)) for i in xrange(np)] switch_cpus_1 = [DerivO3CPU(defer_registration=True, cpu_id=(2*np+i)) @@ -348,7 +385,7 @@ num_checkpoints += 1 if exit_event.getCause() == "user interrupt received": - exit_cause = exit_event.getCause(); + exit_cause = exit_event.getCause() else: when, period = options.take_checkpoints.split(",", 1) when = int(when) @@ -380,23 +417,46 @@ num_checkpoints += 1 if exit_event.getCause() != "simulate() limit reached": - exit_cause = exit_event.getCause(); + exit_cause = exit_event.getCause() else: # no checkpoints being taken via this script if options.fast_forward: m5.stats.reset() print "**** REAL SIMULATION ****" - exit_event = m5.simulate(maxtick) + if options.repeat_switch and maxtick > options.switch_freq: + print 'starting switch loop' + while True: + exit_event = m5.simulate(options.switch_freq) + exit_cause = exit_event.getCause() - while exit_event.getCause() == "checkpoint": - m5.checkpoint(joinpath(cptdir, "cpt.%d")) - num_checkpoints += 1 - if num_checkpoints == max_checkpoints: - exit_cause = "maximum %d checkpoints dropped" % max_checkpoints - break + if exit_cause != "simulate() limit reached": + break - exit_event = m5.simulate(maxtick - m5.curTick()) - exit_cause = exit_event.getCause() + 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()) <= options.switch_freq: + exit_event = m5.simulate(maxtick - m5.curTick()) + break + else: + exit_event = m5.simulate(maxtick) + + while exit_event.getCause() == "checkpoint": + m5.checkpoint(joinpath(cptdir, "cpt.%d")) + num_checkpoints += 1 + if num_checkpoints == max_checkpoints: + exit_cause = "maximum %d checkpoints dropped" % max_checkpoints + break + + exit_event = m5.simulate(maxtick - m5.curTick()) + exit_cause = exit_event.getCause() if exit_cause == '': exit_cause = exit_event.getCause() @@ -404,4 +464,3 @@ if options.checkpoint_at_end: m5.checkpoint(joinpath(cptdir, "cpt.%d")) -