From e23e3bea8bc332626e026078dc8b23c983fc890f Mon Sep 17 00:00:00 2001 From: Andreas Hansson Date: Mon, 22 Apr 2013 13:20:34 -0400 Subject: mem: Address mapping with fine-grained channel interleaving 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 | 10 +++++----- src/mem/simple_dram.cc | 45 ++++++++++++++++++++++++++++++++------------- 2 files changed, 37 insertions(+), 18 deletions(-) (limited to 'src/mem') diff --git a/src/mem/SimpleDRAM.py b/src/mem/SimpleDRAM.py index 9cc56189e..e16c99e0f 100644 --- a/src/mem/SimpleDRAM.py +++ b/src/mem/SimpleDRAM.py @@ -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'] diff --git a/src/mem/simple_dram.cc b/src/mem/simple_dram.cc index bb9230e97..310530a69 100644 --- a/src/mem/simple_dram.cc +++ b/src/mem/simple_dram.cc @@ -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, -- cgit v1.2.3