diff options
author | Neha Agarwal <neha.agarwal@arm.com> | 2013-11-01 11:56:27 -0400 |
---|---|---|
committer | Neha Agarwal <neha.agarwal@arm.com> | 2013-11-01 11:56:27 -0400 |
commit | 77fce1ce0e1db502b47ea72c4243c929666d04fa (patch) | |
tree | ec65bb9c33ec6b6090b8ce65a5c7a9d5771249a5 /src/mem | |
parent | bb572663cf1ba802492743f1196eb9eac4c20bea (diff) | |
download | gem5-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')
-rw-r--r-- | src/mem/simple_dram.cc | 96 | ||||
-rw-r--r-- | src/mem/simple_dram.hh | 6 |
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. * |