summaryrefslogtreecommitdiff
path: root/src/cpu/simple/atomic.cc
diff options
context:
space:
mode:
authorDam Sunwoo <dam.sunwoo@arm.com>2013-04-22 13:20:31 -0400
committerDam Sunwoo <dam.sunwoo@arm.com>2013-04-22 13:20:31 -0400
commit2c1e34431326381833de289b1d90f2427ba16c98 (patch)
tree2f1b7a0e9a400d5b5d660b4386d4b993cbd0e31c /src/cpu/simple/atomic.cc
parent121b15a54da77ef77e98ff59621e1c5b0f1f1f52 (diff)
downloadgem5-2c1e34431326381833de289b1d90f2427ba16c98.tar.xz
cpu: generate SimPoint basic block vector profiles
This patch is based on http://reviews.m5sim.org/r/1474/ originally written by Mitch Hayenga. Basic block vectors are generated (simpoint.bb.gz in simout folder) based on start and end addresses of basic blocks. Some comments to the original patch are addressed and hooks are added to create and resume from checkpoints based on instruction counts dictated by external SimPoint analysis tools. SimPoint creation/resuming options will be implemented as a separate patch.
Diffstat (limited to 'src/cpu/simple/atomic.cc')
-rw-r--r--src/cpu/simple/atomic.cc85
1 files changed, 84 insertions, 1 deletions
diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc
index d7c4190ee..1dd9675f9 100644
--- a/src/cpu/simple/atomic.cc
+++ b/src/cpu/simple/atomic.cc
@@ -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"
@@ -109,9 +110,20 @@ AtomicSimpleCPU::AtomicSimpleCPU(AtomicSimpleCPUParams *p)
drain_manager(NULL),
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),
+ simpointStream(NULL),
+ currentBBV(0, 0),
+ currentBBVInstCount(0)
{
_status = Idle;
+
+ if (simpoint) {
+ simpointStream = simout.create(p->simpoint_profile_file, false);
+ }
}
@@ -120,6 +132,9 @@ AtomicSimpleCPU::~AtomicSimpleCPU()
if (tickEvent.scheduled()) {
deschedule(tickEvent);
}
+ if (simpointStream) {
+ simout.close(simpointStream);
+ }
}
unsigned int
@@ -534,6 +549,13 @@ AtomicSimpleCPU::tick()
curStaticInst->isFirstMicroop()))
instCnt++;
+ // profile for SimPoints if enabled and macro inst is finished
+ if (simpoint && curStaticInst && (fault == NoFault) &&
+ (!curStaticInst->isMicroop() ||
+ curStaticInst->isLastMicroop())) {
+ profileSimPoint();
+ }
+
Tick stall_ticks = 0;
if (simulate_inst_stalls && icache_access)
stall_ticks += icache_latency;
@@ -572,6 +594,67 @@ AtomicSimpleCPU::printAddr(Addr a)
dcachePort.printAddr(a);
}
+void
+AtomicSimpleCPU::profileSimPoint()
+{
+ if (!currentBBVInstCount)
+ currentBBV.first = thread->pcState().instAddr();
+
+ ++intervalCount;
+ ++currentBBVInstCount;
+
+ // If inst is control inst, assume end of basic block.
+ if (curStaticInst->isControl()) {
+ currentBBV.second = thread->pcState().instAddr();
+
+ auto map_itr = bbMap.find(currentBBV);
+ if (map_itr == bbMap.end()){
+ // If a new (previously unseen) basic block is found,
+ // add a new unique id, record num of insts and insert into bbMap.
+ BBInfo info;
+ info.id = bbMap.size() + 1;
+ info.insts = currentBBVInstCount;
+ info.count = currentBBVInstCount;
+ bbMap.insert(std::make_pair(currentBBV, info));
+ } else {
+ // If basic block is seen before, just increment the count by the
+ // number of insts in basic block.
+ BBInfo& info = map_itr->second;
+ assert(info.insts == currentBBVInstCount);
+ info.count += currentBBVInstCount;
+ }
+ currentBBVInstCount = 0;
+
+ // Reached end of interval if the sum of the current inst count
+ // (intervalCount) and the excessive inst count from the previous
+ // interval (intervalDrift) is greater than/equal to the interval size.
+ if (intervalCount + intervalDrift >= intervalSize) {
+ // summarize interval and display BBV info
+ std::vector<pair<uint64_t, uint64_t> > counts;
+ for (auto map_itr = bbMap.begin(); map_itr != bbMap.end();
+ ++map_itr) {
+ BBInfo& info = map_itr->second;
+ if (info.count != 0) {
+ counts.push_back(std::make_pair(info.id, info.count));
+ info.count = 0;
+ }
+ }
+ std::sort(counts.begin(), counts.end());
+
+ // 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;
+ }
+ }
+}
////////////////////////////////////////////////////////////////////////
//