From 83d99aebb1dcbe015e752fd74e9cd5c6b5ea0380 Mon Sep 17 00:00:00 2001 From: Andreas Hansson Date: Thu, 30 May 2013 12:54:13 -0400 Subject: [PATCH] mem: Add bytes per activate DRAM controller stat This patch adds a histogram to track how many bytes are accessed in an open row before it is closed. This metric is useful in characterising a workload and the efficiency of the DRAM scheduler. For example, a DDR3-1600 device requires 44 cycles (tRC) before it can activate another row in the same bank. For a x32 interface (8 bytes per cycle) that means 8 x 44 = 352 bytes must be transferred to hide the preparation time. --- src/mem/simple_dram.cc | 19 +++++++++++++++++++ src/mem/simple_dram.hh | 13 +++++++++---- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/mem/simple_dram.cc b/src/mem/simple_dram.cc index c54947438..bd3a70d25 100644 --- a/src/mem/simple_dram.cc +++ b/src/mem/simple_dram.cc @@ -363,11 +363,17 @@ SimpleDRAM::processWriteEvent() bank.openRow = dram_pkt->row; bank.freeAt = schedTime + tBURST + std::max(accessLat, tCL); busBusyUntil = bank.freeAt - tCL; + bank.bytesAccessed += bytesPerCacheLine; if (!rowHitFlag) { bank.tRASDoneAt = bank.freeAt + tRP; recordActivate(bank.freeAt - tCL - tRCD); busBusyUntil = bank.freeAt - tCL - tRCD; + + // sample the number of bytes accessed and reset it as + // we are now closing this row + bytesPerActivate.sample(bank.bytesAccessed); + bank.bytesAccessed = 0; } } else if (pageMgmt == Enums::close) { bank.freeAt = schedTime + tBURST + accessLat + tRP + tRP; @@ -378,6 +384,7 @@ SimpleDRAM::processWriteEvent() "banks_id %d is %lld\n", dram_pkt->rank * banksPerRank + dram_pkt->bank, bank.freeAt); + bytesPerActivate.sample(bytesPerCacheLine); } else panic("Unknown page management policy chosen\n"); @@ -898,6 +905,8 @@ SimpleDRAM::doDRAMAccess(DRAMPacket* dram_pkt) if (pageMgmt == Enums::open) { bank.openRow = dram_pkt->row; bank.freeAt = curTick() + addDelay + accessLat; + bank.bytesAccessed += bytesPerCacheLine; + // If you activated a new row do to this access, the next access // will have to respect tRAS for this bank. Assume tRAS ~= 3 * tRP. // Also need to account for t_XAW @@ -905,6 +914,10 @@ SimpleDRAM::doDRAMAccess(DRAMPacket* dram_pkt) bank.tRASDoneAt = bank.freeAt + tRP; recordActivate(bank.freeAt - tCL - tRCD); //since this is open page, //no tRP by default + // sample the number of bytes accessed and reset it as + // we are now closing this row + bytesPerActivate.sample(bank.bytesAccessed); + bank.bytesAccessed = 0; } } else if (pageMgmt == Enums::close) { // accounting for tRAS also // assuming that tRAS ~= 3 * tRP, and tRC ~= 4 * tRP, as is common @@ -912,6 +925,7 @@ SimpleDRAM::doDRAMAccess(DRAMPacket* dram_pkt) bank.freeAt = curTick() + addDelay + accessLat + tRP + tRP; recordActivate(bank.freeAt - tRP - tRP - tCL - tRCD); //essentially (freeAt - tRC) DPRINTF(DRAM,"doDRAMAccess::bank.freeAt is %lld\n",bank.freeAt); + bytesPerActivate.sample(bytesPerCacheLine); } else panic("No page management policy chosen\n"); @@ -1192,6 +1206,11 @@ SimpleDRAM::regStats() .name(name() + ".wrQLenPdf") .desc("What write queue length does an incoming req see"); + bytesPerActivate + .init(bytesPerCacheLine * linesPerRowBuffer) + .name(name() + ".bytesPerActivate") + .desc("Bytes accessed per row activation") + .flags(nozero); bytesRead .name(name() + ".bytesRead") diff --git a/src/mem/simple_dram.hh b/src/mem/simple_dram.hh index 920dcf33a..e4d20163a 100644 --- a/src/mem/simple_dram.hh +++ b/src/mem/simple_dram.hh @@ -133,8 +133,10 @@ class SimpleDRAM : public AbstractMemory std::deque actTicks; /** - * A basic class to track the bank state indirectly via - * times "freeAt" and "tRASDoneAt" and what page is currently open + * A basic class to track the bank state indirectly via times + * "freeAt" and "tRASDoneAt" and what page is currently open. The + * bank also keeps track of how many bytes have been accessed in + * the open row since it was opened. */ class Bank { @@ -148,7 +150,10 @@ class SimpleDRAM : public AbstractMemory Tick freeAt; Tick tRASDoneAt; - Bank() : openRow(INVALID_ROW), freeAt(0), tRASDoneAt(0) + uint32_t bytesAccessed; + + Bank() : + openRow(INVALID_ROW), freeAt(0), tRASDoneAt(0), bytesAccessed(0) { } }; @@ -452,7 +457,7 @@ class SimpleDRAM : public AbstractMemory Stats::Vector writePktSize; Stats::Vector rdQLenPdf; Stats::Vector wrQLenPdf; - + Stats::Histogram bytesPerActivate; // Latencies summed over all requests Stats::Scalar totQLat; -- 2.30.2