summaryrefslogtreecommitdiff
path: root/src/mem/simple_dram.cc
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 /src/mem/simple_dram.cc
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.
Diffstat (limited to 'src/mem/simple_dram.cc')
-rw-r--r--src/mem/simple_dram.cc96
1 files changed, 42 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());