diff -r b4bd51f8b7a0 configs/common/Options.py --- a/configs/common/Options.py Tue Oct 16 14:47:31 2012 -0500 +++ b/configs/common/Options.py Fri Oct 19 13:21:00 2012 -0500 @@ -42,6 +42,8 @@ parser.add_option("--caches", action="store_true") parser.add_option("--l2cache", action="store_true") parser.add_option("--fastmem", action="store_true") + parser.add_option("--simpoint_profile", action="store_true") + parser.add_option("--simpoint_interval", type="int", default=100000000) parser.add_option("--clock", action="store", type="string", default='2GHz') parser.add_option("--num-dirs", type="int", default=1) parser.add_option("--num-l2caches", type="int", default=1) diff -r b4bd51f8b7a0 configs/example/se.py --- a/configs/example/se.py Tue Oct 16 14:47:31 2012 -0500 +++ b/configs/example/se.py Fri Oct 19 13:21:00 2012 -0500 @@ -163,6 +163,9 @@ if options.fastmem and (options.caches or options.l2cache): fatal("You cannot use fastmem in combination with caches!") +if options.simpoint_profile and (options.cpu_type != "atomic" or not options.fastmem): + fatal("SimPoint generation should be done with the atomic cpu and fastmem") + for i in xrange(np): if options.smt: system.cpu[i].workload = multiprocesses @@ -174,6 +177,10 @@ if options.fastmem: system.cpu[i].fastmem = True + if options.simpoint_profile: + system.cpu[i].simpoint_profile = True + system.cpu[i].simpoint_interval = options.simpoint_interval + if options.checker: system.cpu[i].addCheckerCpu() diff -r b4bd51f8b7a0 src/cpu/simple/AtomicSimpleCPU.py --- a/src/cpu/simple/AtomicSimpleCPU.py Tue Oct 16 14:47:31 2012 -0500 +++ b/src/cpu/simple/AtomicSimpleCPU.py Fri Oct 19 13:21:00 2012 -0500 @@ -47,3 +47,5 @@ simulate_data_stalls = Param.Bool(False, "Simulate dcache stall cycles") simulate_inst_stalls = Param.Bool(False, "Simulate icache stall cycles") fastmem = Param.Bool(False, "Access memory directly") + simpoint_profile = Param.Bool(False, "Generate SimPoint BBVs") + simpoint_interval = Param.UInt64(100000000, "Simpoint Interval Size") diff -r b4bd51f8b7a0 src/cpu/simple/atomic.hh --- a/src/cpu/simple/atomic.hh Tue Oct 16 14:47:31 2012 -0500 +++ b/src/cpu/simple/atomic.hh Fri Oct 19 13:21:00 2012 -0500 @@ -46,6 +46,29 @@ #include "cpu/simple/base.hh" #include "params/AtomicSimpleCPU.hh" +#include + +struct BasicBlockRange { + Addr start; + Addr end; + bool operator==(const BasicBlockRange &bb) const + { + return (start == bb.start) && (end == bb.end); + } +}; + +namespace std { + template <> + class hash + { + public: + size_t operator()(const BasicBlockRange &bb) const + { + return hash()(bb.start + bb.end); + } + }; +}; + class AtomicSimpleCPU : public BaseSimpleCPU { public: @@ -110,6 +133,23 @@ bool dcache_access; Tick dcache_latency; + void profileSimPoint(); + + // Data structures for SimPoints BBV generation + bool simpoint; + uint64_t intervalSize; + uint64_t intervalCount; + uint64_t intervalDrift; + std::ostream *simpointStream; + + struct BBInfo { + uint64_t id; + uint64_t insts; + uint64_t count; + }; + std::unordered_map bbMap; + BasicBlockRange currentBBV; + uint64_t currentBBVInstCount; protected: /** Return a reference to the data port. */ diff -r b4bd51f8b7a0 src/cpu/simple/atomic.cc --- a/src/cpu/simple/atomic.cc Tue Oct 16 14:47:31 2012 -0500 +++ b/src/cpu/simple/atomic.cc Fri Oct 19 13:21:00 2012 -0500 @@ -44,6 +44,7 @@ #include "arch/mmapped_ipr.hh" #include "arch/utility.hh" #include "base/bigint.hh" +#include "base/output.hh" #include "config/the_isa.hh" #include "cpu/simple/atomic.hh" #include "cpu/exetrace.hh" @@ -107,9 +108,17 @@ simulate_inst_stalls(p->simulate_inst_stalls), icachePort(name() + ".icache_port", this), dcachePort(name() + ".dcache_port", this), - fastmem(p->fastmem) + fastmem(p->fastmem), + simpoint(p->simpoint_profile), + intervalSize(p->simpoint_interval), + intervalCount(0), + intervalDrift(0) { _status = Idle; + + if (simpoint) { + simpointStream = simout.create("simpoint.bb.gz", false); + } } @@ -118,6 +127,9 @@ if (tickEvent.scheduled()) { deschedule(tickEvent); } + if (simpoint) { + simout.close(simpointStream); + } } void @@ -510,6 +522,13 @@ curStaticInst->isFirstMicroop())) instCnt++; + if (simpoint) { + if (curStaticInst && (!curStaticInst->isMicroop() + || curStaticInst->isLastMicroop())) { + profileSimPoint(); + } + } + Tick stall_ticks = 0; if (simulate_inst_stalls && icache_access) stall_ticks += icache_latency; @@ -545,6 +564,53 @@ dcachePort.printAddr(a); } +void +AtomicSimpleCPU::profileSimPoint() +{ + if (!currentBBVInstCount) currentBBV.start = thread->pcState().instAddr(); + + ++intervalCount; + ++currentBBVInstCount; + + if (curStaticInst->isControl()) { + currentBBV.end = thread->pcState().instAddr(); + + auto map_itr = bbMap.find(currentBBV); + if (map_itr == bbMap.end()){ + BBInfo info; + info.id = bbMap.size() + 1; + info.insts = currentBBVInstCount; + info.count = currentBBVInstCount; + bbMap.insert(std::make_pair(currentBBV, info)); + } else { + BBInfo& info = map_itr->second; + assert(info.insts == currentBBVInstCount); + info.count += currentBBVInstCount; + } + currentBBVInstCount = 0; + + if (intervalCount + intervalDrift >= intervalSize) { + std::map counts; + for (auto map_itr = bbMap.begin(); map_itr != bbMap.end(); ++map_itr) { + BBInfo& info = map_itr->second; + if (info.count != 0) { + counts[info.id] = info.count; + info.count = 0; + } + } + + // Print output BBV info + *simpointStream << "T"; + for (auto cnt_itr = counts.begin(); cnt_itr != counts.end(); ++cnt_itr) { + *simpointStream << ":" << cnt_itr->first << ":" << cnt_itr->second << " "; + } + *simpointStream << "\n"; + + intervalDrift = (intervalCount + intervalDrift) - intervalSize; + intervalCount = 0; + } + } +} //////////////////////////////////////////////////////////////////////// //