summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJose Marinho <jose.marinho@arm.com>2017-07-20 14:57:39 +0100
committerAndreas Sandberg <andreas.sandberg@arm.com>2017-11-21 17:09:18 +0000
commit760cc5735f48f3a5a52ebe31df0c039b23c3d611 (patch)
treeda4103b240221359838888467ac4f12544acc2c5
parent00232a868e4816d19c129fb3d6ef5519d7176d5a (diff)
downloadgem5-760cc5735f48f3a5a52ebe31df0c039b23c3d611.tar.xz
cpu, cpu, sim: move Cycle probe update
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>
-rw-r--r--src/cpu/base.cc23
-rw-r--r--src/cpu/base.hh56
-rw-r--r--src/cpu/kvm/base.cc3
-rw-r--r--src/cpu/minor/pipeline.hh7
-rw-r--r--src/cpu/o3/cpu.cc5
-rw-r--r--src/cpu/simple/atomic.cc3
-rw-r--r--src/cpu/simple/base.cc3
-rw-r--r--src/cpu/simple/timing.cc7
8 files changed, 88 insertions, 19 deletions
diff --git a/src/cpu/base.cc b/src/cpu/base.cc
index af55ee1d6..a41a0c3e3 100644
--- a/src/cpu/base.cc
+++ b/src/cpu/base.cc
@@ -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);
@@ -547,6 +556,12 @@ BaseCPU::suspendContext(ThreadID thread_num)
}
void
+BaseCPU::haltContext(ThreadID thread_num)
+{
+ updateCycleCounters(BaseCPU::CPU_STATE_SLEEP);
+}
+
+void
BaseCPU::enterPwrGating(void)
{
ClockedObject::pwrState(Enums::PwrState::OFF);
@@ -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();
diff --git a/src/cpu/base.hh b/src/cpu/base.hh
index 13c56a945..52598fd22 100644
--- a/src/cpu/base.hh
+++ b/src/cpu/base.hh
@@ -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:
diff --git a/src/cpu/kvm/base.cc b/src/cpu/kvm/base.cc
index d0f7515de..ab83e5d2f 100644
--- a/src/cpu/kvm/base.cc
+++ b/src/cpu/kvm/base.cc
@@ -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 *
diff --git a/src/cpu/minor/pipeline.hh b/src/cpu/minor/pipeline.hh
index 9b6ca0d32..ca96d50cb 100644
--- a/src/cpu/minor/pipeline.hh
+++ b/src/cpu/minor/pipeline.hh
@@ -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
diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc
index 091c3a6ad..c4bc13fb4 100644
--- a/src/cpu/o3/cpu.cc
+++ b/src/cpu/o3/cpu.cc
@@ -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());
diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc
index 9039e6137..eea7615c8 100644
--- a/src/cpu/simple/atomic.cc
+++ b/src/cpu/simple/atomic.cc
@@ -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();
diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc
index 783967602..62900ec78 100644
--- a/src/cpu/simple/base.cc
+++ b/src/cpu/simple/base.cc
@@ -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);
}
diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc
index f57354d56..c38f2107f 100644
--- a/src/cpu/simple/timing.cc
+++ b/src/cpu/simple/timing.cc
@@ -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();
}