mem: Option to toggle DRAM low-power states
Adding an option to enable DRAM low-power states. The low power states can have a significant impact on application performance (sim_ticks) on the order of 2-3x, especially for compute-gpu apps. The options allows for it to easily be enabled/disabled to compare performance numbers. The option is disabled by default. Change-Id: Ib9bddbb792a1a6a4afb5339003472ff8f00a5859 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/18548 Reviewed-by: Wendy Elsasser <wendy.elsasser@arm.com> Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com> Maintainer: Jason Lowe-Power <jason@lowepower.com> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
@@ -224,6 +224,11 @@ def config_mem(options, system):
|
||||
if issubclass(cls, m5.objects.DRAMCtrl) and opt_mem_ranks:
|
||||
mem_ctrl.ranks_per_channel = opt_mem_ranks
|
||||
|
||||
# Enable low-power DRAM states if option is set
|
||||
if issubclass(cls, m5.objects.DRAMCtrl):
|
||||
mem_ctrl.enable_dram_powerdown = \
|
||||
options.enable_dram_powerdown
|
||||
|
||||
if opt_elastic_trace_en:
|
||||
mem_ctrl.latency = '1ns'
|
||||
print("For elastic trace, over-riding Simple Memory "
|
||||
|
||||
@@ -104,6 +104,8 @@ def addNoISAOptions(parser):
|
||||
parser.add_option("--mem-size", action="store", type="string",
|
||||
default="512MB",
|
||||
help="Specify the physical memory size (single memory)")
|
||||
parser.add_option("--enable-dram-powerdown", action="store_true",
|
||||
help="Enable low-power states in DRAMCtrl")
|
||||
|
||||
|
||||
parser.add_option("--memchecker", action="store_true")
|
||||
|
||||
@@ -130,6 +130,11 @@ def setup_memory_controllers(system, ruby, dir_cntrls, options):
|
||||
else:
|
||||
mem_ctrl.port = dir_cntrl.memory
|
||||
|
||||
# Enable low-power DRAM states if option is set
|
||||
if issubclass(MemConfig.get(options.mem_type), DRAMCtrl):
|
||||
mem_ctrl.enable_dram_powerdown = \
|
||||
options.enable_dram_powerdown
|
||||
|
||||
index += 1
|
||||
dir_cntrl.addr_ranges = dir_ranges
|
||||
|
||||
|
||||
@@ -135,6 +135,10 @@ class DRAMCtrl(QoSMemCtrl):
|
||||
# to be instantiated for a multi-channel configuration
|
||||
channels = Param.Unsigned(1, "Number of channels")
|
||||
|
||||
# Enable DRAM powerdown states if True. This is False by default due to
|
||||
# performance being lower when enabled
|
||||
enable_dram_powerdown = Param.Bool(False, "Enable powerdown states")
|
||||
|
||||
# For power modelling we need to know if the DRAM has a DLL or not
|
||||
dll = Param.Bool(True, "DRAM has DLL or not")
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ DRAMCtrl::DRAMCtrl(const DRAMCtrlParams* p) :
|
||||
backendLatency(p->static_backend_latency),
|
||||
nextBurstAt(0), prevArrival(0),
|
||||
nextReqTime(0), activeRank(0), timeStampOffset(0),
|
||||
lastStatsResetTick(0)
|
||||
lastStatsResetTick(0), enableDRAMPowerdown(p->enable_dram_powerdown)
|
||||
{
|
||||
// sanity check the ranks since we rely on bit slicing for the
|
||||
// address decoding
|
||||
@@ -705,7 +705,7 @@ DRAMCtrl::processRespondEvent()
|
||||
// track if this is the last packet before idling
|
||||
// and that there are no outstanding commands to this rank
|
||||
if (dram_pkt->rankRef.isQueueEmpty() &&
|
||||
dram_pkt->rankRef.outstandingEvents == 0) {
|
||||
dram_pkt->rankRef.outstandingEvents == 0 && enableDRAMPowerdown) {
|
||||
// verify that there are no events scheduled
|
||||
assert(!dram_pkt->rankRef.activateEvent.scheduled());
|
||||
assert(!dram_pkt->rankRef.prechargeEvent.scheduled());
|
||||
@@ -1856,7 +1856,8 @@ DRAMCtrl::Rank::processPrechargeEvent()
|
||||
if (numBanksActive == 0) {
|
||||
// no reads to this rank in the Q and no pending
|
||||
// RD/WR or refresh commands
|
||||
if (isQueueEmpty() && outstandingEvents == 0) {
|
||||
if (isQueueEmpty() && outstandingEvents == 0 &&
|
||||
memory.enableDRAMPowerdown) {
|
||||
// should still be in ACT state since bank still open
|
||||
assert(pwrState == PWR_ACT);
|
||||
|
||||
@@ -2057,7 +2058,7 @@ DRAMCtrl::Rank::processRefreshEvent()
|
||||
|
||||
// Force PRE power-down if there are no outstanding commands
|
||||
// in Q after refresh.
|
||||
} else if (isQueueEmpty()) {
|
||||
} else if (isQueueEmpty() && memory.enableDRAMPowerdown) {
|
||||
// still have refresh event outstanding but there should
|
||||
// be no other events outstanding
|
||||
assert(outstandingEvents == 1);
|
||||
@@ -2328,7 +2329,8 @@ DRAMCtrl::Rank::processPowerEvent()
|
||||
// will issue refresh immediately upon entry
|
||||
if (pwrStatePostRefresh == PWR_PRE_PDN && isQueueEmpty() &&
|
||||
(memory.drainState() != DrainState::Draining) &&
|
||||
(memory.drainState() != DrainState::Drained)) {
|
||||
(memory.drainState() != DrainState::Drained) &&
|
||||
memory.enableDRAMPowerdown) {
|
||||
DPRINTF(DRAMState, "Rank %d bypassing refresh and transitioning "
|
||||
"to self refresh at %11u tick\n", rank, curTick());
|
||||
powerDownSleep(PWR_SREF, curTick());
|
||||
|
||||
@@ -1140,6 +1140,9 @@ class DRAMCtrl : public QoS::MemCtrl
|
||||
/** The time when stats were last reset used to calculate average power */
|
||||
Tick lastStatsResetTick;
|
||||
|
||||
/** Enable or disable DRAM powerdown states. */
|
||||
bool enableDRAMPowerdown;
|
||||
|
||||
/**
|
||||
* Upstream caches need this packet until true is returned, so
|
||||
* hold it for deletion until a subsequent call
|
||||
|
||||
Reference in New Issue
Block a user