Hello Andreas Sandberg,
I'd like you to do a code review. Please visit
https://gem5-review.googlesource.com/3969
to review the following change.
Change subject: pwr: Adds logic to enter power gating for the cpu model
......................................................................
pwr: Adds logic to enter power gating for the cpu model
If the CPU has been clock gated for a sufficient amount of time
(configurable via pwrGatingLatency), the CPU will go into the OFF
power state. This does not model hardware, just behaviour.
Change-Id: Ib3681d1ffa6ad25eba60f47b4020325f63472d43
Reviewed-by: Andreas Sandberg <[email protected]>
---
M src/cpu/BaseCPU.py
M src/cpu/base.cc
M src/cpu/base.hh
M src/cpu/minor/cpu.cc
M src/cpu/o3/cpu.cc
M src/cpu/simple/atomic.cc
M src/cpu/simple/timing.cc
7 files changed, 94 insertions(+), 8 deletions(-)
diff --git a/src/cpu/BaseCPU.py b/src/cpu/BaseCPU.py
index 550ba62..d7f2d99 100644
--- a/src/cpu/BaseCPU.py
+++ b/src/cpu/BaseCPU.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2012-2013, 2015 ARM Limited
+# Copyright (c) 2012-2013, 2015-2017 ARM Limited
# All rights reserved.
#
# The license below extends only to copyright in the software and shall
@@ -135,6 +135,8 @@
cpu_id = Param.Int(-1, "CPU identifier")
socket_id = Param.Unsigned(0, "Physical Socket identifier")
numThreads = Param.Unsigned(1, "number of HW thread contexts")
+ pwr_gating_latency = Param.Cycles(300,
+ "Latency to enter power gating state when all contexts are
suspended")
function_trace = Param.Bool(False, "Enable function trace")
function_trace_start = Param.Tick(0, "Tick to start function trace")
diff --git a/src/cpu/base.cc b/src/cpu/base.cc
index 6f460d3..3fd44f7 100644
--- a/src/cpu/base.cc
+++ b/src/cpu/base.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2012,2016 ARM Limited
+ * Copyright (c) 2011-2012,2016-2017 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -136,7 +136,8 @@
functionTraceStream(nullptr), currentFunctionStart(0),
currentFunctionEnd(0), functionEntryTick(0),
addressMonitor(p->numThreads),
- syscallRetryLatency(p->syscallRetryLatency)
+ syscallRetryLatency(p->syscallRetryLatency),
+ pwrGatingLatency(p->pwr_gating_latency), enterPwrGatingEvent(this)
{
// if Python did not provide a valid ID, do it here
if (_cpuId == -1 ) {
@@ -359,6 +360,9 @@
new CPUProgressEvent(this, params()->progress_interval);
}
+ if (_switchedOut)
+ ClockedObject::pwrState(Enums::PwrState::OFF);
+
// Assumption CPU start to operate instantaneously without any latency
if (ClockedObject::pwrState() == Enums::PwrState::UNDEFINED)
ClockedObject::pwrState(Enums::PwrState::ON);
@@ -470,6 +474,33 @@
}
}
+void
+BaseCPU::deschedulePowerGatingEvent()
+{
+ if (enterPwrGatingEvent.scheduled()){
+ deschedule(enterPwrGatingEvent);
+ }
+}
+
+void
+BaseCPU::schedulePowerGatingEvent()
+{
+ bool active_threads = false;
+ for (auto tc : threadContexts) {
+ if (tc->status() == ThreadContext::Active){
+ active_threads = true;
+ break;
+ }
+ }
+
+ if (ClockedObject::pwrState() == Enums::PwrState::CLK_GATED
+ && !active_threads) {
+ assert(!enterPwrGatingEvent.scheduled());
+ // Schedule a power gating event when clock gated for the specified
+ // amount of time
+ schedule(enterPwrGatingEvent, clockEdge(pwrGatingLatency));
+ }
+}
int
BaseCPU::findContext(ThreadContext *tc)
@@ -485,6 +516,10 @@
void
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);
}
@@ -501,6 +536,15 @@
// All CPU threads suspended, enter lower power state for the CPU
ClockedObject::pwrState(Enums::PwrState::CLK_GATED);
+
+ //Schedule power gating event when clock gated for a configurable
cycles
+ schedule(enterPwrGatingEvent, clockEdge(pwrGatingLatency));
+}
+
+void
+BaseCPU::enterPwrGating(void)
+{
+ ClockedObject::pwrState(Enums::PwrState::OFF);
}
void
@@ -514,6 +558,9 @@
// Flush all TLBs in the CPU to avoid having stale translations if
// it gets switched in later.
flushTLBs();
+
+ // Go to the power gating state
+ ClockedObject::pwrState(Enums::PwrState::OFF);
}
void
@@ -525,6 +572,8 @@
assert(oldCPU != this);
_pid = oldCPU->getPid();
_taskId = oldCPU->taskId();
+ // Take over the power state of the switchedOut CPU
+ ClockedObject::pwrState(oldCPU->pwrState());
_switchedOut = false;
ThreadID size = threadContexts.size();
diff --git a/src/cpu/base.hh b/src/cpu/base.hh
index 14dfc26..9f6199e 100644
--- a/src/cpu/base.hh
+++ b/src/cpu/base.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2013 ARM Limited
+ * Copyright (c) 2011-2013, 2017 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -316,6 +316,11 @@
void registerThreadContexts();
+ // Functions to deschedule and reschedule the events to enter the
+ // power gating sleep before and after checkpoiting respectively.
+ void deschedulePowerGatingEvent();
+ void schedulePowerGatingEvent();
+
/**
* Prepare for another CPU to take over execution.
*
@@ -590,6 +595,11 @@
}
Cycles syscallRetryLatency;
+ // Enables CPU to enter power gating on a configurable cycle count
+ protected:
+ const Cycles pwrGatingLatency;
+ void enterPwrGating();
+ EventWrapper<BaseCPU, &BaseCPU::enterPwrGating> enterPwrGatingEvent;
};
#endif // THE_ISA == NULL_ISA
diff --git a/src/cpu/minor/cpu.cc b/src/cpu/minor/cpu.cc
index ae4fda6..48a0205 100644
--- a/src/cpu/minor/cpu.cc
+++ b/src/cpu/minor/cpu.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2014 ARM Limited
+ * Copyright (c) 2012-2014, 2017 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -195,6 +195,9 @@
DrainState
MinorCPU::drain()
{
+ // Deschedule any power gating event (if any)
+ BaseCPU::deschedulePowerGatingEvent();
+
if (switchedOut()) {
DPRINTF(Drain, "Minor CPU switched out, draining not needed.\n");
return DrainState::Drained;
@@ -240,10 +243,14 @@
"'timing' mode.\n");
}
- for (ThreadID tid = 0; tid < numThreads; tid++)
+ for (ThreadID tid = 0; tid < numThreads; tid++){
wakeup(tid);
+ }
pipeline->drainResume();
+
+ // Reschedule any power gating event (if any)
+ BaseCPU::schedulePowerGatingEvent();
}
void
diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc
index c249d90..8146c68 100644
--- a/src/cpu/o3/cpu.cc
+++ b/src/cpu/o3/cpu.cc
@@ -1050,6 +1050,9 @@
DrainState
FullO3CPU<Impl>::drain()
{
+ // Deschedule any power gating event (if any)
+ BaseCPU::deschedulePowerGatingEvent();
+
// If the CPU isn't doing anything, then return immediately.
if (switchedOut())
return DrainState::Drained;
@@ -1194,6 +1197,9 @@
assert(!tickEvent.scheduled());
if (_status == Running)
schedule(tickEvent, nextCycle());
+
+ // Reschedule any power gating event (if any)
+ BaseCPU::schedulePowerGatingEvent();
}
template <class Impl>
diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc
index 6c31f1d..2487215 100644
--- a/src/cpu/simple/atomic.cc
+++ b/src/cpu/simple/atomic.cc
@@ -1,6 +1,6 @@
/*
* Copyright 2014 Google, Inc.
- * Copyright (c) 2012-2013,2015 ARM Limited
+ * Copyright (c) 2012-2013,2015,2017 ARM Limited
* All rights reserved.
*
* The license below extends only to copyright in the software and shall
@@ -116,6 +116,9 @@
DrainState
AtomicSimpleCPU::drain()
{
+ // Deschedule any power gating event (if any)
+ BaseCPU::deschedulePowerGatingEvent();
+
if (switchedOut())
return DrainState::Drained;
@@ -178,6 +181,9 @@
threadInfo[tid]->notIdleFraction = 0;
}
}
+
+ // Reschedule any power gating event (if any)
+ BaseCPU::schedulePowerGatingEvent();
}
bool
diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc
index d2cb6ee..60d82fb 100644
--- a/src/cpu/simple/timing.cc
+++ b/src/cpu/simple/timing.cc
@@ -1,6 +1,6 @@
/*
* Copyright 2014 Google, Inc.
- * Copyright (c) 2010-2013,2015 ARM Limited
+ * Copyright (c) 2010-2013,2015,2017 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -94,6 +94,9 @@
DrainState
TimingSimpleCPU::drain()
{
+ // Deschedule any power gating event (if any)
+ BaseCPU::deschedulePowerGatingEvent();
+
if (switchedOut())
return DrainState::Drained;
@@ -146,6 +149,9 @@
}
}
+ // Reschedule any power gating event (if any)
+ BaseCPU::schedulePowerGatingEvent();
+
system->totalNumInsts = 0;
}
--
To view, visit https://gem5-review.googlesource.com/3969
To unsubscribe, visit https://gem5-review.googlesource.com/settings
Gerrit-Project: public/gem5
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ib3681d1ffa6ad25eba60f47b4020325f63472d43
Gerrit-Change-Number: 3969
Gerrit-PatchSet: 1
Gerrit-Owner: Anouk Van Laer <[email protected]>
Gerrit-Reviewer: Andreas Sandberg <[email protected]>
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev