mem: Address mapping with fine-grained channel interleaving
authorAndreas Hansson <andreas.hansson@arm.com>
Mon, 22 Apr 2013 17:20:34 +0000 (13:20 -0400)
committerAndreas Hansson <andreas.hansson@arm.com>
Mon, 22 Apr 2013 17:20:34 +0000 (13:20 -0400)
This patch adds an address mapping scheme where the channel
interleaving takes place on a cache line granularity. It is similar to
the existing RaBaChCo that interleaves on a DRAM page, but should give
higher performance when there is less locality in the address
stream.

src/mem/SimpleDRAM.py
src/mem/simple_dram.cc

index 9cc56189e676b6fe570e653e5516900e6d6b0861..e16c99e0fc611e574a19c1e239bfed884f4790e7 100644 (file)
@@ -44,11 +44,11 @@ from AbstractMemory import *
 class MemSched(Enum): vals = ['fcfs', 'frfcfs']
 
 # Enum for the address mapping. With Ra, Co, Ba and Ch denoting rank,
-# column, bank and channel, respectively, and going from MSB to LSB,
-# the two schemes available are RaBaChCo and CoRaBaCh, either
-# optimising for sequential accesses hitting in the open row, or
-# maximising parallelism.
-class AddrMap(Enum): vals = ['RaBaChCo', 'CoRaBaCh']
+# column, bank and channel, respectively, and going from MSB to LSB.
+# Available are RaBaChCo and RaBaCoCh, that are suitable for an
+# open-page policy, optimising for sequential accesses hitting in the
+# 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']
index bb9230e97000eed7ad4f2ccc13f0ad4230d63b34..310530a692625ed3a5290fb4f8dcfa61ed970d28 100644 (file)
@@ -118,6 +118,11 @@ SimpleDRAM::init()
                 panic("Interleaving of %s doesn't match RaBaChCo address map\n",
                       name());
             }
+        } else if (addrMapping == Enums::RaBaCoCh) {
+            if (bytesPerCacheLine != range.granularity()) {
+                panic("Interleaving of %s doesn't match RaBaCoCh address map\n",
+                      name());
+            }
         } else if (addrMapping == Enums::CoRaBaCh) {
             if (bytesPerCacheLine != range.granularity())
                 panic("Interleaving of %s doesn't match CoRaBaCh address map\n",
@@ -173,11 +178,9 @@ SimpleDRAM::writeQueueFull() const
 SimpleDRAM::DRAMPacket*
 SimpleDRAM::decodeAddr(PacketPtr pkt)
 {
-    // decode the address based on the address mapping scheme
-    //
-    // with Ra, Co, Ba and Ch denoting rank, column, bank and channel,
-    // respectively, and going from MSB to LSB, the two schemes are
-    // RaBaChCo and CoRaBaCh
+    // decode the address based on the address mapping scheme, with
+    // Ra, Co, Ba and Ch denoting rank, column, bank and channel,
+    // respectively
     uint8_t rank;
     uint16_t bank;
     uint16_t row;
@@ -188,20 +191,36 @@ SimpleDRAM::decodeAddr(PacketPtr pkt)
     addr = addr / bytesPerCacheLine;
 
     // we have removed the lowest order address bits that denote the
-    // position within the cache line, proceed and select the
-    // appropriate bits for bank, rank and row (no column address is
-    // needed)
+    // position within the cache line
     if (addrMapping == Enums::RaBaChCo) {
         // the lowest order bits denote the column to ensure that
         // sequential cache lines occupy the same row
         addr = addr / linesPerRowBuffer;
 
-        // take out the channel part of the address, note that this has
-        // to match with how accesses are interleaved between the
-        // controllers in the address mapping
+        // take out the channel part of the address
+        addr = addr / channels;
+
+        // after the channel bits, get the bank bits to interleave
+        // over the banks
+        bank = addr % banksPerRank;
+        addr = addr / banksPerRank;
+
+        // after the bank, we get the rank bits which thus interleaves
+        // over the ranks
+        rank = addr % ranksPerChannel;
+        addr = addr / ranksPerChannel;
+
+        // lastly, get the row bits
+        row = addr % rowsPerBank;
+        addr = addr / rowsPerBank;
+    } else if (addrMapping == Enums::RaBaCoCh) {
+        // take out the channel part of the address
         addr = addr / channels;
 
-        // after the channel bits, we get the bank bits to interleave
+        // next, the column
+        addr = addr / linesPerRowBuffer;
+
+        // after the column bits, we get the bank bits to interleave
         // over the banks
         bank = addr % banksPerRank;
         addr = addr / banksPerRank;
@@ -474,7 +493,7 @@ SimpleDRAM::printParams() const
 
     string scheduler =  memSchedPolicy == Enums::fcfs ? "FCFS" : "FR-FCFS";
     string address_mapping = addrMapping == Enums::RaBaChCo ? "RaBaChCo" :
-        "CoRaBaCh";
+        (addrMapping == Enums::RaBaCoCh ? "RaBaCoCh" : "CoRaBaCh");
     string page_policy = pageMgmt == Enums::open ? "OPEN" : "CLOSE";
 
     DPRINTF(DRAM,