summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeha Agarwal <neha.agarwal@arm.com>2013-11-01 11:56:27 -0400
committerNeha Agarwal <neha.agarwal@arm.com>2013-11-01 11:56:27 -0400
commit77fce1ce0e1db502b47ea72c4243c929666d04fa (patch)
treeec65bb9c33ec6b6090b8ce65a5c7a9d5771249a5
parentbb572663cf1ba802492743f1196eb9eac4c20bea (diff)
downloadgem5-77fce1ce0e1db502b47ea72c4243c929666d04fa.tar.xz
mem: Unify request selection for read and write queues
This patch unifies the request selection across read and write queues for FR-FCFS scheduling policy. It also fixes the request selection code to prioritize the row hits present in the request queues over the selection based on earliest bank availability.
-rw-r--r--src/mem/simple_dram.cc96
-rw-r--r--src/mem/simple_dram.hh6
2 files changed, 48 insertions, 54 deletions
diff --git a/src/mem/simple_dram.cc b/src/mem/simple_dram.cc
index 69209fb8a..46e81f564 100644
--- a/src/mem/simple_dram.cc
+++ b/src/mem/simple_dram.cc
@@ -791,34 +791,7 @@ SimpleDRAM::chooseNextWrite()
if (memSchedPolicy == Enums::fcfs) {
// Do nothing, since the correct request is already head
} else if (memSchedPolicy == Enums::frfcfs) {
- // Only determine bank availability when needed
- uint64_t earliest_banks = 0;
-
- auto i = writeQueue.begin();
- bool foundRowHit = false;
- while (!foundRowHit && i != writeQueue.end()) {
- DRAMPacket* dram_pkt = *i;
- const Bank& bank = dram_pkt->bankRef;
- if (bank.openRow == dram_pkt->row) {
- DPRINTF(DRAM, "Write row buffer hit\n");
- writeQueue.erase(i);
- writeQueue.push_front(dram_pkt);
- foundRowHit = true;
- } else {
- // No row hit, go for first ready
- if (earliest_banks == 0)
- earliest_banks = minBankFreeAt(writeQueue);
-
- // Bank is ready or is one of the first available bank
- if (bank.freeAt <= curTick() ||
- bits(earliest_banks, dram_pkt->bankId, dram_pkt->bankId)) {
- writeQueue.erase(i);
- writeQueue.push_front(dram_pkt);
- break;
- }
- }
- ++i;
- }
+ reorderQueue(writeQueue);
} else
panic("No scheduling policy chosen\n");
@@ -845,32 +818,7 @@ SimpleDRAM::chooseNextRead()
// Do nothing, since the request to serve is already the first
// one in the read queue
} else if (memSchedPolicy == Enums::frfcfs) {
- // Only determine this when needed
- uint64_t earliest_banks = 0;
-
- for (auto i = readQueue.begin(); i != readQueue.end() ; ++i) {
- DRAMPacket* dram_pkt = *i;
- const Bank& bank = dram_pkt->bankRef;
- // Check if it is a row hit
- if (bank.openRow == dram_pkt->row) {
- DPRINTF(DRAM, "Row buffer hit\n");
- readQueue.erase(i);
- readQueue.push_front(dram_pkt);
- break;
- } else {
- // No row hit, go for first ready
- if (earliest_banks == 0)
- earliest_banks = minBankFreeAt(readQueue);
-
- // Bank is ready or is the first available bank
- if (bank.freeAt <= curTick() ||
- bits(earliest_banks, dram_pkt->bankId, dram_pkt->bankId)) {
- readQueue.erase(i);
- readQueue.push_front(dram_pkt);
- break;
- }
- }
- }
+ reorderQueue(readQueue);
} else
panic("No scheduling policy chosen!\n");
@@ -879,6 +827,46 @@ SimpleDRAM::chooseNextRead()
}
void
+SimpleDRAM::reorderQueue(std::deque<DRAMPacket*>& queue)
+{
+ // Only determine this when needed
+ uint64_t earliest_banks = 0;
+
+ // Search for row hits first, if no row hit is found then schedule the
+ // packet to one of the earliest banks available
+ bool found_earliest_pkt = false;
+ auto selected_pkt_it = queue.begin();
+
+ for (auto i = queue.begin(); i != queue.end() ; ++i) {
+ DRAMPacket* dram_pkt = *i;
+ const Bank& bank = dram_pkt->bankRef;
+ // Check if it is a row hit
+ if (bank.openRow == dram_pkt->row) {
+ DPRINTF(DRAM, "Row buffer hit\n");
+ selected_pkt_it = i;
+ break;
+ } else if (!found_earliest_pkt) {
+ // No row hit, go for first ready
+ if (earliest_banks == 0)
+ earliest_banks = minBankFreeAt(queue);
+
+ // Bank is ready or is the first available bank
+ if (bank.freeAt <= curTick() ||
+ bits(earliest_banks, dram_pkt->bankId, dram_pkt->bankId)) {
+ // Remember the packet to be scheduled to one of the earliest
+ // banks available
+ selected_pkt_it = i;
+ found_earliest_pkt = true;
+ }
+ }
+ }
+
+ DRAMPacket* selected_pkt = *selected_pkt_it;
+ queue.erase(selected_pkt_it);
+ queue.push_front(selected_pkt);
+}
+
+void
SimpleDRAM::accessAndRespond(PacketPtr pkt, Tick static_latency)
{
DPRINTF(DRAM, "Responding to Address %lld.. ",pkt->getAddr());
diff --git a/src/mem/simple_dram.hh b/src/mem/simple_dram.hh
index a7a100d7c..535e3a8c5 100644
--- a/src/mem/simple_dram.hh
+++ b/src/mem/simple_dram.hh
@@ -398,6 +398,12 @@ class SimpleDRAM : public AbstractMemory
void chooseNextWrite();
/**
+ * For FR-FCFS policy reorder the read/write queue depending on row buffer
+ * hits and earliest banks available in DRAM
+ */
+ void reorderQueue(std::deque<DRAMPacket*>& queue);
+
+ /**
* Looking at all banks, determine the moment in time when they
* are all free.
*