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>
This commit is contained in:
committed by
Andreas Sandberg
parent
00232a868e
commit
760cc5735f
@@ -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();
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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 *
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user