changeset 2a0fe8bca031 in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=2a0fe8bca031
description:
        cpu: Probe points for basic PMU stats

        This changeset adds probe points that can be used to implement PMU
        counters for CPU stats. The following probes are supported:

          * BaseCPU::ppCycles / Cycles
          * BaseCPU::ppRetiredInsts / RetiredInsts
          * BaseCPU::ppRetiredLoads / RetiredLoads
          * BaseCPU::ppRetiredStores / RetiredStores
          * BaseCPU::ppRetiredBranches RetiredBranches

diffstat:

 src/cpu/base.cc           |  36 +++++++++++++++++++++++++++++++++
 src/cpu/base.hh           |  51 +++++++++++++++++++++++++++++++++++++++++++++++
 src/cpu/minor/execute.cc  |   2 +
 src/cpu/minor/pipeline.hh |   5 ++++
 src/cpu/o3/cpu.cc         |  14 ++++++++++--
 src/cpu/simple/atomic.cc  |   7 +++++-
 src/cpu/simple/base.cc    |   3 ++
 src/cpu/simple/timing.cc  |  29 ++++++++++++++++----------
 src/cpu/simple/timing.hh  |   4 ++-
 src/sim/ticked_object.hh  |  15 +++++++++++++
 10 files changed, 150 insertions(+), 16 deletions(-)

diffs (truncated from 380 to 300 lines):

diff -r 25c5da51bbe0 -r 2a0fe8bca031 src/cpu/base.cc
--- a/src/cpu/base.cc   Thu Oct 16 05:49:41 2014 -0400
+++ b/src/cpu/base.cc   Thu Oct 16 05:49:41 2014 -0400
@@ -283,6 +283,42 @@
     }
 }
 
+ProbePoints::PMUUPtr
+BaseCPU::pmuProbePoint(const char *name)
+{
+    ProbePoints::PMUUPtr ptr;
+    ptr.reset(new ProbePoints::PMU(getProbeManager(), name));
+
+    return ptr;
+}
+
+void
+BaseCPU::regProbePoints()
+{
+    ppCycles = pmuProbePoint("Cycles");
+
+    ppRetiredInsts = pmuProbePoint("RetiredInsts");
+    ppRetiredLoads = pmuProbePoint("RetiredLoads");
+    ppRetiredStores = pmuProbePoint("RetiredStores");
+    ppRetiredBranches = pmuProbePoint("RetiredBranches");
+}
+
+void
+BaseCPU::probeInstCommit(const StaticInstPtr &inst)
+{
+    if (!inst->isMicroop() || inst->isLastMicroop())
+        ppRetiredInsts->notify(1);
+
+
+    if (inst->isLoad())
+        ppRetiredLoads->notify(1);
+
+    if (inst->isStore())
+        ppRetiredLoads->notify(1);
+
+    if (inst->isControl())
+        ppRetiredBranches->notify(1);
+}
 
 void
 BaseCPU::regStats()
diff -r 25c5da51bbe0 -r 2a0fe8bca031 src/cpu/base.hh
--- a/src/cpu/base.hh   Thu Oct 16 05:49:41 2014 -0400
+++ b/src/cpu/base.hh   Thu Oct 16 05:49:41 2014 -0400
@@ -62,6 +62,7 @@
 #include "sim/eventq.hh"
 #include "sim/full_system.hh"
 #include "sim/insttracer.hh"
+#include "sim/probe/pmu.hh"
 #include "sim/system.hh"
 
 struct BaseCPUParams;
@@ -280,6 +281,8 @@
     virtual void startup();
     virtual void regStats();
 
+    void regProbePoints() M5_ATTR_OVERRIDE;
+
     void registerThreadContexts();
 
     /**
@@ -437,6 +440,54 @@
      */
     void scheduleLoadStop(ThreadID tid, Counter loads, const char *cause);
 
+  public:
+    /**
+     * @{
+     * @name PMU Probe points.
+     */
+
+    /**
+     * Helper method to trigger PMU probes for a committed
+     * instruction.
+     *
+     * @param inst Instruction that just committed
+     */
+    virtual void probeInstCommit(const StaticInstPtr &inst);
+
+    /**
+     * Helper method to instantiate probe points belonging to this
+     * object.
+     *
+     * @param name Name of the probe point.
+     * @return A unique_ptr to the new probe point.
+     */
+    ProbePoints::PMUUPtr pmuProbePoint(const char *name);
+
+    /** CPU cycle counter */
+    ProbePoints::PMUUPtr ppCycles;
+
+    /**
+     * Instruction commit probe point.
+     *
+     * This probe point is triggered whenever one or more instructions
+     * are committed. It is normally triggered once for every
+     * instruction. However, CPU models committing bundles of
+     * instructions may call notify once for the entire bundle.
+     */
+    ProbePoints::PMUUPtr ppRetiredInsts;
+
+    /** Retired load instructions */
+    ProbePoints::PMUUPtr ppRetiredLoads;
+    /** Retired store instructions */
+    ProbePoints::PMUUPtr ppRetiredStores;
+
+    /** Retired branches (any type) */
+    ProbePoints::PMUUPtr ppRetiredBranches;
+
+    /** @} */
+
+
+
     // Function tracing
   private:
     bool functionTracingEnabled;
diff -r 25c5da51bbe0 -r 2a0fe8bca031 src/cpu/minor/execute.cc
--- a/src/cpu/minor/execute.cc  Thu Oct 16 05:49:41 2014 -0400
+++ b/src/cpu/minor/execute.cc  Thu Oct 16 05:49:41 2014 -0400
@@ -853,6 +853,8 @@
     /* Set the CP SeqNum to the numOps commit number */
     if (inst->traceData)
         inst->traceData->setCPSeq(thread->numOp);
+
+    cpu.probeInstCommit(inst->staticInst);
 }
 
 bool
diff -r 25c5da51bbe0 -r 2a0fe8bca031 src/cpu/minor/pipeline.hh
--- a/src/cpu/minor/pipeline.hh Thu Oct 16 05:49:41 2014 -0400
+++ b/src/cpu/minor/pipeline.hh Thu Oct 16 05:49:41 2014 -0400
@@ -126,6 +126,11 @@
      *  stages and pipeline advance) */
     void evaluate();
 
+    void countCycles(Cycles delta) M5_ATTR_OVERRIDE
+    {
+        cpu.ppCycles->notify(delta);
+    }
+
     void minorTrace() const;
 
     /** Functions below here are BaseCPU operations passed on to pipeline
diff -r 25c5da51bbe0 -r 2a0fe8bca031 src/cpu/o3/cpu.cc
--- a/src/cpu/o3/cpu.cc Thu Oct 16 05:49:41 2014 -0400
+++ b/src/cpu/o3/cpu.cc Thu Oct 16 05:49:41 2014 -0400
@@ -405,8 +405,11 @@
 void
 FullO3CPU<Impl>::regProbePoints()
 {
+    BaseCPU::regProbePoints();
+
     ppInstAccessComplete = new ProbePointArg<PacketPtr>(getProbeManager(), 
"InstAccessComplete");
     ppDataAccessComplete = new ProbePointArg<std::pair<DynInstPtr, PacketPtr> 
>(getProbeManager(), "DataAccessComplete");
+
     fetch.regProbePoints();
     iew.regProbePoints();
     commit.regProbePoints();
@@ -534,6 +537,7 @@
     assert(getDrainState() != Drainable::Drained);
 
     ++numCycles;
+    ppCycles->notify(1);
 
 //    activity = false;
 
@@ -1444,6 +1448,8 @@
     // Check for instruction-count-based events.
     comInstEventQueue[tid]->serviceEvents(thread[tid]->numInst);
     system->instEventQueue.serviceEvents(system->totalNumInsts);
+
+    probeInstCommit(inst->staticInst);
 }
 
 template <class Impl>
@@ -1622,10 +1628,12 @@
 
     Cycles cycles(curCycle() - lastRunningCycle);
     // @todo: This is an oddity that is only here to match the stats
-    if (cycles != 0)
+    if (cycles > 1) {
         --cycles;
-    idleCycles += cycles;
-    numCycles += cycles;
+        idleCycles += cycles;
+        numCycles += cycles;
+        ppCycles->notify(cycles);
+    }
 
     schedule(tickEvent, clockEdge());
 }
diff -r 25c5da51bbe0 -r 2a0fe8bca031 src/cpu/simple/atomic.cc
--- a/src/cpu/simple/atomic.cc  Thu Oct 16 05:49:41 2014 -0400
+++ b/src/cpu/simple/atomic.cc  Thu Oct 16 05:49:41 2014 -0400
@@ -233,7 +233,9 @@
     assert(!tickEvent.scheduled());
 
     notIdleFraction = 1;
-    numCycles += ticksToCycles(thread->lastActivate - thread->lastSuspend);
+    Cycles delta = ticksToCycles(thread->lastActivate - thread->lastSuspend);
+    numCycles += delta;
+    ppCycles->notify(delta);
 
     //Make sure ticks are still on multiples of cycles
     schedule(tickEvent, clockEdge(Cycles(0)));
@@ -501,6 +503,7 @@
 
     for (int i = 0; i < width || locked; ++i) {
         numCycles++;
+        ppCycles->notify(1);
 
         if (!curStaticInst || !curStaticInst->isDelayedCommit())
             checkForInterrupts();
@@ -614,6 +617,8 @@
 void
 AtomicSimpleCPU::regProbePoints()
 {
+    BaseCPU::regProbePoints();
+
     ppCommit = new ProbePointArg<pair<SimpleThread*, const StaticInstPtr>>
                                 (getProbeManager(), "Commit");
 }
diff -r 25c5da51bbe0 -r 2a0fe8bca031 src/cpu/simple/base.cc
--- a/src/cpu/simple/base.cc    Thu Oct 16 05:49:41 2014 -0400
+++ b/src/cpu/simple/base.cc    Thu Oct 16 05:49:41 2014 -0400
@@ -544,6 +544,9 @@
         delete traceData;
         traceData = NULL;
     }
+
+    // Call CPU instruction commit probes
+    probeInstCommit(curStaticInst);
 }
 
 void
diff -r 25c5da51bbe0 -r 2a0fe8bca031 src/cpu/simple/timing.cc
--- a/src/cpu/simple/timing.cc  Thu Oct 16 05:49:41 2014 -0400
+++ b/src/cpu/simple/timing.cc  Thu Oct 16 05:49:41 2014 -0400
@@ -178,7 +178,7 @@
     assert(!stayAtPC);
     assert(microPC() == 0);
 
-    numCycles += curCycle() - previousCycle;
+    updateCycleCounts();
 }
 
 
@@ -332,8 +332,7 @@
 {
     // fault may be NoFault in cases where a fault is suppressed,
     // for instance prefetches.
-    numCycles += curCycle() - previousCycle;
-    previousCycle = curCycle();
+    updateCycleCounts();
 
     if (traceData) {
         // Since there was a fault, we shouldn't trace this instruction.
@@ -569,8 +568,7 @@
         _status = IcacheWaitResponse;
         completeIfetch(NULL);
 
-        numCycles += curCycle() - previousCycle;
-        previousCycle = curCycle();
+        updateCycleCounts();
     }
 }
 
@@ -603,8 +601,7 @@
         advanceInst(fault);
     }
 
-    numCycles += curCycle() - previousCycle;
-    previousCycle = curCycle();
+    updateCycleCounts();
 }
 
 
@@ -651,8 +648,7 @@
 
     _status = BaseSimpleCPU::Running;
 
-    numCycles += curCycle() - previousCycle;
-    previousCycle = curCycle();
+    updateCycleCounts();
 
     if (pkt)
         pkt->req->setAccessLatency();
@@ -753,8 +749,8 @@
            pkt->req->getFlags().isSet(Request::NO_ACCESS));
 
     pkt->req->setAccessLatency();
-    numCycles += curCycle() - previousCycle;
-    previousCycle = curCycle();
+
+    updateCycleCounts();
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to