changeset af0028ff07db in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=af0028ff07db
description:
        mem: Add a simple adaptive version of the open-page policy

        This patch adds a basic adaptive version of the open-page policy that
        guides the decision to keep open or close by looking at the contents
        of the controller queues. If no row hits are found, and bank conflicts
        are present, then the row is closed by means of an auto
        precharge. This is a well-known technique that should improve
        performance in most use-cases.

diffstat:

 src/mem/SimpleDRAM.py  |   4 +-
 src/mem/simple_dram.cc |  53 ++++++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 49 insertions(+), 8 deletions(-)

diffs (109 lines):

diff -r 5ace73846f27 -r af0028ff07db src/mem/SimpleDRAM.py
--- a/src/mem/SimpleDRAM.py     Fri Nov 01 11:56:25 2013 -0400
+++ b/src/mem/SimpleDRAM.py     Fri Nov 01 11:56:26 2013 -0400
@@ -53,8 +53,8 @@
 # open row. For a closed-page policy, CoRaBaCh maximises parallelism.
 class AddrMap(Enum): vals = ['RaBaChCo', 'RaBaCoCh', 'CoRaBaCh']
 
-# Enum for the page policy, either open or close.
-class PageManage(Enum): vals = ['open', 'close']
+# Enum for the page policy, either open, open_adaptive or close.
+class PageManage(Enum): vals = ['open', 'open_adaptive', 'close']
 
 # SimpleDRAM is a single-channel single-ported DRAM controller model
 # that aims to model the most important system-level performance
diff -r 5ace73846f27 -r af0028ff07db src/mem/simple_dram.cc
--- a/src/mem/simple_dram.cc    Fri Nov 01 11:56:25 2013 -0400
+++ b/src/mem/simple_dram.cc    Fri Nov 01 11:56:26 2013 -0400
@@ -598,7 +598,8 @@
     string scheduler =  memSchedPolicy == Enums::fcfs ? "FCFS" : "FR-FCFS";
     string address_mapping = addrMapping == Enums::RaBaChCo ? "RaBaChCo" :
         (addrMapping == Enums::RaBaCoCh ? "RaBaCoCh" : "CoRaBaCh");
-    string page_policy = pageMgmt == Enums::open ? "OPEN" : "CLOSE";
+    string page_policy = pageMgmt == Enums::open ? "OPEN" :
+        (pageMgmt == Enums::open_adaptive ? "OPEN (adaptive)" : "CLOSE");
 
     DPRINTF(DRAM,
             "Memory controller %s characteristics\n"    \
@@ -924,7 +925,8 @@
     Tick potentialActTick;
 
     const Bank& bank = dram_pkt->bankRef;
-    if (pageMgmt == Enums::open) { // open-page policy
+     // open-page policy
+    if (pageMgmt == Enums::open || pageMgmt == Enums::open_adaptive) {
         if (bank.openRow == dram_pkt->row) {
             // When we have a row-buffer hit,
             // we don't care about tRAS having expired or not,
@@ -955,13 +957,17 @@
             if (freeTime > inTime)
                accLat += freeTime - inTime;
 
+            // If the there is no open row (open adaptive), then there
+            // is no precharge delay, otherwise go with tRP
+            Tick precharge_delay = bank.openRow == -1 ? 0 : tRP;
+
             //The bank is free, and you may be able to activate
-            potentialActTick = inTime + accLat + tRP;
+            potentialActTick = inTime + accLat + precharge_delay;
             if (potentialActTick < bank.actAllowedAt)
                 accLat += bank.actAllowedAt - potentialActTick;
 
-            accLat += tRP + tRCD + tCL;
-            bankLat += tRP + tRCD + tCL;
+            accLat += precharge_delay + tRCD + tCL;
+            bankLat += precharge_delay + tRCD + tCL;
         }
     } else if (pageMgmt == Enums::close) {
         // With a close page policy, no notion of
@@ -1067,7 +1073,7 @@
     Bank& bank = dram_pkt->bankRef;
 
     // Update bank state
-    if (pageMgmt == Enums::open) {
+    if (pageMgmt == Enums::open || pageMgmt == Enums::open_adaptive) {
         bank.openRow = dram_pkt->row;
         bank.freeAt = curTick() + addDelay + accessLat;
         bank.bytesAccessed += burstSize;
@@ -1085,6 +1091,41 @@
             bytesPerActivate.sample(bank.bytesAccessed);
             bank.bytesAccessed = 0;
         }
+
+        if (pageMgmt == Enums::open_adaptive) {
+            // a twist on the open page policy is to not blindly keep the
+            // page open, but close it if there are no row hits, and there
+            // are bank conflicts in the queue
+            bool got_more_hits = false;
+            bool got_bank_conflict = false;
+
+            // either look at the read queue or write queue
+            const deque<DRAMPacket*>& queue = dram_pkt->isRead ? readQueue :
+                writeQueue;
+            auto p = queue.begin();
+            // make sure we are not considering the packet that we are
+            // currently dealing with (which is the head of the queue)
+            ++p;
+
+            // keep on looking until we have found both or reached
+            // the end
+            while (!(got_more_hits && got_bank_conflict) &&
+                   p != queue.end()) {
+                bool same_rank_bank = (dram_pkt->rank == (*p)->rank) &&
+                    (dram_pkt->bank == (*p)->bank);
+                bool same_row = dram_pkt->row == (*p)->row;
+                got_more_hits |= same_rank_bank && same_row;
+                got_bank_conflict |= same_rank_bank && !same_row;
+                ++p;
+            }
+
+            // auto pre-charge
+            if (!got_more_hits && got_bank_conflict) {
+                bank.openRow = -1;
+                bank.freeAt = std::max(bank.freeAt, bank.tRASDoneAt) + tRP;
+            }
+        }
+
         DPRINTF(DRAM, "doDRAMAccess::bank.freeAt is %lld\n", bank.freeAt);
     } else if (pageMgmt == Enums::close) {
         actTick = curTick() + addDelay + accessLat - tRCD - tCL;
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to