From 9ed9ba480bf077b263a36f776d6dd2138193ebae Mon Sep 17 00:00:00 2001 From: Matthias Jung Date: Tue, 20 Jun 2017 17:07:25 +0200 Subject: [PATCH] Commented the FR_FCFS scheduler since the original implementation the comments are missed. I just added the comments such that anybody can understand it. --- .../src/controller/scheduler/Fr_Fcfs.cpp | 46 +++++++++++++++++-- 1 file changed, 41 insertions(+), 5 deletions(-) diff --git a/DRAMSys/simulator/src/controller/scheduler/Fr_Fcfs.cpp b/DRAMSys/simulator/src/controller/scheduler/Fr_Fcfs.cpp index a9053f94..30750c7f 100644 --- a/DRAMSys/simulator/src/controller/scheduler/Fr_Fcfs.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/Fr_Fcfs.cpp @@ -42,20 +42,43 @@ using namespace std; - +// The FR_FCFS is descibed in a 2000 paper from Rixner et al.: +// Memory Access Scheduling +// +// The FR_FCFS scheduler features for each bank in the DRAM a specific +// scheduling buffer for example: +// +// Bank0: OOOOOOOO +// Bank1: OOXXXXXX +// ... ^ ^ +// ... | | +// ... back | +// ... front +// ... +// Bank6: OOOOO0XX +// Bank7: XXXXXXXX void FR_FCFS::schedule(gp *payload) { - buffer[DramExtension::getExtension(payload).getBank()].emplace_back(payload); + + // FIXME: Question: what if the buffer is full? IMHO the schedule function + // should provide a true or false when the placement into the buffer worked + // out or not (?). + buffer[DramExtension::getExtension(payload).getBank()] + .emplace_back(payload); } std::pair FR_FCFS::getNextRequest(Bank bank) { + // If the bank is empty like Bank0 in the example we do nothing if(buffer[bank].empty()) { return pair(Command::NOP, NULL); } + // In FR_FCFS row hits have always the highest priority, therefore we search + // for row hits. If we find a row hit, we remove the transaction from the + // queue and send it to the DRAM. deque::iterator it = FindRowHit(bank); if(it != buffer[bank].end()) { @@ -64,9 +87,19 @@ std::pair FR_FCFS::getNextRequest(Bank bank) return pair(getReadWriteCommand(*payload), payload); } - return pair(getNextCommand(buffer[bank].front()), buffer[bank].front()); + // If there is no row hit, the FR_FCFS takes always the oldest transaction + // in the buffer, i.e. the transaction in the front. + return pair(getNextCommand(buffer[bank].front()), + buffer[bank].front()); } +// This function searches for a row hit in the scheduling queue of the specific +// bank. If no row hit is found the end of the queue is returned. +// +// Note: end() Returns an iterator referring to the past-the-end element in the +// deque container. The past-the-end element is the theoretical element that +// would follow the last element in the deque container. It does not point to +// any element, and thus shall not be dereferenced. deque::iterator FR_FCFS::FindRowHit(Bank bank) { deque &queue = buffer[bank]; @@ -74,14 +107,17 @@ deque::iterator FR_FCFS::FindRowHit(Bank bank) if(!controllerCore.getRowBufferStates().rowBufferIsOpen(bank)) return queue.end(); + // Traverse the scheduling queue of the specific bank: for(auto it = queue.begin(); it!=queue.end(); it++) { gp* payload = *it; - //Found row-hit - if(DramExtension::getRow(payload) == controllerCore.getRowBufferStates().getRowInRowBuffer(bank)) + //Found row-hit and return the according iterator + if(DramExtension::getRow(payload) + == controllerCore.getRowBufferStates().getRowInRowBuffer(bank)) { return it; } } + return queue.end(); }