mem: Option to toggle DRAM low-power states
authorMatthew Poremba <matthew.poremba@amd.com>
Wed, 1 May 2019 18:32:49 +0000 (11:32 -0700)
committerMatthew Poremba <matthew.poremba@amd.com>
Thu, 6 Jun 2019 19:55:38 +0000 (19:55 +0000)
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>
configs/common/MemConfig.py
configs/common/Options.py
configs/ruby/Ruby.py
src/mem/DRAMCtrl.py
src/mem/dram_ctrl.cc
src/mem/dram_ctrl.hh

index 29c41388ca35b3e3eb943c9b878dbe9f0930c5f5..d09869285854f50b60344c10bc6245b63692783d 100644 (file)
@@ -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 "
index 4279b80061912d6a77ea95b3230368759b035fd0..f6fa0d031987f46d045b6482393fc80b02fe458a 100644 (file)
@@ -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")
index 2d69ac19a91ee45ab6e782263ccf2b6d956777ce..c9ae251d91a995288b5128cd63b9fe5de147a9e1 100644 (file)
@@ -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
 
index 93ea7d56fdc9be2e5d74c5d9b505444303eb94f9..14db3d3c9d7bc775345a70a1a69c6dae8a728ab9 100644 (file)
@@ -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")
 
index 08465aa70b4a908929e0243aab22f0e93d7dc080..06c540ba6faa34e3b219c629bb7b4cc59400254b 100644 (file)
@@ -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());
index 54826e0a882a9e3eb5325a1140996da41f05109a..7de0872ea3298ebda51cc12a81a43cc106910059 100644 (file)
@@ -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