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.
This commit is contained in:
Neha Agarwal 2013-11-01 11:56:27 -04:00
parent bb572663cf
commit 77fce1ce0e
2 changed files with 48 additions and 54 deletions

View file

@ -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");
@ -878,6 +826,46 @@ SimpleDRAM::chooseNextRead()
return true;
}
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)
{

View file

@ -397,6 +397,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.