diff --git a/dram/dramSys/dramSys.pro b/dram/dramSys/dramSys.pro index 6ba44ef5..b521d493 100644 --- a/dram/dramSys/dramSys.pro +++ b/dram/dramSys/dramSys.pro @@ -8,15 +8,15 @@ LIBS += -L/opt/systemc/lib-linux64 -lsystemc LIBS += -L/opt/boost/lib -lboost_filesystem -lboost_system LIBS += -L/opt/sqlite3/lib -lsqlite3 LIBS += -lpthread -#LIBS += -lxerces-c -#LIBS += -L../src/common/third_party/DRAMPower/src/ -ldrampowerxml -#LIBS += -L../src/common/third_party/DRAMPower/src/ -ldrampower +LIBS += -L/opt/xerces/lib -lxerces-c +LIBS += -L../src/common/third_party/DRAMPower/src/ -ldrampowerxml +LIBS += -L../src/common/third_party/DRAMPower/src/ -ldrampower INCLUDEPATH += /opt/systemc/include INCLUDEPATH += /opt/boost/include INCLUDEPATH += /opt/sqlite3/include -#INCLUDEPATH += ../src/common/third_party/DRAMPower/src -#INCLUDEPATH += ../src/common/third_party/DRAMPower/src/libdrampower +INCLUDEPATH += ../src/common/third_party/DRAMPower/src +INCLUDEPATH += ../src/common/third_party/DRAMPower/src/libdrampower DEFINES += TIXML_USE_STL DEFINES += SC_INCLUDE_DYNAMIC_PROCESSES diff --git a/dram/resources/configs/memconfigs/fr_fcfs.xml b/dram/resources/configs/memconfigs/fr_fcfs.xml index b126adb1..9dd3c80c 100644 --- a/dram/resources/configs/memconfigs/fr_fcfs.xml +++ b/dram/resources/configs/memconfigs/fr_fcfs.xml @@ -1,6 +1,6 @@ - + @@ -9,7 +9,6 @@ - - + diff --git a/dram/resources/simulations/sim-batch.xml b/dram/resources/simulations/sim-batch.xml index a9e88a0b..f0aa5a30 100644 --- a/dram/resources/simulations/sim-batch.xml +++ b/dram/resources/simulations/sim-batch.xml @@ -10,7 +10,7 @@ - chstone-sha_32.stl + mediabench-epic_32.stl diff --git a/dram/src/controller/Controller.h b/dram/src/controller/Controller.h index 4c0f5a7d..ea8adc02 100644 --- a/dram/src/controller/Controller.h +++ b/dram/src/controller/Controller.h @@ -116,13 +116,10 @@ template void Controller::buildScheduler() { string selectedScheduler = Configuration::getInstance().Scheduler; + //selectedScheduler == "ReadWriteGrouper"; if (selectedScheduler == "FR_FCFS") { - - //Scheduler* s = new FR_FCFS(*controllerCore, Configuration::getInstance().RefreshAwareScheduling, - // Configuration::getInstance().AdaptiveOpenPagePolicy); - //scheduler = new ReadWriteGrouper(s); scheduler = new FR_FCFS(*controllerCore, Configuration::getInstance().RefreshAwareScheduling,Configuration::getInstance().AdaptiveOpenPagePolicy); } else if (selectedScheduler == "PAR_BS") @@ -131,7 +128,13 @@ void Controller::buildScheduler() Configuration::getInstance().Capsize); } else if (selectedScheduler == "FIFO") + { scheduler = new Fifo(*controllerCore); + } + else if (selectedScheduler == "ReadWriteGrouper") + { + scheduler = new ReadWriteGrouper(*controllerCore); + } else reportFatal(name(), "unsupported scheduler: " + selectedScheduler); } diff --git a/dram/src/controller/scheduler/Fr_Fcfs.cpp b/dram/src/controller/scheduler/Fr_Fcfs.cpp index 5635cc33..b0b6c159 100644 --- a/dram/src/controller/scheduler/Fr_Fcfs.cpp +++ b/dram/src/controller/scheduler/Fr_Fcfs.cpp @@ -97,6 +97,19 @@ unsigned int FR_FCFS::getNumberOfQueuedPayloads() return numberOfQueuedPaylods; } +bool FR_FCFS::containsPayloadTragetingSameAddress(gp *payload) +{ + Bank bank = DramExtension::getExtension(payload).getBank(); + Row row = DramExtension::getExtension(payload).getRow(); + + for(gp* bufferedPayload: buffer[bank]) + { + if(DramExtension::getExtension(bufferedPayload).getRow() == row) + return true; + } + return false; +} + std::vector FR_FCFS::findRowHits(Bank bank, Row row) { vector found; diff --git a/dram/src/controller/scheduler/Fr_Fcfs.h b/dram/src/controller/scheduler/Fr_Fcfs.h index ccfbf718..39446120 100644 --- a/dram/src/controller/scheduler/Fr_Fcfs.h +++ b/dram/src/controller/scheduler/Fr_Fcfs.h @@ -25,6 +25,8 @@ public: gp* popOldest(Bank bank); unsigned int getNumberOfQueuedPayloads(); + //used by read/write grouper + bool containsPayloadTragetingSameAddress(gp* payload); private: std::vector findRowHits(Bank bank, Row row); std::map> buffer; diff --git a/dram/src/controller/scheduler/readwritegrouper.cpp b/dram/src/controller/scheduler/readwritegrouper.cpp index efb202d4..b28057db 100644 --- a/dram/src/controller/scheduler/readwritegrouper.cpp +++ b/dram/src/controller/scheduler/readwritegrouper.cpp @@ -6,130 +6,139 @@ namespace scheduler{ using namespace tlm; using namespace std; -string ReadWriteGrouper::senderName = "ReadWriteGrouper"; - -ReadWriteGrouper::ReadWriteGrouper(Scheduler *scheduler): - scheduler(scheduler), mode(Mode::read) +ReadWriteGrouper::ReadWriteGrouper(core::ControllerCore& controllerCore): controllerCore(controllerCore) { - printDebugMessage("In read mode"); + batches.push_back(shared_ptr(new FR_FCFS(controllerCore,true,false))); + batches.push_back(shared_ptr(new FR_FCFS(controllerCore,true,false))); } ReadWriteGrouper::~ReadWriteGrouper() { - delete scheduler; + +} + +void ReadWriteGrouper::schedule(gp *payload) +{ + tlm_command command = payload->get_command(); + printDebugMessage("Scheduling new payload"); + + if(batches.size() > 2) + { + if(command == TLM_READ_COMMAND) + { + if(schedulingReadCausesHazardWithQueuedWrite(payload)) + { + printDebugMessage("Scheduling read causes hazard with queued write"); + batches.push_back(shared_ptr(new FR_FCFS(controllerCore,true,false))); + batches.push_back(shared_ptr(new FR_FCFS(controllerCore,true,false))); + } + + getLatestReadBatch().schedule(payload); + } + else if(command == TLM_WRITE_COMMAND) + { + getLatestWriteBatch().schedule(payload); + } + } + else if(batches.size() == 2) + { + if(command == TLM_READ_COMMAND) + { + if(getLatestReadBatch().hasPayloads() && schedulingReadCausesHazardWithQueuedWrite(payload)) + { + printDebugMessage("Scheduling read causes hazard with queued write"); + batches.push_back(shared_ptr(new FR_FCFS(controllerCore,true,false))); + batches.push_back(shared_ptr(new FR_FCFS(controllerCore,true,false))); + } + else if(!getLatestReadBatch().hasPayloads() && getLatestWriteBatch().hasPayloads()) + { + batches.erase(batches.begin()); + batches.push_back(shared_ptr(new FR_FCFS(controllerCore,true,false))); + batches.push_back(shared_ptr(new FR_FCFS(controllerCore,true,false))); + } + getLatestReadBatch().schedule(payload); + + } + else if(command == TLM_WRITE_COMMAND) + { + getLatestWriteBatch().schedule(payload); + } + } + else + { + sc_assert(false); + } +} + +gp *ReadWriteGrouper::getNextPayload() +{ + if(batches.size() > 2) + { + return batches.front()->getNextPayload(); + } + else if(batches.size() == 2) + { + if(getLatestReadBatch().hasPayloads()) + return getLatestReadBatch().getNextPayload(); + else if(getLatestWriteBatch().hasPayloads()) + return getLatestWriteBatch().getNextPayload(); + else + return NULL; + } + else + { + sc_assert(false); + } } void ReadWriteGrouper::removePayload(gp *payload) { - scheduler->removePayload(payload); - - //if scheduler is empty now - if(!scheduler->hasPayloads()) + if(batches.size() > 2) { - printDebugMessage("No more transactions in scheduler"); - - if((mode == Mode::read && !writeQueue.empty()) || mode == Mode::readToWrite) - switchToWriteMode(); + batches.front()->removePayload(payload); + if(!batches.front()->hasPayloads()) + batches.erase(batches.begin()); + } + else if(batches.size() == 2) + { + if(payload->is_read()) + getLatestReadBatch().removePayload(payload); else - switchToReadMode(); + getLatestWriteBatch().removePayload(payload); } -} - -void ReadWriteGrouper::schedule(gp *payload) -{ -tlm_command command = payload->get_command(); - -//in read mode hazards could occur by letting a read pass a queued write -if(mode == Mode::read) -{ - if(command == TLM_READ_COMMAND) + else { - //if scheduling the read would cause a hazard switch to readToWriteMode and put the read into the readQueue - if(schedulingReadCausesHazardWithQueuedWrite(payload)) - { - switchToReadToWriteMode(); - readQueue.push_back(payload); - } - else - scheduler->schedule(payload); - } - else if(command == TLM_WRITE_COMMAND) - { - writeQueue.push_back(payload); - if(!scheduler->hasPayloads()) - //there are no reads in the scheduler, so switch directly to write mode - switchToWriteMode(); + sc_assert(false); } } -else if(mode == Mode::readToWrite) -{ - if(command == TLM_READ_COMMAND) - readQueue.push_back(payload); - else if(command == TLM_WRITE_COMMAND) - writeQueue.push_back(payload); -} -else if(mode == Mode::write) -{ - if(command == TLM_READ_COMMAND) - readQueue.push_back(payload); - else if(command == TLM_WRITE_COMMAND) - scheduler->schedule(payload); -} -} - -gp *ReadWriteGrouper::getNextPayload() -{ - return scheduler->getNextPayload(); -} bool ReadWriteGrouper::hasPayloads() { - return scheduler->hasPayloads(); + if(batches.size() > 2) + return true; + else if(batches.size() == 2) + return (getLatestReadBatch().hasPayloads() || getLatestWriteBatch().hasPayloads()); + else + sc_assert(false); } bool ReadWriteGrouper::schedulingReadCausesHazardWithQueuedWrite(gp *payload) { sc_assert(payload->is_read()); - for(gp* write: writeQueue) - { - if(payload->get_address()==write->get_address()) - return true; - } - return false; + return getLatestWriteBatch().containsPayloadTragetingSameAddress(payload); } -void ReadWriteGrouper::switchToReadMode() +FR_FCFS &ReadWriteGrouper::getLatestWriteBatch() { - printDebugMessage("Switching to read mode"); - sc_assert(!scheduler->hasPayloads()); - mode = Mode::read; - for(gp* read: readQueue) - scheduler->schedule(read); - readQueue.clear(); + return *batches[batches.size()-1]; } -void ReadWriteGrouper::switchToWriteMode() +FR_FCFS &ReadWriteGrouper::getLatestReadBatch() { - printDebugMessage("Switching to write mode"); - sc_assert(!scheduler->hasPayloads()); - mode = Mode::write; - for(gp* write: writeQueue) - scheduler->schedule(write); - writeQueue.clear(); -} - -void ReadWriteGrouper::switchToReadToWriteMode() -{ - printDebugMessage("Switching to read-to-write-mode"); - mode = Mode::readToWrite; -} - -void printDebugMessage(string message) -{ - DebugManager::getInstance().printDebugMessage(ReadWriteGrouper::senderName, message); + return *batches[batches.size()-2]; } } diff --git a/dram/src/controller/scheduler/readwritegrouper.h b/dram/src/controller/scheduler/readwritegrouper.h index 9f5945f1..dedd0c5d 100644 --- a/dram/src/controller/scheduler/readwritegrouper.h +++ b/dram/src/controller/scheduler/readwritegrouper.h @@ -1,40 +1,37 @@ #ifndef READWRITEGROUPER_H #define READWRITEGROUPER_H #include "Scheduler.h" +#include "Fr_Fcfs.h" +#include "../core/ControllerCore.h" +#include #include + namespace scheduler{ -/* Scheduler that batches reads and writes to reduce the overhead when switching from - * read to write mode (read-to-write constraints) - * The scheduler prioritizes reads. It switches to write mode, when stalling a write would induce a data-hazard - * or when there are no reads to process. - */ class ReadWriteGrouper : public Scheduler { public: - ReadWriteGrouper(Scheduler *scheduler); + ReadWriteGrouper(core::ControllerCore& controllerCore); ~ReadWriteGrouper(); virtual void schedule(gp* payload) override; virtual bool hasPayloads() override; virtual gp* getNextPayload() override; virtual void removePayload(gp* payload) override; - static std::string senderName; - private: - Scheduler *scheduler; - std::vector readQueue, writeQueue; - //Mode readToWrite is used to process the remaining reads in the readScheduler before - //switching to write mode (this is used when a potential hazard causes the scheduler to switch modes) - enum class Mode{read,readToWrite, write}; - Mode mode; + // contains batches of requests + // last element always contains writes + // next-to-last element always contains reads + // there are always at least two batches + // if there are more than two batches, batches[0] is never empty and + // getNextPayload and removePayload are forwarded to batches[0] + std::vector> batches; + core::ControllerCore& controllerCore; bool schedulingReadCausesHazardWithQueuedWrite(gp* payload); - void switchToReadMode(); - void switchToWriteMode(); - void switchToReadToWriteMode(); - void printDebugMessage(std::string message); + FR_FCFS& getLatestWriteBatch(); + FR_FCFS& getLatestReadBatch(); }; diff --git a/dram/src/simulation/Simulation.cpp b/dram/src/simulation/Simulation.cpp index 48158a40..7607bdbd 100644 --- a/dram/src/simulation/Simulation.cpp +++ b/dram/src/simulation/Simulation.cpp @@ -52,7 +52,6 @@ void Simulation::setupDebugManager(const string& traceName) dbg.addToWhiteList(TlmRecorder::senderName); dbg.addToWhiteList(ControllerCore::senderName); dbg.addToWhiteList(PowerDownManagerBankwise::senderName); - dbg.addToWhiteList(ReadWriteGrouper::senderName); dbg.writeToConsole = true; dbg.writeToFile = true;