diff --git a/DRAMSys/simulator/library.pro b/DRAMSys/simulator/library.pro index fcbdeb0a..a81a8976 100644 --- a/DRAMSys/simulator/library.pro +++ b/DRAMSys/simulator/library.pro @@ -118,7 +118,8 @@ SOURCES += \ src/error/ECC/Word.cpp \ src/error/eccbaseclass.cpp \ src/error/ecchamming.cpp \ - src/controller/scheduler/Fr_Fcfs_read_priority.cpp + src/controller/scheduler/Fr_Fcfs_read_priority.cpp \ + src/controller/scheduler/Fr_Fcfs_grouper.cpp HEADERS += \ src/common/third_party/tinyxml2/tinyxml2.h \ @@ -188,7 +189,8 @@ HEADERS += \ src/error/ECC/Word.h \ src/error/eccbaseclass.h \ src/error/ecchamming.h \ - src/controller/scheduler/Fr_Fcfs_read_priority.h + src/controller/scheduler/Fr_Fcfs_read_priority.h \ + src/controller/scheduler/Fr_Fcfs_grouper.h thermalsim = $$(THERMALSIM) isEmpty(thermalsim) { diff --git a/DRAMSys/simulator/resources/configs/mcconfigs/fr_fcfs_grp.xml b/DRAMSys/simulator/resources/configs/mcconfigs/fr_fcfs_grp.xml new file mode 100644 index 00000000..44d5db18 --- /dev/null +++ b/DRAMSys/simulator/resources/configs/mcconfigs/fr_fcfs_grp.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/DRAMSys/simulator/resources/resources.pri b/DRAMSys/simulator/resources/resources.pri index f240b193..e2e85724 100644 --- a/DRAMSys/simulator/resources/resources.pri +++ b/DRAMSys/simulator/resources/resources.pri @@ -150,3 +150,8 @@ OTHER_FILES += resources/configs/thermalsim/config.xml # Error Simulation data OTHER_FILES += resources/error/wideio.csv + +DISTFILES += \ + $$PWD/traces/read_write_switch.stl \ + $$PWD/configs/mcconfigs/fr_fcfs_rp.xml \ + $$PWD/configs/mcconfigs/fr_fcfs_grp.xml diff --git a/DRAMSys/simulator/src/common/Utils.h b/DRAMSys/simulator/src/common/Utils.h index 9d97e8dc..78dc85ed 100644 --- a/DRAMSys/simulator/src/common/Utils.h +++ b/DRAMSys/simulator/src/common/Utils.h @@ -94,7 +94,10 @@ bool isIn(const T& value, const std::vector& collection) constexpr const char headline[] = "========================================================="; -static inline void loadbar(unsigned int x, unsigned int n, unsigned int w = 50, unsigned int granularity = 1) +static inline void loadbar(unsigned int x, + unsigned int n, + unsigned int w = 50, + unsigned int granularity = 1) { if ((n < 100) || ((x != n) && (x % (n / 100 * granularity) != 0))) return; @@ -106,7 +109,7 @@ static inline void loadbar(unsigned int x, unsigned int n, unsigned int w = 50, for (unsigned int x = 0; x < c; x++) std::cout << "█"; - if(rest > 0 && rest < 0.125) + if(rest >= 0 && rest < 0.125 && c != w) std::cout << " "; if(rest >= 0.125 && rest < 2*0.125) std::cout << "▏"; diff --git a/DRAMSys/simulator/src/controller/Controller.cpp b/DRAMSys/simulator/src/controller/Controller.cpp index e9686617..0f7ebbf3 100644 --- a/DRAMSys/simulator/src/controller/Controller.cpp +++ b/DRAMSys/simulator/src/controller/Controller.cpp @@ -36,10 +36,12 @@ */ #include "Controller.h" +#include void Controller::buildScheduler() { string selectedScheduler = Configuration::getInstance().Scheduler; + std::cout << "Selected Scheduler: " << selectedScheduler << std::endl; if (selectedScheduler == "FIFO") { @@ -57,6 +59,10 @@ void Controller::buildScheduler() { scheduler = new FR_FCFS_RP(*controllerCore); } + else if (selectedScheduler == "FR_FCFS_GRP") + { + scheduler = new FR_FCFS_GRP(*controllerCore); + } else if (selectedScheduler == "SMS") { scheduler = new SMS("SMS", *controllerCore, Configuration::getInstance().SJFProbability); diff --git a/DRAMSys/simulator/src/controller/Controller.h b/DRAMSys/simulator/src/controller/Controller.h index cc833aae..184cb445 100644 --- a/DRAMSys/simulator/src/controller/Controller.h +++ b/DRAMSys/simulator/src/controller/Controller.h @@ -68,6 +68,7 @@ #include "scheduler/FifoStrict.h" #include "scheduler/Fr_Fcfs.h" #include "scheduler/Fr_Fcfs_read_priority.h" +#include "scheduler/Fr_Fcfs_grouper.h" #include "scheduler/SMS.h" #include "scheduler/IScheduler.h" diff --git a/DRAMSys/simulator/src/controller/scheduler/Fr_Fcfs_grouper.cpp b/DRAMSys/simulator/src/controller/scheduler/Fr_Fcfs_grouper.cpp new file mode 100644 index 00000000..8f1e80a6 --- /dev/null +++ b/DRAMSys/simulator/src/controller/scheduler/Fr_Fcfs_grouper.cpp @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2017, University of Kaiserslautern + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: + * Matthias Jung + */ + +#include "Fr_Fcfs_grouper.h" + +// The FR_FCFS_Read_Priority works exactly like the FR_FCFS_RP. +// However writes are grouped! For detailed documentation look into the FR_FCFS. +// TODO: what is missed is a check if the buffers are full. This will only work +// if we have buffers with a fixed size (Prado's future patch). + +std::pair FR_FCFS_GRP::getNextRequest(Bank bank) +{ + // If the bank is empty we do nothing: + if(buffer[bank].empty()) + { + return pair(Command::NOP, NULL); + } + + // If we are in write mode we should check if we should switch to read mode + // because there are no writes anymore in the buffer. + if(readMode == false) + { + if(getNumberOfRequest(tlm::TLM_WRITE_COMMAND) == 0) + { + readMode = true; + } + } + else // If we are in read mode but all reads are served we switch to write + { + if(getNumberOfRequest(tlm::TLM_READ_COMMAND) == 0) + { + readMode = false; + } + } + + // Now lets search for read and write commands. However keep in mind that + // readMode is a shared variable for all the banks! + if(readMode == true) + { + // 1. Seach for read hit: + for(auto it = buffer[bank].begin(); it!=buffer[bank].end(); it++) + { + gp* read = *it; + + if(read->get_command() == tlm::TLM_READ_COMMAND) + { + // If there is a row hit: + if(DramExtension::getRow(read) + == controllerCore.getRowBufferStates() + .getRowInRowBuffer(bank)) + { + if(hazardDetection(bank, it) == false) + { + buffer[bank].erase(it); + printDebugMessage("Read Hit found"); + return pair(getReadWriteCommand(*read), + read); + } + else + { + // If there was a hazard, switch the mode and try again: + readMode = false; + return getNextRequest(bank); + } + } + } + } + + // 2. Search for read miss: + for(auto it = buffer[bank].begin(); it!=buffer[bank].end(); it++) + { + gp* read = *it; + + if(read->get_command() == tlm::TLM_READ_COMMAND) + { + if(hazardDetection(bank, it) == false) + { + printDebugMessage("Read miss found"); + return pair(getNextCommand(read),read); + } + else + { + // If there was a hazard, switch the mode and try again: + readMode = false; + return getNextRequest(bank); + } + } + } + } + else // write mode: + { + // 3. Search for write hit: + for(auto it = buffer[bank].begin(); it!=buffer[bank].end(); it++) + { + gp* write = *it; + + if(write->get_command() == tlm::TLM_WRITE_COMMAND) + { + // If there is a row hit: + if(DramExtension::getRow(write) + == controllerCore.getRowBufferStates() + .getRowInRowBuffer(bank)) + { + buffer[bank].erase(it); + printDebugMessage("Write Hit found"); + return pair(getReadWriteCommand(*write), + write); + } + } + } + + // 4. Search for write miss: + for(auto it = buffer[bank].begin(); it!=buffer[bank].end(); it++) + { + gp* write = *it; + + if(write->get_command() == tlm::TLM_WRITE_COMMAND) + { + printDebugMessage("Write miss found"); + return pair(getNextCommand(write),write); + } + } + } + + // If nothing was found in the current mode, switch the mode and try again: + readMode = !readMode; + return getNextRequest(bank); + + reportFatal("FR_FCFS_RP", "Never should go here ..."); +} + +// There is a hazard if a read is found which will be scheduled before a write +// to the same column and the same row of the same bank: +bool FR_FCFS_GRP::hazardDetection(Bank bank, std::deque::iterator ext) +{ + gp* read = *ext; + + //for(unsigned long i=0; i < id; i++) + for(auto it = buffer[bank].begin(); it!=ext; it++) + { + gp* write = *it; + if(write->get_command() == tlm::TLM_WRITE_COMMAND) + { + if((DramExtension::getExtension(read).getColumn() + == DramExtension::getExtension(write).getColumn()) + && (DramExtension::getExtension(read).getRow() + == DramExtension::getExtension(write).getRow())) + { + printDebugMessage("Hazard Detected"); + return true; + } + } + } + return false; +} + +// Estimate the number of writes/reads in all bank buffers: +unsigned int FR_FCFS_GRP::getNumberOfRequest(tlm::tlm_command cmd) +{ + unsigned int numberOfRequests = 0; + for(unsigned int i = 0; + i < Configuration::getInstance().memSpec.NumberOfBanks; + i++) + { + for(auto it = buffer[i].begin(); it!=buffer[i].end(); it++) + { + gp* trans = *it; + if(trans->get_command()==cmd) + { + numberOfRequests++; + } + } + } + + return numberOfRequests; +} + +void FR_FCFS_GRP::printDebugMessage(std::string message) +{ + DebugManager::getInstance().printDebugMessage("FR_FCFS_GRP", message); +} diff --git a/DRAMSys/simulator/src/controller/scheduler/Fr_Fcfs_grouper.h b/DRAMSys/simulator/src/controller/scheduler/Fr_Fcfs_grouper.h new file mode 100644 index 00000000..bf13341f --- /dev/null +++ b/DRAMSys/simulator/src/controller/scheduler/Fr_Fcfs_grouper.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2017, University of Kaiserslautern + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: + * Matthias Jung + */ + +#ifndef FR_FCFS_GROUPER_H +#define FR_FCFS_GROUPER_H + +#include "Fr_Fcfs.h" + +class FR_FCFS_GRP : public FR_FCFS +{ +public: + FR_FCFS_GRP(ControllerCore &controllerCore) : FR_FCFS(controllerCore), + readMode(true) + {} + + std::pair + getNextRequest(Bank bank) override; + +private: + + bool hazardDetection(Bank bank, std::deque::iterator ext); + unsigned int getNumberOfRequest(tlm::tlm_command cmd); + void printDebugMessage(std::string message); + bool readMode; +}; + +#endif // FR_FCFS_GROUPER_H