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.
This commit is contained in:
@@ -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")
|
||||
|
||||
@@ -133,8 +133,10 @@ class SimpleDRAM : public AbstractMemory
|
||||
std::deque<Tick> 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;
|
||||
|
||||
Reference in New Issue
Block a user