cpu, cpu, sim: move Cycle probe update
authorJose Marinho <jose.marinho@arm.com>
Thu, 20 Jul 2017 13:57:39 +0000 (14:57 +0100)
committerAndreas Sandberg <andreas.sandberg@arm.com>
Tue, 21 Nov 2017 17:09:18 +0000 (17:09 +0000)
Move the code responsible for performing the actual probe point notify
into BaseCPU. Use BaseCPU activateContext and suspendContext to keep
track of sleep cycles. Create a probe point (ppActiveCycles) that does
not count cycles where the processor was asleep. Rename ppCycles
to ppAllCycles to reflect its nature.

Change-Id: I1907ddd07d0ff9f2ef22cc9f61f5f46c630c9d66
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/5762
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
src/cpu/base.cc
src/cpu/base.hh
src/cpu/kvm/base.cc
src/cpu/minor/pipeline.hh
src/cpu/o3/cpu.cc
src/cpu/simple/atomic.cc
src/cpu/simple/base.cc
src/cpu/simple/timing.cc

index af55ee1d6233950a186d898ba9a5e65821aebd0f..a41a0c3e30380933e39e9a0c833355c2fa472320 100644 (file)
@@ -133,6 +133,7 @@ BaseCPU::BaseCPU(Params *p, bool is_checker)
       _switchedOut(p->switched_out), _cacheLineSize(p->system->cacheLineSize()),
       interrupts(p->interrupts), profileEvent(NULL),
       numThreads(p->numThreads), system(p->system),
+      previousCycle(0), previousState(CPU_STATE_SLEEP),
       functionTraceStream(nullptr), currentFunctionStart(0),
       currentFunctionEnd(0), functionEntryTick(0),
       addressMonitor(p->numThreads),
@@ -385,12 +386,16 @@ BaseCPU::pmuProbePoint(const char *name)
 void
 BaseCPU::regProbePoints()
 {
-    ppCycles = pmuProbePoint("Cycles");
+    ppAllCycles = pmuProbePoint("Cycles");
+    ppActiveCycles = pmuProbePoint("ActiveCycles");
 
     ppRetiredInsts = pmuProbePoint("RetiredInsts");
     ppRetiredLoads = pmuProbePoint("RetiredLoads");
     ppRetiredStores = pmuProbePoint("RetiredStores");
     ppRetiredBranches = pmuProbePoint("RetiredBranches");
+
+    ppSleeping = new ProbePointArg<bool>(this->getProbeManager(),
+                                         "Sleeping");
 }
 
 void
@@ -520,9 +525,10 @@ BaseCPU::activateContext(ThreadID thread_num)
     // Squash enter power gating event while cpu gets activated
     if (enterPwrGatingEvent.scheduled())
         deschedule(enterPwrGatingEvent);
-
     // For any active thread running, update CPU power state to active (ON)
     ClockedObject::pwrState(Enums::PwrState::ON);
+
+    updateCycleCounters(CPU_STATE_WAKEUP);
 }
 
 void
@@ -535,6 +541,9 @@ BaseCPU::suspendContext(ThreadID thread_num)
         }
     }
 
+    // All CPU thread are suspended, update cycle count
+    updateCycleCounters(CPU_STATE_SLEEP);
+
     // All CPU threads suspended, enter lower power state for the CPU
     ClockedObject::pwrState(Enums::PwrState::CLK_GATED);
 
@@ -546,6 +555,12 @@ BaseCPU::suspendContext(ThreadID thread_num)
     }
 }
 
+void
+BaseCPU::haltContext(ThreadID thread_num)
+{
+    updateCycleCounters(BaseCPU::CPU_STATE_SLEEP);
+}
+
 void
 BaseCPU::enterPwrGating(void)
 {
@@ -579,6 +594,10 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU)
     _taskId = oldCPU->taskId();
     // Take over the power state of the switchedOut CPU
     ClockedObject::pwrState(oldCPU->pwrState());
+
+    previousState = oldCPU->previousState;
+    previousCycle = oldCPU->previousCycle;
+
     _switchedOut = false;
 
     ThreadID size = threadContexts.size();
index 13c56a945d27acf052acc2c0549f1b834879d4ad..52598fd229468c6e3ccea585df9238a1a156389d 100644 (file)
@@ -63,6 +63,7 @@
 #include "sim/full_system.hh"
 #include "sim/insttracer.hh"
 #include "sim/probe/pmu.hh"
+#include "sim/probe/probe.hh"
 #include "sim/system.hh"
 #include "debug/Mwait.hh"
 
@@ -277,7 +278,7 @@ class BaseCPU : public MemObject
     virtual void suspendContext(ThreadID thread_num);
 
     /// Notify the CPU that the indicated context is now halted.
-    virtual void haltContext(ThreadID thread_num) {}
+    virtual void haltContext(ThreadID thread_num);
 
    /// Given a Thread Context pointer return the thread num
    int findContext(ThreadContext *tc);
@@ -489,6 +490,7 @@ class BaseCPU : public MemObject
      */
     virtual void probeInstCommit(const StaticInstPtr &inst);
 
+   protected:
     /**
      * Helper method to instantiate probe points belonging to this
      * object.
@@ -498,9 +500,6 @@ class BaseCPU : public MemObject
      */
     ProbePoints::PMUUPtr pmuProbePoint(const char *name);
 
-    /** CPU cycle counter */
-    ProbePoints::PMUUPtr ppCycles;
-
     /**
      * Instruction commit probe point.
      *
@@ -519,9 +518,58 @@ class BaseCPU : public MemObject
     /** Retired branches (any type) */
     ProbePoints::PMUUPtr ppRetiredBranches;
 
+    /** CPU cycle counter even if any thread Context is suspended*/
+    ProbePoints::PMUUPtr ppAllCycles;
+
+    /** CPU cycle counter, only counts if any thread contexts is active **/
+    ProbePoints::PMUUPtr ppActiveCycles;
+
+    /**
+     * ProbePoint that signals transitions of threadContexts sets.
+     * The ProbePoint reports information through it bool parameter.
+     * - If the parameter is true then the last enabled threadContext of the
+     * CPU object was disabled.
+     * - If the parameter is false then a threadContext was enabled, all the
+     * remaining threadContexts are disabled.
+     */
+    ProbePointArg<bool> *ppSleeping;
     /** @} */
 
+    enum CPUState {
+        CPU_STATE_ON,
+        CPU_STATE_SLEEP,
+        CPU_STATE_WAKEUP
+    };
+
+    Cycles previousCycle;
+    CPUState previousState;
 
+    /** base method keeping track of cycle progression **/
+    inline void updateCycleCounters(CPUState state)
+    {
+        uint32_t delta = curCycle() - previousCycle;
+
+        if (previousState == CPU_STATE_ON) {
+            ppActiveCycles->notify(delta);
+        }
+
+        switch (state)
+        {
+          case CPU_STATE_WAKEUP:
+            ppSleeping->notify(false);
+            break;
+          case CPU_STATE_SLEEP:
+            ppSleeping->notify(true);
+            break;
+          default:
+            break;
+        }
+
+        ppAllCycles->notify(delta);
+
+        previousCycle = curCycle();
+        previousState = state;
+    }
 
     // Function tracing
   private:
index d0f7515de02def9935c94aaf392f2d9510369c72..ab83e5d2ff0c950d917e0e901cf4c3fc1b5c8ee6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2015 ARM Limited
+ * Copyright (c) 2012, 2015, 2017 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -584,6 +584,7 @@ BaseKvmCPU::haltContext(ThreadID thread_num)
 {
     // for now, these are equivalent
     suspendContext(thread_num);
+    updateCycleCounters(BaseCPU::CPU_STATE_SLEEP);
 }
 
 ThreadContext *
index 9b6ca0d32332143d427b37693fe30fcbf3ef00e8..ca96d50cb4402a82f964cc4dc698f87155a3e7b3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2014 ARM Limited
+ * Copyright (c) 2013-2014, 2017 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -126,11 +126,6 @@ class Pipeline : public Ticked
      *  stages and pipeline advance) */
     void evaluate() override;
 
-    void countCycles(Cycles delta) override
-    {
-        cpu.ppCycles->notify(delta);
-    }
-
     void minorTrace() const;
 
     /** Functions below here are BaseCPU operations passed on to pipeline
index 091c3a6ad0387be5b89b6c741387b3d5f23c3639..c4bc13fb4c1a10271ddf56aee005db3cdd88de1a 100644 (file)
@@ -568,7 +568,7 @@ FullO3CPU<Impl>::tick()
     assert(drainState() != DrainState::Drained);
 
     ++numCycles;
-    ppCycles->notify(1);
+    updateCycleCounters(BaseCPU::CPU_STATE_ON);
 
 //    activity = false;
 
@@ -796,6 +796,8 @@ FullO3CPU<Impl>::haltContext(ThreadID tid)
 
     deactivateThread(tid);
     removeThread(tid);
+
+    updateCycleCounters(BaseCPU::CPU_STATE_SLEEP);
 }
 
 template <class Impl>
@@ -1771,7 +1773,6 @@ FullO3CPU<Impl>::wakeCPU()
         --cycles;
         idleCycles += cycles;
         numCycles += cycles;
-        ppCycles->notify(cycles);
     }
 
     schedule(tickEvent, clockEdge());
index 9039e6137b1d3164e7f3b524c13a17d1fe4483e3..eea7615c83fab389595b24b4b7b73466311f81a2 100644 (file)
@@ -228,7 +228,6 @@ AtomicSimpleCPU::activateContext(ThreadID thread_num)
     Cycles delta = ticksToCycles(threadInfo[thread_num]->thread->lastActivate -
                                  threadInfo[thread_num]->thread->lastSuspend);
     numCycles += delta;
-    ppCycles->notify(delta);
 
     if (!tickEvent.scheduled()) {
         //Make sure ticks are still on multiples of cycles
@@ -562,7 +561,7 @@ AtomicSimpleCPU::tick()
 
     for (int i = 0; i < width || locked; ++i) {
         numCycles++;
-        ppCycles->notify(1);
+        updateCycleCounters(BaseCPU::CPU_STATE_ON);
 
         if (!curStaticInst || !curStaticInst->isDelayedCommit()) {
             checkForInterrupts();
index 7839676027948a8051845b653bdd2392d60d99d9..62900ec7840611313a476290201af4b29ee14208 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2012,2015 ARM Limited
+ * Copyright (c) 2010-2012, 2015, 2017 ARM Limited
  * Copyright (c) 2013 Advanced Micro Devices, Inc.
  * All rights reserved
  *
@@ -215,6 +215,7 @@ BaseSimpleCPU::haltContext(ThreadID thread_num)
 {
     // for now, these are equivalent
     suspendContext(thread_num);
+    updateCycleCounters(BaseCPU::CPU_STATE_SLEEP);
 }
 
 
index f57354d56d73812b9636c1f647e5c62acb119a72..c38f2107fcc36919e0bbb3fa15ed2e0087bff9ae 100644 (file)
@@ -185,6 +185,7 @@ TimingSimpleCPU::switchOut()
     assert(thread->microPC() == 0);
 
     updateCycleCounts();
+    updateCycleCounters(BaseCPU::CPU_STATE_ON);
 }
 
 
@@ -363,6 +364,7 @@ TimingSimpleCPU::translationFault(const Fault &fault)
     // fault may be NoFault in cases where a fault is suppressed,
     // for instance prefetches.
     updateCycleCounts();
+    updateCycleCounters(BaseCPU::CPU_STATE_ON);
 
     if (traceData) {
         // Since there was a fault, we shouldn't trace this instruction.
@@ -631,6 +633,7 @@ TimingSimpleCPU::fetch()
         completeIfetch(NULL);
 
         updateCycleCounts();
+        updateCycleCounters(BaseCPU::CPU_STATE_ON);
     }
 }
 
@@ -664,6 +667,7 @@ TimingSimpleCPU::sendFetch(const Fault &fault, RequestPtr req,
     }
 
     updateCycleCounts();
+    updateCycleCounters(BaseCPU::CPU_STATE_ON);
 }
 
 
@@ -721,6 +725,7 @@ TimingSimpleCPU::completeIfetch(PacketPtr pkt)
     _status = BaseSimpleCPU::Running;
 
     updateCycleCounts();
+    updateCycleCounters(BaseCPU::CPU_STATE_ON);
 
     if (pkt)
         pkt->req->setAccessLatency();
@@ -821,6 +826,7 @@ TimingSimpleCPU::completeDataAccess(PacketPtr pkt)
     pkt->req->setAccessLatency();
 
     updateCycleCounts();
+    updateCycleCounters(BaseCPU::CPU_STATE_ON);
 
     if (pkt->senderState) {
         SplitFragmentSenderState * send_state =
@@ -875,7 +881,6 @@ TimingSimpleCPU::updateCycleCounts()
     const Cycles delta(curCycle() - previousCycle);
 
     numCycles += delta;
-    ppCycles->notify(delta);
 
     previousCycle = curCycle();
 }