From 760cc5735f48f3a5a52ebe31df0c039b23c3d611 Mon Sep 17 00:00:00 2001 From: Jose Marinho Date: Thu, 20 Jul 2017 14:57:39 +0100 Subject: [PATCH] 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 Reviewed-on: https://gem5-review.googlesource.com/5762 Maintainer: Andreas Sandberg Reviewed-by: Jason Lowe-Power --- src/cpu/base.cc | 23 ++++++++++++++-- src/cpu/base.hh | 56 ++++++++++++++++++++++++++++++++++++--- src/cpu/kvm/base.cc | 3 ++- src/cpu/minor/pipeline.hh | 7 +---- src/cpu/o3/cpu.cc | 5 ++-- src/cpu/simple/atomic.cc | 3 +-- src/cpu/simple/base.cc | 3 ++- src/cpu/simple/timing.cc | 7 ++++- 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(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(); 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 *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::tick() assert(drainState() != DrainState::Drained); ++numCycles; - ppCycles->notify(1); + updateCycleCounters(BaseCPU::CPU_STATE_ON); // activity = false; @@ -796,6 +796,8 @@ FullO3CPU::haltContext(ThreadID tid) deactivateThread(tid); removeThread(tid); + + updateCycleCounters(BaseCPU::CPU_STATE_SLEEP); } template @@ -1771,7 +1773,6 @@ FullO3CPU::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(); } -- 2.30.2