From 4ed7ff420b85fc9ac60b937ec9e7bf025a610faa Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Thu, 23 Feb 2017 16:22:44 +0100 Subject: [PATCH 01/39] Initial setup for SMS implementation # Explain what has been changed # Explain why this change is being made # Provide links to any relevant tickets, articles or other resources --- .../resources/configs/mcconfigs/sms.xml | 15 ++++++++++++ .../resources/simulations/sim-batch.xml | 6 ++--- DRAMSys/simulator/simulator.pro | 6 +++-- .../simulator/src/controller/Controller.cpp | 4 ++++ DRAMSys/simulator/src/controller/Controller.h | 1 + .../core/configuration/Configuration.cpp | 6 +++++ .../core/configuration/Configuration.h | 1 + .../src/controller/scheduler/SMS.cpp | 13 ++++++++++ .../simulator/src/controller/scheduler/SMS.h | 24 +++++++++++++++++++ 9 files changed, 71 insertions(+), 5 deletions(-) create mode 100644 DRAMSys/simulator/resources/configs/mcconfigs/sms.xml create mode 100644 DRAMSys/simulator/src/controller/scheduler/SMS.cpp create mode 100644 DRAMSys/simulator/src/controller/scheduler/SMS.h diff --git a/DRAMSys/simulator/resources/configs/mcconfigs/sms.xml b/DRAMSys/simulator/resources/configs/mcconfigs/sms.xml new file mode 100644 index 00000000..f975678a --- /dev/null +++ b/DRAMSys/simulator/resources/configs/mcconfigs/sms.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/DRAMSys/simulator/resources/simulations/sim-batch.xml b/DRAMSys/simulator/resources/simulations/sim-batch.xml index 0752914c..dcc783d9 100644 --- a/DRAMSys/simulator/resources/simulations/sim-batch.xml +++ b/DRAMSys/simulator/resources/simulations/sim-batch.xml @@ -2,7 +2,7 @@ - + @@ -39,11 +39,11 @@ - + - + chstone-adpcm_32.stl diff --git a/DRAMSys/simulator/simulator.pro b/DRAMSys/simulator/simulator.pro index 593718da..20ddcef4 100644 --- a/DRAMSys/simulator/simulator.pro +++ b/DRAMSys/simulator/simulator.pro @@ -107,7 +107,8 @@ SOURCES += \ src/controller/Controller.cpp \ src/simulation/TracePlayer.cpp \ src/simulation/StlPlayer.cpp \ - src/controller/core/powerdown/PowerDownManagerTimeoutBankwise.cpp + src/controller/core/powerdown/PowerDownManagerTimeoutBankwise.cpp \ + src/controller/scheduler/SMS.cpp HEADERS += \ src/common/third_party/tinyxml2/tinyxml2.h \ @@ -169,7 +170,8 @@ HEADERS += \ src/controller/core/configuration/ConfigurationLoader.h \ src/error/errormodel.h \ src/simulation/ExampleInitiator.h \ - src/controller/core/powerdown/PowerDownManagerTimeoutBankwise.h + src/controller/core/powerdown/PowerDownManagerTimeoutBankwise.h \ + src/controller/scheduler/SMS.h thermalsim = $$(THERMALSIM) isEmpty(thermalsim) { diff --git a/DRAMSys/simulator/src/controller/Controller.cpp b/DRAMSys/simulator/src/controller/Controller.cpp index 65847603..b16f981b 100644 --- a/DRAMSys/simulator/src/controller/Controller.cpp +++ b/DRAMSys/simulator/src/controller/Controller.cpp @@ -53,6 +53,10 @@ void Controller::buildScheduler() { scheduler = new FR_FCFS(*controllerCore); } + else if (selectedScheduler == "SMS") + { + scheduler = new SMS(*controllerCore, Configuration::getInstance().SJFProbability); + } //else if (selectedScheduler == "PAR_BS") //{ // scheduler = new PAR_BS(*controllerCore,Configuration::getInstance().RefreshAwareScheduling, diff --git a/DRAMSys/simulator/src/controller/Controller.h b/DRAMSys/simulator/src/controller/Controller.h index a07a8b74..a1286d1f 100644 --- a/DRAMSys/simulator/src/controller/Controller.h +++ b/DRAMSys/simulator/src/controller/Controller.h @@ -67,6 +67,7 @@ #include "scheduler/Fifo.h" #include "scheduler/FifoStrict.h" #include "scheduler/Fr_Fcfs.h" +#include "scheduler/SMS.h" #include "scheduler/IScheduler.h" using namespace std; diff --git a/DRAMSys/simulator/src/controller/core/configuration/Configuration.cpp b/DRAMSys/simulator/src/controller/core/configuration/Configuration.cpp index 594a746b..910e0029 100644 --- a/DRAMSys/simulator/src/controller/core/configuration/Configuration.cpp +++ b/DRAMSys/simulator/src/controller/core/configuration/Configuration.cpp @@ -121,6 +121,12 @@ void Configuration::setParameter(std::string name, std::string value) MaxNrOfTransactions = string2int(value); else if(name == "Scheduler") Scheduler = value; + else if(name == "SJFProbability") + if (string2int(value) > 100 || string2int(value) < 0) { + SC_REPORT_FATAL("Configuration", ("Invalid value for parameter " + name + ". This parameter must be between 0 and 100.").c_str()); + } else { + SJFProbability = string2int(value); + } else if(name == "Capsize") Capsize = string2int(value); else if(name == "PowerDownTimeout") diff --git a/DRAMSys/simulator/src/controller/core/configuration/Configuration.h b/DRAMSys/simulator/src/controller/core/configuration/Configuration.h index 53437269..929d65f1 100644 --- a/DRAMSys/simulator/src/controller/core/configuration/Configuration.h +++ b/DRAMSys/simulator/src/controller/core/configuration/Configuration.h @@ -66,6 +66,7 @@ struct Configuration bool OpenPagePolicy = true; unsigned int MaxNrOfTransactions = 8; std::string Scheduler; + unsigned int SJFProbability; unsigned int Capsize = 5; sc_time getPowerDownTimeout(){return powerDownTimeoutInClk*memSpec.clk;} EPowerDownMode PowerDownMode = EPowerDownMode::Staggered; diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp new file mode 100644 index 00000000..a5eef6dc --- /dev/null +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -0,0 +1,13 @@ +#include "SMS.h" + +using namespace std; + +void SMS::schedule (gp *payload) +{ + buffer[DramExtension::getExtension(payload).getThread()].emplace_back(payload); +} + +std::pair SMS::getNextRequest(Bank bank) +{ + return pair(Command::NOP, NULL); +} diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h new file mode 100644 index 00000000..c2c7dfa3 --- /dev/null +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h @@ -0,0 +1,24 @@ +#ifndef SMS_H +#define SMS_H + +#include "IScheduler.h" +#include "../core/ControllerCore.h" +#include "../core/configuration/Configuration.h" +#include "../../common/dramExtension.h" + +using namespace std; + +class SMS: public sc_module, public IScheduler +{ +public: + SMS(ControllerCore &controllerCore, unsigned int SJFprobability) : IScheduler(controllerCore), SJFprobability(SJFprobability){} + virtual ~SMS(){} + virtual void schedule(gp *payload) override; + virtual std::pair getNextRequest(Bank bank) override; + +private: + std::map> buffer; + unsigned int SJFprobability; +}; + +#endif // SMS_H From 2cfa7114af2fb3dc6a3fad2d3010b2fd7821d098 Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Thu, 23 Feb 2017 21:14:30 +0100 Subject: [PATCH 02/39] Implement getNextRequest # Explain what has been changed # Explain why this change is being made # Provide links to any relevant tickets, articles or other resources --- .../src/controller/scheduler/SMS.cpp | 22 ++++++++++++++++--- .../simulator/src/controller/scheduler/SMS.h | 2 ++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index a5eef6dc..a3ae0867 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -2,12 +2,28 @@ using namespace std; -void SMS::schedule (gp *payload) +void SMS::schedule(gp *payload) { - buffer[DramExtension::getExtension(payload).getThread()].emplace_back(payload); + buffer[DramExtension::getExtension(payload).getThread()].emplace_back(payload); } std::pair SMS::getNextRequest(Bank bank) { - return pair(Command::NOP, NULL); + if (bankbuffer[bank].empty()) + { + return pair(Command::NOP, NULL); + } + else + { + gp* payload = bankbuffer[bank].front(); + Command command = IScheduler::getNextCommand(*payload); + if (command == Command::Read || command == Command::ReadA || command == Command::Write + || command == Command::WriteA) + { + bankbuffer[bank].pop_front(); + } + + return pair(command, payload); + } + } diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h index c2c7dfa3..d6fde08a 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.h +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h @@ -18,6 +18,8 @@ public: private: std::map> buffer; + std::map> bankbuffer; + unsigned int SJFprobability; }; From 42b1c96afdb76fe28f281853e6b627d7f698be9a Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Thu, 23 Feb 2017 21:48:29 +0100 Subject: [PATCH 03/39] First prototype of ReadyBatch class # Explain what has been changed # Explain why this change is being made # Provide links to any relevant tickets, articles or other resources --- .../resources/configs/mcconfigs/sms.xml | 2 ++ DRAMSys/simulator/simulator.pro | 6 +++-- .../core/configuration/Configuration.cpp | 4 +++ .../core/configuration/Configuration.h | 2 ++ .../src/controller/scheduler/ReadyBatch.cpp | 1 + .../src/controller/scheduler/ReadyBatch.h | 25 +++++++++++++++++++ 6 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp create mode 100644 DRAMSys/simulator/src/controller/scheduler/ReadyBatch.h diff --git a/DRAMSys/simulator/resources/configs/mcconfigs/sms.xml b/DRAMSys/simulator/resources/configs/mcconfigs/sms.xml index f975678a..bee3151e 100644 --- a/DRAMSys/simulator/resources/configs/mcconfigs/sms.xml +++ b/DRAMSys/simulator/resources/configs/mcconfigs/sms.xml @@ -4,6 +4,8 @@ + + diff --git a/DRAMSys/simulator/simulator.pro b/DRAMSys/simulator/simulator.pro index 20ddcef4..4d98bf05 100644 --- a/DRAMSys/simulator/simulator.pro +++ b/DRAMSys/simulator/simulator.pro @@ -108,7 +108,8 @@ SOURCES += \ src/simulation/TracePlayer.cpp \ src/simulation/StlPlayer.cpp \ src/controller/core/powerdown/PowerDownManagerTimeoutBankwise.cpp \ - src/controller/scheduler/SMS.cpp + src/controller/scheduler/SMS.cpp \ + src/controller/scheduler/ReadyBatch.cpp HEADERS += \ src/common/third_party/tinyxml2/tinyxml2.h \ @@ -171,7 +172,8 @@ HEADERS += \ src/error/errormodel.h \ src/simulation/ExampleInitiator.h \ src/controller/core/powerdown/PowerDownManagerTimeoutBankwise.h \ - src/controller/scheduler/SMS.h + src/controller/scheduler/SMS.h \ + src/controller/scheduler/ReadyBatch.h thermalsim = $$(THERMALSIM) isEmpty(thermalsim) { diff --git a/DRAMSys/simulator/src/controller/core/configuration/Configuration.cpp b/DRAMSys/simulator/src/controller/core/configuration/Configuration.cpp index 910e0029..f3698179 100644 --- a/DRAMSys/simulator/src/controller/core/configuration/Configuration.cpp +++ b/DRAMSys/simulator/src/controller/core/configuration/Configuration.cpp @@ -127,6 +127,10 @@ void Configuration::setParameter(std::string name, std::string value) } else { SJFProbability = string2int(value); } + else if (name == "ReadyBatchSize") + ReadyBatchSize = string2int(value); + else if (name == "ReadyBatchThresholdAge") + ReadyBatchThresholdAge = string2int(value); else if(name == "Capsize") Capsize = string2int(value); else if(name == "PowerDownTimeout") diff --git a/DRAMSys/simulator/src/controller/core/configuration/Configuration.h b/DRAMSys/simulator/src/controller/core/configuration/Configuration.h index 929d65f1..6ca503a7 100644 --- a/DRAMSys/simulator/src/controller/core/configuration/Configuration.h +++ b/DRAMSys/simulator/src/controller/core/configuration/Configuration.h @@ -67,6 +67,8 @@ struct Configuration unsigned int MaxNrOfTransactions = 8; std::string Scheduler; unsigned int SJFProbability; + unsigned int ReadyBatchSize; + unsigned int ReadyBatchThresholdAge; unsigned int Capsize = 5; sc_time getPowerDownTimeout(){return powerDownTimeoutInClk*memSpec.clk;} EPowerDownMode PowerDownMode = EPowerDownMode::Staggered; diff --git a/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp new file mode 100644 index 00000000..a55c4c40 --- /dev/null +++ b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp @@ -0,0 +1 @@ +#include "ReadyBatch.h" diff --git a/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.h b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.h new file mode 100644 index 00000000..91fac215 --- /dev/null +++ b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.h @@ -0,0 +1,25 @@ +#ifndef READYBATCH_H +#define READYBATCH_H + +#include "tlm.h" +#include "../../common/dramExtension.h" + +typedef tlm::tlm_generic_payload gp; + +using namespace std; + +class ReadyBatch +{ +public: + ReadyBatch(unsigned int fifosize) : fifosize(fifosize){} + bool addTransaction(gp* payload); +private: + std::deque readybatch; + unsigned int fifosize; + + Row getRow(); + sc_time getTimeOfOldestRequest(); + unsigned int getNumRequests(); +}; + +#endif // READYBATCH_H From 413916f4027bcf3f7c6f9fdab1fdf9e858d3a92f Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Thu, 23 Feb 2017 22:35:09 +0100 Subject: [PATCH 04/39] Implement ReadyBatch class # Explain what has been changed # Explain why this change is being made # Provide links to any relevant tickets, articles or other resources --- .../src/controller/scheduler/ReadyBatch.cpp | 42 +++++++++++++++++++ .../src/controller/scheduler/ReadyBatch.h | 4 +- 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp index a55c4c40..af218173 100644 --- a/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp @@ -1 +1,43 @@ #include "ReadyBatch.h" + +ReadyBatch::ReadyBatch() +{ + fifosize = Configuration::getInstance().ReadyBatchSize; + thresholdAge(Configuration::getInstance().ReadyBatchThresholdAge, SC_NS); +} + +unsigned int ReadyBatch::getNumRequests() +{ + return readybatch.size(); +} + +Row ReadyBatch::getRow() +{ + return DramExtension::getExtension(readybatch.front()).getRow(); +} + +sc_time ReadyBatch::getTimeOfOldestRequest() +{ + sc_time oldestTime = sc_time_stamp(); + for (auto reqPayload = readybatch.begin(); reqPayload != readybatch.end(); reqPayload++) + { + sc_time requestTimeOfGeneration = GenerationExtension::getExtension(*reqPayload).TimeOfGeneration(); + if (requestTimeOfGeneration < oldestTime) + { + oldestTime = requestTimeOfGeneration; + } + } + return oldestTime; +} + +bool ReadyBatch::addTransaction(gp* payload) +{ + sc_time currentAge = sc_time_stamp() - getTimeOfOldestRequest(); + Row newRow = DramExtension::getExtension(payload).getRow(); + if (getNumRequests == fifosize || currentAge >= thresholdAge || newRow != getRow()) { + return false; + } else { + readybatch.emplace_back(payload); + return true; + } +} diff --git a/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.h b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.h index 91fac215..ff9e8e80 100644 --- a/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.h +++ b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.h @@ -3,6 +3,7 @@ #include "tlm.h" #include "../../common/dramExtension.h" +#include "../core/configuration/Configuration.h" typedef tlm::tlm_generic_payload gp; @@ -11,11 +12,12 @@ using namespace std; class ReadyBatch { public: - ReadyBatch(unsigned int fifosize) : fifosize(fifosize){} + ReadyBatch(); bool addTransaction(gp* payload); private: std::deque readybatch; unsigned int fifosize; + sc_time thresholdAge; Row getRow(); sc_time getTimeOfOldestRequest(); From df9368b1fd35cd83df0cd1a7cdea0fa59ead0a75 Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Wed, 1 Mar 2017 17:22:01 +0100 Subject: [PATCH 05/39] 1st implementation SMS batch scheduler --- .../src/controller/scheduler/ReadyBatch.cpp | 10 ++ .../src/controller/scheduler/ReadyBatch.h | 4 +- .../src/controller/scheduler/SMS.cpp | 170 ++++++++++++++++++ .../simulator/src/controller/scheduler/SMS.h | 30 +++- 4 files changed, 211 insertions(+), 3 deletions(-) diff --git a/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp index af218173..84af0d69 100644 --- a/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp @@ -41,3 +41,13 @@ bool ReadyBatch::addTransaction(gp* payload) return true; } } + +std::deque& ReadyBatch::getTransactions() +{ + return readybatch; +} + +bool ReadyBatch::isEmpty() +{ + return readybatch.empty(); +} diff --git a/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.h b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.h index ff9e8e80..5e2e8f49 100644 --- a/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.h +++ b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.h @@ -14,6 +14,9 @@ class ReadyBatch public: ReadyBatch(); bool addTransaction(gp* payload); + unsigned int getNumRequests(); + std::deque& getTransactions(); + bool isEmpty(); private: std::deque readybatch; unsigned int fifosize; @@ -21,7 +24,6 @@ private: Row getRow(); sc_time getTimeOfOldestRequest(); - unsigned int getNumRequests(); }; #endif // READYBATCH_H diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index a3ae0867..252300b1 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -5,6 +5,16 @@ using namespace std; void SMS::schedule(gp *payload) { buffer[DramExtension::getExtension(payload).getThread()].emplace_back(payload); + + Thread thread = DramExtension::getExtension(payload).getThread(); + // update memory request counter + memrequestcounter[thread]++; + inFlightMemRequestCounter[thread]++; + + // update memory request intensity + sc_time lastrequestTimeOfGeneration = GenerationExtension::getExtension(payload).TimeOfGeneration(); + sc_time memClk = Configuration::getInstance().memSpec.clk; + memoryIntensity[thread] = (memrequestcounter[thread] * 1000.0 * memClk) / lastrequestTimeOfGeneration; // in MPKC } std::pair SMS::getNextRequest(Bank bank) @@ -20,6 +30,7 @@ std::pair SMS::getNextRequest(Bank bank) if (command == Command::Read || command == Command::ReadA || command == Command::Write || command == Command::WriteA) { + inFlightMemRequestCounter[DramExtension::getExtension(payload).getThread()]--; bankbuffer[bank].pop_front(); } @@ -27,3 +38,162 @@ std::pair SMS::getNextRequest(Bank bank) } } + +unsigned int SMS::totalMemoryRequests() +{ + //TODO: recheck this? how about total in-flight requests instead? + unsigned int totalSize = 0; + for (auto &reqQueue : buffer) + { + totalSize += reqQueue.second.size(); + } + return totalSize; +} + +void SMS::batchFormation() +{ + if (existReadyBatch()) + { + SC_REPORT_FATAL("SMS", "Form ready batches when exist at least a ready batch"); + } + else + { + auto totalNumThreads = Configuration::getInstance().NumberOfTracePlayers; + for (auto threadID = 1; threadID <= totalNumThreads; threadID++) + { + batchFormation(Thread(threadID)); + } + } +} + +void SMS::batchScheduler() +{ + while (true) + { + srand(time(NULL)); + bool isSJF = (rand() % 100) < SJFprobability; + if (!existReadyBatch()) + { + // bypass low memory intensity thread + + // bypass if system is lightly load + if (totalMemoryRequests() <= 16 && totalMemoryRequests() > 0) //TODO how about buffer empty? + { + bypassRequests(); + } + else + { + batchFormation(); + if (isSJF) + { + selectSJF() + } + else + { + selectRR(); + } + } + } + else if (isSJF) + { + selectSJF() + } + else + { + selectRR(); + } + } +} + +void SMS::selectSJF() +{ + // find shorstest thread + unsigned int minThread = 1 + auto totalNumThreads = Configuration::getInstance().NumberOfTracePlayers; + for (auto threadID = 2; threadID <= totalNumThreads; threadID++) + { + if (memrequestcounter[Thread(threadID)] <= memrequestcounter[Thread(minThread)]) + { + minThread = threadID; + } + } + + // drain to bank buffers + std::deque requestPtrs = readybatches[Thread(minThread)]->getTransactions(); + for (auto intr = requestPtrs.begin(); intr != requestPtrs.end(); intr++) + { + Bank bank = DramExtension::getExtension(*intr).getBank(); + bankbuffer.emplace(bank, *intr); + } + requestPtrs.clear(); + + // reform the drained ready batch + // batchFormation(Thread(minThread)); +} + +void SMS::selectRR() +{ + static std::map::iterator next = readybatches.begin(); + + // drain to bank buffers + std::deque requestPtrs = (*next).second->getTransactions(); + for (auto intr = requestPtrs.begin(); intr != requestPtrs.end(); intr++) + { + Bank bank = DramExtension::getExtension(*intr).getBank(); + bankbuffer.emplace(bank, *intr); + } + requestPtrs.clear(); + + // reform the drained ready batch + // batchFormation((*next).first); + + // point to next pair + do + { + next++; + if (next == readybatches.end()) + { + next = readybatches.begin(); + } + } while ((*next).second->isEmpty()); +} + +bool SMS::existReadyBatch() +{ + for (auto& thread_readybatch : readybatches) + { + if (!thread_readybatch.second->isEmpty()) + { + return true; + } + } + return false; +} + +void SMS::batchFormation(Thread thread) +{ + if (!readybatches[thread]->isEmpty()) + { + SC_REPORT_FATAL("SMS", "Ready batch formation for non empty ready batch"); + } + else + { + while (!buffer[thread].empty() && readybatches[thread]->addTransaction(buffer[thread].front())) + { + buffer[thread].pop_front(); + } + } +} + +void SMS::bypassRequests() +{ + for(auto& thread_requests : buffer) + { + for(auto request = thread_requests.second.begin(); request != thread_requests.second.end(); request++) + { + Bank bank = DramExtension::getExtension(*request).getBank(); + bankbuffer[bank].emplace_back(request); + thread_requests.second.erase(request); + } + } +} diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h index d6fde08a..9f871776 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.h +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h @@ -1,17 +1,31 @@ #ifndef SMS_H #define SMS_H +#include +#include +#include "sysc/utils/sc_report.h" #include "IScheduler.h" #include "../core/ControllerCore.h" #include "../core/configuration/Configuration.h" #include "../../common/dramExtension.h" +#define MIN_TOTAL_REQ 16 + using namespace std; class SMS: public sc_module, public IScheduler { public: - SMS(ControllerCore &controllerCore, unsigned int SJFprobability) : IScheduler(controllerCore), SJFprobability(SJFprobability){} + SMS(ControllerCore &controllerCore, unsigned int SJFprobability) : IScheduler(controllerCore), SJFprobability(SJFprobability) + { + // initialize memory request counter & memory request intensity for each thread + auto totalNumThreads = Configuration::getInstance().NumberOfTracePlayers; + for (auto threadID = 1; threadID <= totalNumThreads; threadID++) + { + memrequestcounter.emplace(Thread(threadID), 0); + memoryIntensity.emplace(Thread(threadID), 0); + } + } virtual ~SMS(){} virtual void schedule(gp *payload) override; virtual std::pair getNextRequest(Bank bank) override; @@ -19,8 +33,20 @@ public: private: std::map> buffer; std::map> bankbuffer; - + std::map readybatches; + std::map memrequestcounter; + std::map inFlightMemRequestCounter; + std::map memoryIntensity; unsigned int SJFprobability; + + void batchScheduler(); + unsigned int totalMemoryRequests(); + void batchFormation(); + void selectSJF(); + void selectRR(); + bool existReadyBatch(); + void batchFormation(Thread thread); + void bypassRequests(); }; #endif // SMS_H From 725d7e9d19fa88e66519924626503f260bd05e06 Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Fri, 3 Mar 2017 03:20:37 +0100 Subject: [PATCH 06/39] Fix compile errors & warnings # Explain what has been changed # Explain why this change is being made # Provide links to any relevant tickets, articles or other resources --- .../analyzer/businessObjects/phases/phase.h | 14 ++++++------- DRAMSys/analyzer/businessObjects/timespan.h | 3 ++- .../src/common/tlm2_base_protocol_checker.h | 6 +++--- DRAMSys/simulator/src/controller/Controller.h | 2 +- .../src/controller/scheduler/ReadyBatch.cpp | 4 ++-- .../src/controller/scheduler/SMS.cpp | 20 +++++++++---------- .../simulator/src/controller/scheduler/SMS.h | 5 +++-- 7 files changed, 28 insertions(+), 26 deletions(-) diff --git a/DRAMSys/analyzer/businessObjects/phases/phase.h b/DRAMSys/analyzer/businessObjects/phases/phase.h index 62c5ea27..ef8d187a 100644 --- a/DRAMSys/analyzer/businessObjects/phases/phase.h +++ b/DRAMSys/analyzer/businessObjects/phases/phase.h @@ -180,7 +180,7 @@ public: using AUTO_REFRESH::AUTO_REFRESH; protected: virtual QString Name() const override {return "REFA";} - virtual bool isBankwise() const {return false;} + virtual bool isBankwise() const override {return false;} }; class REFB : public AUTO_REFRESH @@ -201,7 +201,7 @@ protected: virtual std::vector getTimesOnCommandBus() const {return {span.Begin()};} virtual QColor getColor(const TraceDrawingProperties &drawingProperties) const override {Q_UNUSED(drawingProperties) return getPhaseColor();} virtual QColor getPhaseColor() const override {return ColorGenerator::getColor(10);} - virtual bool isBankwise() const {return false;} + virtual bool isBankwise() const override {return false;} }; class PDNAB : public Phase @@ -222,7 +222,7 @@ public: using PDNAB::PDNAB; protected: virtual QString Name() const override {return "PDNA";} - virtual bool isBankwise() const {return false;} + virtual bool isBankwise() const override {return false;} }; class PDNPB : public Phase @@ -243,7 +243,7 @@ public: using PDNPB::PDNPB; protected: virtual QString Name() const override {return "PDNP";} - virtual bool isBankwise() const {return false;} + virtual bool isBankwise() const override {return false;} }; class SREFB : public Phase @@ -251,8 +251,8 @@ class SREFB : public Phase public: using Phase::Phase; protected: - virtual QString Name() const {return "SREFB";} - virtual Qt::BrushStyle getBrushStyle() const {return Qt::Dense1Pattern;} + virtual QString Name() const override {return "SREFB";} + virtual Qt::BrushStyle getBrushStyle() const override {return Qt::Dense1Pattern;} virtual QColor getColor(const TraceDrawingProperties &drawingProperties) const override {Q_UNUSED(drawingProperties) return getPhaseColor();} virtual QColor getPhaseColor() const override {return QColor(Qt::black);} virtual Phase::PhaseSymbol getPhaseSymbol() const override {return PhaseSymbol::Rect;} @@ -264,7 +264,7 @@ public: using SREFB::SREFB; protected: virtual QString Name() const override {return "SREF";} - virtual bool isBankwise() const {return false;} + virtual bool isBankwise() const override {return false;} }; diff --git a/DRAMSys/analyzer/businessObjects/timespan.h b/DRAMSys/analyzer/businessObjects/timespan.h index c54f99b0..dcc32839 100644 --- a/DRAMSys/analyzer/businessObjects/timespan.h +++ b/DRAMSys/analyzer/businessObjects/timespan.h @@ -38,6 +38,7 @@ #ifndef TIMESPAN_H #define TIMESPAN_H #include +#include #include "tracetime.h" class Timespan @@ -47,7 +48,7 @@ class Timespan public: Timespan(traceTime begin = 0, traceTime end = 0) : begin(begin), end(end){} - traceTime timeCovered() const{return abs(End()-Begin());} + traceTime timeCovered() const{return std::abs(End()-Begin());} traceTime Begin() const{return begin;} void setBegin(traceTime time){begin = time;} traceTime End() const{return end;} diff --git a/DRAMSys/simulator/src/common/tlm2_base_protocol_checker.h b/DRAMSys/simulator/src/common/tlm2_base_protocol_checker.h index eb0833a1..99b5ce10 100755 --- a/DRAMSys/simulator/src/common/tlm2_base_protocol_checker.h +++ b/DRAMSys/simulator/src/common/tlm2_base_protocol_checker.h @@ -343,7 +343,7 @@ void tlm2_base_protocol_checker:: BOILERPLATE b_transport_pre_checks( - tlm::tlm_generic_payload& trans, sc_core::sc_time& delay) + tlm::tlm_generic_payload& trans, sc_core::sc_time& /*delay*/) { ++ m_map[&trans].b_call; @@ -372,7 +372,7 @@ b_transport_pre_checks( BOILERPLATE b_transport_post_checks( - tlm::tlm_generic_payload& trans, sc_core::sc_time& delay) + tlm::tlm_generic_payload& trans, sc_core::sc_time& /*delay*/) { check_response_path(trans, "b_transport"); check_trans_not_modified(trans, "b_transport"); @@ -914,7 +914,7 @@ get_direct_mem_ptr_pre_checks( BOILERPLATE -get_direct_mem_ptr_post_checks( tlm::tlm_generic_payload& trans, tlm::tlm_dmi& dmi_data ) +get_direct_mem_ptr_post_checks( tlm::tlm_generic_payload& trans, tlm::tlm_dmi& /*dmi_data*/ ) { tlm::tlm_generic_payload* init = m_map[&trans].gp; diff --git a/DRAMSys/simulator/src/controller/Controller.h b/DRAMSys/simulator/src/controller/Controller.h index a1286d1f..77de4bf3 100644 --- a/DRAMSys/simulator/src/controller/Controller.h +++ b/DRAMSys/simulator/src/controller/Controller.h @@ -110,7 +110,7 @@ private: void buildScheduler(); void payloadEntersSystem(tlm_generic_payload& payload); void payloadLeavesSystem(tlm_generic_payload& payload); - void scheduleNextFromScheduler(Bank bank); + void scheduleNextFromScheduler(Bank bank) override; // --- FRONTEND ------ tlm_sync_enum nb_transport_fw(tlm_generic_payload& payload, tlm_phase& phase, sc_time& fwDelay); diff --git a/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp index 84af0d69..2200a6f4 100644 --- a/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp @@ -3,7 +3,7 @@ ReadyBatch::ReadyBatch() { fifosize = Configuration::getInstance().ReadyBatchSize; - thresholdAge(Configuration::getInstance().ReadyBatchThresholdAge, SC_NS); + thresholdAge = sc_time(Configuration::getInstance().ReadyBatchThresholdAge, SC_NS); } unsigned int ReadyBatch::getNumRequests() @@ -34,7 +34,7 @@ bool ReadyBatch::addTransaction(gp* payload) { sc_time currentAge = sc_time_stamp() - getTimeOfOldestRequest(); Row newRow = DramExtension::getExtension(payload).getRow(); - if (getNumRequests == fifosize || currentAge >= thresholdAge || newRow != getRow()) { + if (getNumRequests() == fifosize || currentAge >= thresholdAge || newRow != getRow()) { return false; } else { readybatch.emplace_back(payload); diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index 252300b1..7e9fd5b5 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -58,8 +58,8 @@ void SMS::batchFormation() } else { - auto totalNumThreads = Configuration::getInstance().NumberOfTracePlayers; - for (auto threadID = 1; threadID <= totalNumThreads; threadID++) + unsigned int totalNumThreads = Configuration::getInstance().NumberOfTracePlayers; + for (unsigned int threadID = 1; threadID <= totalNumThreads; threadID++) { batchFormation(Thread(threadID)); } @@ -86,7 +86,7 @@ void SMS::batchScheduler() batchFormation(); if (isSJF) { - selectSJF() + selectSJF(); } else { @@ -96,7 +96,7 @@ void SMS::batchScheduler() } else if (isSJF) { - selectSJF() + selectSJF(); } else { @@ -108,9 +108,9 @@ void SMS::batchScheduler() void SMS::selectSJF() { // find shorstest thread - unsigned int minThread = 1 - auto totalNumThreads = Configuration::getInstance().NumberOfTracePlayers; - for (auto threadID = 2; threadID <= totalNumThreads; threadID++) + unsigned int minThread = 1; + unsigned int totalNumThreads = Configuration::getInstance().NumberOfTracePlayers; + for (unsigned int threadID = 2; threadID <= totalNumThreads; threadID++) { if (memrequestcounter[Thread(threadID)] <= memrequestcounter[Thread(minThread)]) { @@ -123,7 +123,7 @@ void SMS::selectSJF() for (auto intr = requestPtrs.begin(); intr != requestPtrs.end(); intr++) { Bank bank = DramExtension::getExtension(*intr).getBank(); - bankbuffer.emplace(bank, *intr); + bankbuffer[bank].emplace_back(*intr); } requestPtrs.clear(); @@ -140,7 +140,7 @@ void SMS::selectRR() for (auto intr = requestPtrs.begin(); intr != requestPtrs.end(); intr++) { Bank bank = DramExtension::getExtension(*intr).getBank(); - bankbuffer.emplace(bank, *intr); + bankbuffer[bank].emplace_back(*intr); } requestPtrs.clear(); @@ -192,7 +192,7 @@ void SMS::bypassRequests() for(auto request = thread_requests.second.begin(); request != thread_requests.second.end(); request++) { Bank bank = DramExtension::getExtension(*request).getBank(); - bankbuffer[bank].emplace_back(request); + bankbuffer[bank].emplace_back(*request); thread_requests.second.erase(request); } } diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h index 9f871776..6b7853a6 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.h +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h @@ -5,6 +5,7 @@ #include #include "sysc/utils/sc_report.h" #include "IScheduler.h" +#include "ReadyBatch.h" #include "../core/ControllerCore.h" #include "../core/configuration/Configuration.h" #include "../../common/dramExtension.h" @@ -19,8 +20,8 @@ public: SMS(ControllerCore &controllerCore, unsigned int SJFprobability) : IScheduler(controllerCore), SJFprobability(SJFprobability) { // initialize memory request counter & memory request intensity for each thread - auto totalNumThreads = Configuration::getInstance().NumberOfTracePlayers; - for (auto threadID = 1; threadID <= totalNumThreads; threadID++) + unsigned int totalNumThreads = Configuration::getInstance().NumberOfTracePlayers; + for (unsigned int threadID = 1; threadID <= totalNumThreads; threadID++) { memrequestcounter.emplace(Thread(threadID), 0); memoryIntensity.emplace(Thread(threadID), 0); From 73eb716deb50dd2789d97b871791657e5a3e55db Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Fri, 3 Mar 2017 03:32:18 +0100 Subject: [PATCH 07/39] Implement batch scheduler as a SYSTEMC process # Explain what has been changed # Explain why this change is being made # Provide links to any relevant tickets, articles or other resources --- DRAMSys/simulator/src/controller/scheduler/SMS.cpp | 3 +++ DRAMSys/simulator/src/controller/scheduler/SMS.h | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index 7e9fd5b5..4e8a86fb 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -68,8 +68,11 @@ void SMS::batchFormation() void SMS::batchScheduler() { + sc_time memClk = Configuration::getInstance().memSpec.clk; while (true) { + wait(memClk); + srand(time(NULL)); bool isSJF = (rand() % 100) < SJFprobability; if (!existReadyBatch()) diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h index 6b7853a6..bb60f447 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.h +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h @@ -26,10 +26,13 @@ public: memrequestcounter.emplace(Thread(threadID), 0); memoryIntensity.emplace(Thread(threadID), 0); } + SC_THREAD(batchScheduler); } + SC_HAS_PROCESS(SMS); virtual ~SMS(){} virtual void schedule(gp *payload) override; virtual std::pair getNextRequest(Bank bank) override; + void batchScheduler(); private: std::map> buffer; @@ -40,7 +43,6 @@ private: std::map memoryIntensity; unsigned int SJFprobability; - void batchScheduler(); unsigned int totalMemoryRequests(); void batchFormation(); void selectSJF(); From ee006952de61c95ec1114ef8ae2b115ee089c991 Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Wed, 8 Mar 2017 00:11:47 +0100 Subject: [PATCH 08/39] Safeguard against empty buffer & bypass low memory intensity request # Explain what has been changed # Explain why this change is being made # Provide links to any relevant tickets, articles or other resources --- .../src/controller/scheduler/SMS.cpp | 111 ++++++++++++------ .../simulator/src/controller/scheduler/SMS.h | 5 +- 2 files changed, 77 insertions(+), 39 deletions(-) diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index 4e8a86fb..4790edb7 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -50,19 +50,22 @@ unsigned int SMS::totalMemoryRequests() return totalSize; } -void SMS::batchFormation() +bool SMS::batchFormation() { if (existReadyBatch()) { + return false; SC_REPORT_FATAL("SMS", "Form ready batches when exist at least a ready batch"); } else { + bool isBatchForm = false; unsigned int totalNumThreads = Configuration::getInstance().NumberOfTracePlayers; for (unsigned int threadID = 1; threadID <= totalNumThreads; threadID++) { - batchFormation(Thread(threadID)); + isBatchForm = isBatchForm || batchFormation(Thread(threadID)); } + return isBatchForm; } } @@ -77,33 +80,31 @@ void SMS::batchScheduler() bool isSJF = (rand() % 100) < SJFprobability; if (!existReadyBatch()) { - // bypass low memory intensity thread - - // bypass if system is lightly load - if (totalMemoryRequests() <= 16 && totalMemoryRequests() > 0) //TODO how about buffer empty? + if (totalMemoryRequests() == 0) { + continue; + } + else if (totalMemoryRequests() <= 16 && totalMemoryRequests() > 0) + { + // bypass if system is lightly load bypassRequests(); } - else + else if (totalMemoryRequests() > 16) { - batchFormation(); - if (isSJF) + // bypass low memory intensity thread + bypassLowMemoryIntensity(); + + // pick & drain a ready batch + if (batchFormation()) { - selectSJF(); - } - else - { - selectRR(); + isSJF ? selectSJF() : selectRR(); } } } - else if (isSJF) - { - selectSJF(); - } else { - selectRR(); + // pick & drain a ready batch + isSJF ? selectSJF() : selectRR(); } } } @@ -115,7 +116,7 @@ void SMS::selectSJF() unsigned int totalNumThreads = Configuration::getInstance().NumberOfTracePlayers; for (unsigned int threadID = 2; threadID <= totalNumThreads; threadID++) { - if (memrequestcounter[Thread(threadID)] <= memrequestcounter[Thread(minThread)]) + if (inFlightMemRequestCounter[Thread(threadID)] <= inFlightMemRequestCounter[Thread(minThread)]) { minThread = threadID; } @@ -123,12 +124,15 @@ void SMS::selectSJF() // drain to bank buffers std::deque requestPtrs = readybatches[Thread(minThread)]->getTransactions(); - for (auto intr = requestPtrs.begin(); intr != requestPtrs.end(); intr++) + if (!requestPtrs.empty()) { - Bank bank = DramExtension::getExtension(*intr).getBank(); - bankbuffer[bank].emplace_back(*intr); + for (auto intr = requestPtrs.begin(); intr != requestPtrs.end(); intr++) + { + Bank bank = DramExtension::getExtension(*intr).getBank(); + bankbuffer[bank].emplace_back(*intr); + } + requestPtrs.clear(); } - requestPtrs.clear(); // reform the drained ready batch // batchFormation(Thread(minThread)); @@ -140,25 +144,38 @@ void SMS::selectRR() // drain to bank buffers std::deque requestPtrs = (*next).second->getTransactions(); - for (auto intr = requestPtrs.begin(); intr != requestPtrs.end(); intr++) + if (!requestPtrs.empty()) { - Bank bank = DramExtension::getExtension(*intr).getBank(); - bankbuffer[bank].emplace_back(*intr); + for (auto intr = requestPtrs.begin(); intr != requestPtrs.end(); intr++) + { + Bank bank = DramExtension::getExtension(*intr).getBank(); + bankbuffer[bank].emplace_back(*intr); + } + requestPtrs.clear(); } - requestPtrs.clear(); // reform the drained ready batch // batchFormation((*next).first); // point to next pair - do + if (existReadyBatch()) { - next++; - if (next == readybatches.end()) + do { - next = readybatches.begin(); - } - } while ((*next).second->isEmpty()); + next++; + if (next == readybatches.end()) + { + next = readybatches.begin(); + } + } while ((*next).second->isEmpty()); + } + else + { + // point to next empty ready batch, later call to batchScheduler() will call batchFormation() + // this next empty ready batch will be refilled + next++; + } + } bool SMS::existReadyBatch() @@ -173,10 +190,11 @@ bool SMS::existReadyBatch() return false; } -void SMS::batchFormation(Thread thread) +bool SMS::batchFormation(Thread thread) { if (!readybatches[thread]->isEmpty()) { + return false; SC_REPORT_FATAL("SMS", "Ready batch formation for non empty ready batch"); } else @@ -185,14 +203,15 @@ void SMS::batchFormation(Thread thread) { buffer[thread].pop_front(); } + return !readybatches[thread]->isEmpty(); } } void SMS::bypassRequests() { - for(auto& thread_requests : buffer) + for (auto& thread_requests : buffer) { - for(auto request = thread_requests.second.begin(); request != thread_requests.second.end(); request++) + for (auto request = thread_requests.second.begin(); request != thread_requests.second.end(); request++) { Bank bank = DramExtension::getExtension(*request).getBank(); bankbuffer[bank].emplace_back(*request); @@ -200,3 +219,21 @@ void SMS::bypassRequests() } } } + +void SMS::bypassLowMemoryIntensity() +{ + unsigned int totalNumThreads = Configuration::getInstance().NumberOfTracePlayers; + for (unsigned int threadID = 1; threadID <= totalNumThreads; threadID++) + { + if (memoryIntensity[Thread(threadID)] < 1 && memoryIntensity[Thread(threadID)] > 0) + { + for (auto request = buffer[Thread(threadID)].begin(); + request != buffer[Thread(threadID)].end(); request++) + { + Bank bank = DramExtension::getExtension(*request).getBank(); + bankbuffer[bank].emplace_back(*request); + buffer[Thread(threadID)].erase(request); + } + } + } +} diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h index bb60f447..7989bd08 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.h +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h @@ -44,12 +44,13 @@ private: unsigned int SJFprobability; unsigned int totalMemoryRequests(); - void batchFormation(); + bool batchFormation(); void selectSJF(); void selectRR(); bool existReadyBatch(); - void batchFormation(Thread thread); + bool batchFormation(Thread thread); void bypassRequests(); + void bypassLowMemoryIntensity(); }; #endif // SMS_H From 37435b6285bdfc76bd90bd60e8487fc2e9698318 Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Wed, 8 Mar 2017 00:19:36 +0100 Subject: [PATCH 09/39] Initialize in-flight memory request counters # Explain what has been changed # Explain why this change is being made # Provide links to any relevant tickets, articles or other resources --- DRAMSys/simulator/src/controller/scheduler/SMS.h | 1 + 1 file changed, 1 insertion(+) diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h index 7989bd08..00fe6877 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.h +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h @@ -25,6 +25,7 @@ public: { memrequestcounter.emplace(Thread(threadID), 0); memoryIntensity.emplace(Thread(threadID), 0); + inFlightMemRequestCounter.emplace(Thread(threadID), 0); } SC_THREAD(batchScheduler); } From a0227b2a6005f15cf12fbb9406c7c8a3b1b0458b Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Wed, 8 Mar 2017 23:50:19 +0100 Subject: [PATCH 10/39] Remove unnecessary functions, keep it simple for testing # Explain what has been changed # Explain why this change is being made # Provide links to any relevant tickets, articles or other resources --- .../src/controller/scheduler/ReadyBatch.cpp | 38 +++--- .../src/controller/scheduler/ReadyBatch.h | 4 +- .../src/controller/scheduler/SMS.cpp | 109 ++++++++---------- .../simulator/src/controller/scheduler/SMS.h | 14 +-- 4 files changed, 75 insertions(+), 90 deletions(-) diff --git a/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp index 2200a6f4..91aa48db 100644 --- a/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp @@ -6,35 +6,35 @@ ReadyBatch::ReadyBatch() thresholdAge = sc_time(Configuration::getInstance().ReadyBatchThresholdAge, SC_NS); } -unsigned int ReadyBatch::getNumRequests() -{ - return readybatch.size(); -} +//unsigned int ReadyBatch::getNumRequests() +//{ +// return readybatch.size(); +//} Row ReadyBatch::getRow() { return DramExtension::getExtension(readybatch.front()).getRow(); } -sc_time ReadyBatch::getTimeOfOldestRequest() -{ - sc_time oldestTime = sc_time_stamp(); - for (auto reqPayload = readybatch.begin(); reqPayload != readybatch.end(); reqPayload++) - { - sc_time requestTimeOfGeneration = GenerationExtension::getExtension(*reqPayload).TimeOfGeneration(); - if (requestTimeOfGeneration < oldestTime) - { - oldestTime = requestTimeOfGeneration; - } - } - return oldestTime; -} +//sc_time ReadyBatch::getTimeOfOldestRequest() +//{ +// sc_time oldestTime = sc_time_stamp(); +// for (auto reqPayload = readybatch.begin(); reqPayload != readybatch.end(); reqPayload++) +// { +// sc_time requestTimeOfGeneration = GenerationExtension::getExtension(*reqPayload).TimeOfGeneration(); +// if (requestTimeOfGeneration < oldestTime) +// { +// oldestTime = requestTimeOfGeneration; +// } +// } +// return oldestTime; +//} bool ReadyBatch::addTransaction(gp* payload) { - sc_time currentAge = sc_time_stamp() - getTimeOfOldestRequest(); +// sc_time currentAge = sc_time_stamp() - getTimeOfOldestRequest(); Row newRow = DramExtension::getExtension(payload).getRow(); - if (getNumRequests() == fifosize || currentAge >= thresholdAge || newRow != getRow()) { + if (/*getNumRequests() == fifosize || currentAge >= thresholdAge || */newRow != getRow()) { return false; } else { readybatch.emplace_back(payload); diff --git a/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.h b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.h index 5e2e8f49..c35640a5 100644 --- a/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.h +++ b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.h @@ -14,7 +14,7 @@ class ReadyBatch public: ReadyBatch(); bool addTransaction(gp* payload); - unsigned int getNumRequests(); +// unsigned int getNumRequests(); std::deque& getTransactions(); bool isEmpty(); private: @@ -23,7 +23,7 @@ private: sc_time thresholdAge; Row getRow(); - sc_time getTimeOfOldestRequest(); +// sc_time getTimeOfOldestRequest(); }; #endif // READYBATCH_H diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index 4790edb7..147cea6e 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -8,13 +8,13 @@ void SMS::schedule(gp *payload) Thread thread = DramExtension::getExtension(payload).getThread(); // update memory request counter - memrequestcounter[thread]++; +// memrequestcounter[thread]++; inFlightMemRequestCounter[thread]++; // update memory request intensity - sc_time lastrequestTimeOfGeneration = GenerationExtension::getExtension(payload).TimeOfGeneration(); - sc_time memClk = Configuration::getInstance().memSpec.clk; - memoryIntensity[thread] = (memrequestcounter[thread] * 1000.0 * memClk) / lastrequestTimeOfGeneration; // in MPKC +// sc_time lastrequestTimeOfGeneration = GenerationExtension::getExtension(payload).TimeOfGeneration(); +// sc_time memClk = Configuration::getInstance().memSpec.clk; +// memoryIntensity[thread] = (memrequestcounter[thread] * 1000.0 * memClk) / lastrequestTimeOfGeneration; // in MPKC } std::pair SMS::getNextRequest(Bank bank) @@ -39,16 +39,16 @@ std::pair SMS::getNextRequest(Bank bank) } -unsigned int SMS::totalMemoryRequests() -{ - //TODO: recheck this? how about total in-flight requests instead? - unsigned int totalSize = 0; - for (auto &reqQueue : buffer) - { - totalSize += reqQueue.second.size(); - } - return totalSize; -} +//unsigned int SMS::totalMemoryRequests() +//{ +// //TODO: recheck this? how about total in-flight requests instead? +// unsigned int totalSize = 0; +// for (auto &reqQueue : buffer) +// { +// totalSize += reqQueue.second.size(); +// } +// return totalSize; +//} bool SMS::batchFormation() { @@ -80,25 +80,10 @@ void SMS::batchScheduler() bool isSJF = (rand() % 100) < SJFprobability; if (!existReadyBatch()) { - if (totalMemoryRequests() == 0) + // pick & drain a ready batch + if (batchFormation()) { - continue; - } - else if (totalMemoryRequests() <= 16 && totalMemoryRequests() > 0) - { - // bypass if system is lightly load - bypassRequests(); - } - else if (totalMemoryRequests() > 16) - { - // bypass low memory intensity thread - bypassLowMemoryIntensity(); - - // pick & drain a ready batch - if (batchFormation()) - { - isSJF ? selectSJF() : selectRR(); - } + isSJF ? selectSJF() : selectRR(); } } else @@ -207,33 +192,33 @@ bool SMS::batchFormation(Thread thread) } } -void SMS::bypassRequests() -{ - for (auto& thread_requests : buffer) - { - for (auto request = thread_requests.second.begin(); request != thread_requests.second.end(); request++) - { - Bank bank = DramExtension::getExtension(*request).getBank(); - bankbuffer[bank].emplace_back(*request); - thread_requests.second.erase(request); - } - } -} - -void SMS::bypassLowMemoryIntensity() -{ - unsigned int totalNumThreads = Configuration::getInstance().NumberOfTracePlayers; - for (unsigned int threadID = 1; threadID <= totalNumThreads; threadID++) - { - if (memoryIntensity[Thread(threadID)] < 1 && memoryIntensity[Thread(threadID)] > 0) - { - for (auto request = buffer[Thread(threadID)].begin(); - request != buffer[Thread(threadID)].end(); request++) - { - Bank bank = DramExtension::getExtension(*request).getBank(); - bankbuffer[bank].emplace_back(*request); - buffer[Thread(threadID)].erase(request); - } - } - } -} +//void SMS::bypassRequests() +//{ +// for (auto& thread_requests : buffer) +// { +// for (auto request = thread_requests.second.begin(); request != thread_requests.second.end(); request++) +// { +// Bank bank = DramExtension::getExtension(*request).getBank(); +// bankbuffer[bank].emplace_back(*request); +// thread_requests.second.erase(request); +// } +// } +//} +// +//void SMS::bypassLowMemoryIntensity() +//{ +// unsigned int totalNumThreads = Configuration::getInstance().NumberOfTracePlayers; +// for (unsigned int threadID = 1; threadID <= totalNumThreads; threadID++) +// { +// if (memoryIntensity[Thread(threadID)] < 1 && memoryIntensity[Thread(threadID)] > 0) +// { +// for (auto request = buffer[Thread(threadID)].begin(); +// request != buffer[Thread(threadID)].end(); request++) +// { +// Bank bank = DramExtension::getExtension(*request).getBank(); +// bankbuffer[bank].emplace_back(*request); +// buffer[Thread(threadID)].erase(request); +// } +// } +// } +//} diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h index 00fe6877..71f7aa96 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.h +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h @@ -23,8 +23,8 @@ public: unsigned int totalNumThreads = Configuration::getInstance().NumberOfTracePlayers; for (unsigned int threadID = 1; threadID <= totalNumThreads; threadID++) { - memrequestcounter.emplace(Thread(threadID), 0); - memoryIntensity.emplace(Thread(threadID), 0); +// memrequestcounter.emplace(Thread(threadID), 0); +// memoryIntensity.emplace(Thread(threadID), 0); inFlightMemRequestCounter.emplace(Thread(threadID), 0); } SC_THREAD(batchScheduler); @@ -39,19 +39,19 @@ private: std::map> buffer; std::map> bankbuffer; std::map readybatches; - std::map memrequestcounter; +// std::map memrequestcounter; std::map inFlightMemRequestCounter; - std::map memoryIntensity; +// std::map memoryIntensity; unsigned int SJFprobability; - unsigned int totalMemoryRequests(); +// unsigned int totalMemoryRequests(); bool batchFormation(); void selectSJF(); void selectRR(); bool existReadyBatch(); bool batchFormation(Thread thread); - void bypassRequests(); - void bypassLowMemoryIntensity(); +// void bypassRequests(); +// void bypassLowMemoryIntensity(); }; #endif // SMS_H From 904ee688be8f5b1c5674e6acc205f2ae18482df2 Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Mon, 13 Mar 2017 17:33:49 +0100 Subject: [PATCH 11/39] Add test traces # Explain what has been changed # Explain why this change is being made # Provide links to any relevant tickets, articles or other resources --- DRAMSys/simulator/resources/simulations/sim-batch.xml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/DRAMSys/simulator/resources/simulations/sim-batch.xml b/DRAMSys/simulator/resources/simulations/sim-batch.xml index dcc783d9..fbd47695 100644 --- a/DRAMSys/simulator/resources/simulations/sim-batch.xml +++ b/DRAMSys/simulator/resources/simulations/sim-batch.xml @@ -6,7 +6,7 @@ - + @@ -44,7 +44,10 @@ - chstone-adpcm_32.stl + t1.stl + t2.stl + t3.stl + t4.stl From 7626b8b6b5a410aff0ff80325bc1dcc24f6ace07 Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Mon, 13 Mar 2017 17:34:13 +0100 Subject: [PATCH 12/39] Fix bugs # Explain what has been changed # Explain why this change is being made # Provide links to any relevant tickets, articles or other resources --- DRAMSys/simulator/src/controller/Controller.cpp | 2 +- .../src/controller/scheduler/ReadyBatch.cpp | 11 +++++++++-- .../simulator/src/controller/scheduler/ReadyBatch.h | 1 + DRAMSys/simulator/src/controller/scheduler/SMS.h | 12 ++++++++++-- 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/DRAMSys/simulator/src/controller/Controller.cpp b/DRAMSys/simulator/src/controller/Controller.cpp index b16f981b..56e27215 100644 --- a/DRAMSys/simulator/src/controller/Controller.cpp +++ b/DRAMSys/simulator/src/controller/Controller.cpp @@ -55,7 +55,7 @@ void Controller::buildScheduler() } else if (selectedScheduler == "SMS") { - scheduler = new SMS(*controllerCore, Configuration::getInstance().SJFProbability); + scheduler = new SMS("SMS", *controllerCore, Configuration::getInstance().SJFProbability); } //else if (selectedScheduler == "PAR_BS") //{ diff --git a/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp index 91aa48db..af2a624b 100644 --- a/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp @@ -6,6 +6,11 @@ ReadyBatch::ReadyBatch() thresholdAge = sc_time(Configuration::getInstance().ReadyBatchThresholdAge, SC_NS); } +ReadyBatch::~ReadyBatch() +{ + +} + //unsigned int ReadyBatch::getNumRequests() //{ // return readybatch.size(); @@ -13,7 +18,8 @@ ReadyBatch::ReadyBatch() Row ReadyBatch::getRow() { - return DramExtension::getExtension(readybatch.front()).getRow(); + gp*& firstPayload = readybatch.front(); + return DramExtension::getExtension(firstPayload).getRow(); } //sc_time ReadyBatch::getTimeOfOldestRequest() @@ -34,7 +40,8 @@ bool ReadyBatch::addTransaction(gp* payload) { // sc_time currentAge = sc_time_stamp() - getTimeOfOldestRequest(); Row newRow = DramExtension::getExtension(payload).getRow(); - if (/*getNumRequests() == fifosize || currentAge >= thresholdAge || */newRow != getRow()) { + Row oldRow = readybatch.empty()? newRow : getRow(); + if (/*getNumRequests() == fifosize || currentAge >= thresholdAge || */newRow != oldRow) { return false; } else { readybatch.emplace_back(payload); diff --git a/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.h b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.h index c35640a5..1b0f304c 100644 --- a/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.h +++ b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.h @@ -17,6 +17,7 @@ public: // unsigned int getNumRequests(); std::deque& getTransactions(); bool isEmpty(); + ~ReadyBatch(); private: std::deque readybatch; unsigned int fifosize; diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h index 71f7aa96..527b350c 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.h +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h @@ -17,7 +17,7 @@ using namespace std; class SMS: public sc_module, public IScheduler { public: - SMS(ControllerCore &controllerCore, unsigned int SJFprobability) : IScheduler(controllerCore), SJFprobability(SJFprobability) + SMS(sc_module_name /*_name*/, ControllerCore &controllerCore, unsigned int SJFprobability) : IScheduler(controllerCore), SJFprobability(SJFprobability) { // initialize memory request counter & memory request intensity for each thread unsigned int totalNumThreads = Configuration::getInstance().NumberOfTracePlayers; @@ -26,11 +26,19 @@ public: // memrequestcounter.emplace(Thread(threadID), 0); // memoryIntensity.emplace(Thread(threadID), 0); inFlightMemRequestCounter.emplace(Thread(threadID), 0); + readybatches[Thread(threadID)] = new ReadyBatch(); } SC_THREAD(batchScheduler); } SC_HAS_PROCESS(SMS); - virtual ~SMS(){} + virtual ~SMS() + { + unsigned int totalNumThreads = Configuration::getInstance().NumberOfTracePlayers; + for (unsigned int threadID = 1; threadID <= totalNumThreads; threadID++) + { + delete readybatches[Thread(threadID)]; + } + } virtual void schedule(gp *payload) override; virtual std::pair getNextRequest(Bank bank) override; void batchScheduler(); From 0830dc4d53e12c8c0d7d2ed651b42a54a120646f Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Tue, 14 Mar 2017 02:20:52 +0100 Subject: [PATCH 13/39] Change random generator to Bernoulli distribution # Explain what has been changed # Explain why this change is being made # Provide links to any relevant tickets, articles or other resources --- DRAMSys/simulator/src/controller/scheduler/SMS.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index 147cea6e..533498ef 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -1,4 +1,5 @@ #include "SMS.h" +#include using namespace std; @@ -72,12 +73,15 @@ bool SMS::batchFormation() void SMS::batchScheduler() { sc_time memClk = Configuration::getInstance().memSpec.clk; + std::default_random_engine generator; + std::bernoulli_distribution distribution((double) SJFprobability / 100.0); + bool isSJF; + while (true) { wait(memClk); - srand(time(NULL)); - bool isSJF = (rand() % 100) < SJFprobability; + isSJF = distribution(generator); if (!existReadyBatch()) { // pick & drain a ready batch From ba39c9443bc584ac4f90c66cf0bf1e9a00760e3e Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Wed, 22 Mar 2017 12:43:36 +0100 Subject: [PATCH 14/39] Update test cases & simulation configurations # Explain what has been changed # Explain why this change is being made # Provide links to any relevant tickets, articles or other resources --- DRAMSys/simulator/resources/configs/mcconfigs/sms.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DRAMSys/simulator/resources/configs/mcconfigs/sms.xml b/DRAMSys/simulator/resources/configs/mcconfigs/sms.xml index bee3151e..19490a2c 100644 --- a/DRAMSys/simulator/resources/configs/mcconfigs/sms.xml +++ b/DRAMSys/simulator/resources/configs/mcconfigs/sms.xml @@ -1,9 +1,9 @@ - + - + From 3521cafa814ca0da85e61fe4fe5dc34998227c7d Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Wed, 22 Mar 2017 12:44:33 +0100 Subject: [PATCH 15/39] Fix bug in RR & SJF selection functions # Explain what has been changed # Explain why this change is being made # Provide links to any relevant tickets, articles or other resources --- .../src/controller/scheduler/ReadyBatch.cpp | 3 +- .../src/controller/scheduler/SMS.cpp | 271 ++++++++---------- .../simulator/src/controller/scheduler/SMS.h | 12 +- 3 files changed, 117 insertions(+), 169 deletions(-) diff --git a/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp index af2a624b..55118d15 100644 --- a/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp @@ -18,8 +18,7 @@ ReadyBatch::~ReadyBatch() Row ReadyBatch::getRow() { - gp*& firstPayload = readybatch.front(); - return DramExtension::getExtension(firstPayload).getRow(); + return DramExtension::getExtension(readybatch.front()).getRow(); } //sc_time ReadyBatch::getTimeOfOldestRequest() diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index 533498ef..b7da758e 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -6,16 +6,7 @@ using namespace std; void SMS::schedule(gp *payload) { buffer[DramExtension::getExtension(payload).getThread()].emplace_back(payload); - - Thread thread = DramExtension::getExtension(payload).getThread(); - // update memory request counter -// memrequestcounter[thread]++; - inFlightMemRequestCounter[thread]++; - - // update memory request intensity -// sc_time lastrequestTimeOfGeneration = GenerationExtension::getExtension(payload).TimeOfGeneration(); -// sc_time memClk = Configuration::getInstance().memSpec.clk; -// memoryIntensity[thread] = (memrequestcounter[thread] * 1000.0 * memClk) / lastrequestTimeOfGeneration; // in MPKC + inFlightMemRequestCounter[DramExtension::getExtension(payload).getThread()]++; } std::pair SMS::getNextRequest(Bank bank) @@ -40,16 +31,35 @@ std::pair SMS::getNextRequest(Bank bank) } -//unsigned int SMS::totalMemoryRequests() -//{ -// //TODO: recheck this? how about total in-flight requests instead? -// unsigned int totalSize = 0; -// for (auto &reqQueue : buffer) -// { -// totalSize += reqQueue.second.size(); -// } -// return totalSize; -//} +void SMS::batchScheduler() +{ + sc_time memClk = Configuration::getInstance().memSpec.clk; + std::default_random_engine generator; + std::bernoulli_distribution distribution((double) SJFprobability / 100.0); + bool isSJF; + + wait(150, SC_NS); // Test Purpose + + while (true) + { + wait(memClk); //TODO: Is this correct??? + + isSJF = distribution(generator); + if (!existReadyBatch()) + { + // pick & drain a ready batch + if (batchFormation()) + { + isSJF ? selectSJF() : selectRR(); + } + } + else + { + // pick & drain a ready batch + isSJF ? selectSJF() : selectRR(); + } + } +} bool SMS::batchFormation() { @@ -70,115 +80,6 @@ bool SMS::batchFormation() } } -void SMS::batchScheduler() -{ - sc_time memClk = Configuration::getInstance().memSpec.clk; - std::default_random_engine generator; - std::bernoulli_distribution distribution((double) SJFprobability / 100.0); - bool isSJF; - - while (true) - { - wait(memClk); - - isSJF = distribution(generator); - if (!existReadyBatch()) - { - // pick & drain a ready batch - if (batchFormation()) - { - isSJF ? selectSJF() : selectRR(); - } - } - else - { - // pick & drain a ready batch - isSJF ? selectSJF() : selectRR(); - } - } -} - -void SMS::selectSJF() -{ - // find shorstest thread - unsigned int minThread = 1; - unsigned int totalNumThreads = Configuration::getInstance().NumberOfTracePlayers; - for (unsigned int threadID = 2; threadID <= totalNumThreads; threadID++) - { - if (inFlightMemRequestCounter[Thread(threadID)] <= inFlightMemRequestCounter[Thread(minThread)]) - { - minThread = threadID; - } - } - - // drain to bank buffers - std::deque requestPtrs = readybatches[Thread(minThread)]->getTransactions(); - if (!requestPtrs.empty()) - { - for (auto intr = requestPtrs.begin(); intr != requestPtrs.end(); intr++) - { - Bank bank = DramExtension::getExtension(*intr).getBank(); - bankbuffer[bank].emplace_back(*intr); - } - requestPtrs.clear(); - } - - // reform the drained ready batch - // batchFormation(Thread(minThread)); -} - -void SMS::selectRR() -{ - static std::map::iterator next = readybatches.begin(); - - // drain to bank buffers - std::deque requestPtrs = (*next).second->getTransactions(); - if (!requestPtrs.empty()) - { - for (auto intr = requestPtrs.begin(); intr != requestPtrs.end(); intr++) - { - Bank bank = DramExtension::getExtension(*intr).getBank(); - bankbuffer[bank].emplace_back(*intr); - } - requestPtrs.clear(); - } - - // reform the drained ready batch - // batchFormation((*next).first); - - // point to next pair - if (existReadyBatch()) - { - do - { - next++; - if (next == readybatches.end()) - { - next = readybatches.begin(); - } - } while ((*next).second->isEmpty()); - } - else - { - // point to next empty ready batch, later call to batchScheduler() will call batchFormation() - // this next empty ready batch will be refilled - next++; - } - -} - -bool SMS::existReadyBatch() -{ - for (auto& thread_readybatch : readybatches) - { - if (!thread_readybatch.second->isEmpty()) - { - return true; - } - } - return false; -} - bool SMS::batchFormation(Thread thread) { if (!readybatches[thread]->isEmpty()) @@ -196,33 +97,85 @@ bool SMS::batchFormation(Thread thread) } } -//void SMS::bypassRequests() -//{ -// for (auto& thread_requests : buffer) -// { -// for (auto request = thread_requests.second.begin(); request != thread_requests.second.end(); request++) -// { -// Bank bank = DramExtension::getExtension(*request).getBank(); -// bankbuffer[bank].emplace_back(*request); -// thread_requests.second.erase(request); -// } -// } -//} -// -//void SMS::bypassLowMemoryIntensity() -//{ -// unsigned int totalNumThreads = Configuration::getInstance().NumberOfTracePlayers; -// for (unsigned int threadID = 1; threadID <= totalNumThreads; threadID++) -// { -// if (memoryIntensity[Thread(threadID)] < 1 && memoryIntensity[Thread(threadID)] > 0) -// { -// for (auto request = buffer[Thread(threadID)].begin(); -// request != buffer[Thread(threadID)].end(); request++) -// { -// Bank bank = DramExtension::getExtension(*request).getBank(); -// bankbuffer[bank].emplace_back(*request); -// buffer[Thread(threadID)].erase(request); -// } -// } -// } -//} +void SMS::selectSJF() +{ + // find shorstest thread + std::vector threadsWithNonEmptyReadybatches; + for (auto& readybatch : readybatches) + { + if (!readybatch.second->isEmpty()) + { + threadsWithNonEmptyReadybatches.push_back(readybatch.first); + } + } + + if (!threadsWithNonEmptyReadybatches.empty()) + { + Thread minThread = threadsWithNonEmptyReadybatches.front(); + for (auto& thread : threadsWithNonEmptyReadybatches) + { + if (inFlightMemRequestCounter[thread] <= inFlightMemRequestCounter[minThread]) + { + minThread = thread; + } + } + + // drain to bank buffers + std::deque &requestPtrs = readybatches[minThread]->getTransactions(); + for (auto payloadPtrIterator = requestPtrs.begin(); payloadPtrIterator != requestPtrs.end(); payloadPtrIterator++) + { + Bank bank = DramExtension::getExtension(*payloadPtrIterator).getBank(); + bankbuffer[bank].emplace_back(*payloadPtrIterator); + } + requestPtrs.clear(); + + // reform the drained ready batch + // batchFormation(Thread(minThread)); + } + +} + +void SMS::selectRR() +{ + static std::map::iterator next = readybatches.begin(); + + if (existReadyBatch()) + { + while ((*next).second->isEmpty()) + { + next++; + if (next == readybatches.end()) + { + next = readybatches.begin(); + } + } + + // drain to bank buffers + std::deque &requestPtrs = (*next).second->getTransactions(); + for (auto payloadPtrIterator = requestPtrs.begin(); payloadPtrIterator != requestPtrs.end(); payloadPtrIterator++) + { + Bank bank = DramExtension::getExtension(*payloadPtrIterator).getBank(); + bankbuffer[bank].emplace_back(*payloadPtrIterator); + } + requestPtrs.clear(); + + // reform the drained ready batch + // batchFormation((*next).first); + } + +} + +bool SMS::existReadyBatch() +{ + for (auto& thread_readybatch : readybatches) + { + if (!thread_readybatch.second->isEmpty()) + { + return true; + } + } + return false; +} + + + diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h index 527b350c..9d2979f4 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.h +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h @@ -23,15 +23,14 @@ public: unsigned int totalNumThreads = Configuration::getInstance().NumberOfTracePlayers; for (unsigned int threadID = 1; threadID <= totalNumThreads; threadID++) { -// memrequestcounter.emplace(Thread(threadID), 0); -// memoryIntensity.emplace(Thread(threadID), 0); inFlightMemRequestCounter.emplace(Thread(threadID), 0); readybatches[Thread(threadID)] = new ReadyBatch(); } SC_THREAD(batchScheduler); } SC_HAS_PROCESS(SMS); - virtual ~SMS() + + ~SMS() { unsigned int totalNumThreads = Configuration::getInstance().NumberOfTracePlayers; for (unsigned int threadID = 1; threadID <= totalNumThreads; threadID++) @@ -39,27 +38,24 @@ public: delete readybatches[Thread(threadID)]; } } + virtual void schedule(gp *payload) override; virtual std::pair getNextRequest(Bank bank) override; + void batchScheduler(); private: std::map> buffer; std::map> bankbuffer; std::map readybatches; -// std::map memrequestcounter; std::map inFlightMemRequestCounter; -// std::map memoryIntensity; unsigned int SJFprobability; -// unsigned int totalMemoryRequests(); bool batchFormation(); void selectSJF(); void selectRR(); bool existReadyBatch(); bool batchFormation(Thread thread); -// void bypassRequests(); -// void bypassLowMemoryIntensity(); }; #endif // SMS_H From 8c7e3549aa2a5577499cb250c5934a5b4ecf7b5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89der=20F=2E=20Zulian?= Date: Fri, 10 Mar 2017 15:40:04 +0100 Subject: [PATCH 16/39] Fix for disable refresh --- .../simulator/src/controller/core/ControllerCore.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/DRAMSys/simulator/src/controller/core/ControllerCore.cpp b/DRAMSys/simulator/src/controller/core/ControllerCore.cpp index d8650e70..45b3bd47 100644 --- a/DRAMSys/simulator/src/controller/core/ControllerCore.cpp +++ b/DRAMSys/simulator/src/controller/core/ControllerCore.cpp @@ -160,11 +160,16 @@ void ControllerCore::scheduleRequest(Command command, tlm::tlm_generic_payload & sc_time start = clkAlign(sc_time_stamp()); state->cleanUp(start); ScheduledCommand scheduledCommand = schedule(command, start, payload); - if(!((command == Command::Precharge || command == Command::Activate) - && refreshManager->hasCollision(scheduledCommand))) - { + if (config.ControllerCoreDisableRefresh == true) { state->change(scheduledCommand); controller.send(scheduledCommand, payload); + } else { + if(!((command == Command::Precharge || command == Command::Activate) + && refreshManager->hasCollision(scheduledCommand))) + { + state->change(scheduledCommand); + controller.send(scheduledCommand, payload); + } } } From 83e6a1884ce303fb502232680b2828989fec3378 Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Wed, 22 Mar 2017 15:54:33 +0100 Subject: [PATCH 17/39] Revert simulation config file and create a separate simulation file for SMS # Explain what has been changed # Explain why this change is being made # Provide links to any relevant tickets, articles or other resources --- .../resources/simulations/sim-batch.xml | 13 ++--- .../resources/simulations/sms-example.xml | 55 +++++++++++++++++++ 2 files changed, 60 insertions(+), 8 deletions(-) create mode 100644 DRAMSys/simulator/resources/simulations/sms-example.xml diff --git a/DRAMSys/simulator/resources/simulations/sim-batch.xml b/DRAMSys/simulator/resources/simulations/sim-batch.xml index fbd47695..0752914c 100644 --- a/DRAMSys/simulator/resources/simulations/sim-batch.xml +++ b/DRAMSys/simulator/resources/simulations/sim-batch.xml @@ -2,11 +2,11 @@ - + - + @@ -39,15 +39,12 @@ - + - - t1.stl - t2.stl - t3.stl - t4.stl + + chstone-adpcm_32.stl diff --git a/DRAMSys/simulator/resources/simulations/sms-example.xml b/DRAMSys/simulator/resources/simulations/sms-example.xml new file mode 100644 index 00000000..fbd47695 --- /dev/null +++ b/DRAMSys/simulator/resources/simulations/sms-example.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + t1.stl + t2.stl + t3.stl + t4.stl + + + + + From d974851c0eae4494d89cf75883609946105666fc Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Mon, 3 Apr 2017 22:14:44 +0200 Subject: [PATCH 18/39] Small fix --- DRAMSys/simulator/src/controller/scheduler/SMS.cpp | 4 +++- DRAMSys/simulator/src/simulation/main.cpp | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index b7da758e..af4af7be 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -71,10 +71,12 @@ bool SMS::batchFormation() else { bool isBatchForm = false; + bool isBatchFormForThread = false; unsigned int totalNumThreads = Configuration::getInstance().NumberOfTracePlayers; for (unsigned int threadID = 1; threadID <= totalNumThreads; threadID++) { - isBatchForm = isBatchForm || batchFormation(Thread(threadID)); + isBatchFormForThread = batchFormation(Thread(threadID)); + isBatchForm = isBatchForm || isBatchFormForThread; } return isBatchForm; } diff --git a/DRAMSys/simulator/src/simulation/main.cpp b/DRAMSys/simulator/src/simulation/main.cpp index 207d99db..87a8d27a 100644 --- a/DRAMSys/simulator/src/simulation/main.cpp +++ b/DRAMSys/simulator/src/simulation/main.cpp @@ -83,7 +83,7 @@ int sc_main(int argc, char **argv) if(argc > 1) simulationToRun = argv[1]; else - simulationToRun = resources + "simulations/sim-batch.xml"; + simulationToRun = resources + "simulations/sms-example.xml"; cout << "Simulation file is " << simulationToRun << endl; SimulationManager manager(resources); From b0b1d0efd2c5a8f3e781683f6840c85abb8ff03b Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Tue, 11 Apr 2017 22:55:33 +0200 Subject: [PATCH 19/39] Include necessary files for SMS simulation in Qt resource config file --- DRAMSys/simulator/resources/resources.pri | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/DRAMSys/simulator/resources/resources.pri b/DRAMSys/simulator/resources/resources.pri index 1d6ffe46..412c88be 100644 --- a/DRAMSys/simulator/resources/resources.pri +++ b/DRAMSys/simulator/resources/resources.pri @@ -5,6 +5,7 @@ OTHER_FILES += resources/simulations/sim-batch.xml OTHER_FILES += resources/simulations/ddr3-example.xml OTHER_FILES += resources/simulations/ddr3-single-device.xml +OTHER_FILES += resources/simulations/sms-example.xml # scripts OTHER_FILES += resources/scripts/address_scrambler.pl @@ -52,6 +53,10 @@ OTHER_FILES += resources/traces/mediabench-adpcmdecode_32.stl OTHER_FILES += resources/traces/ddr3_example.stl OTHER_FILES += resources/traces/ddr3_single_dev_example.stl OTHER_FILES += resources/traces/ddr3_SAMSUNG_M471B5674QH0_DIMM_example.stl +OTHER_FILES += resources/traces/t1.stl +OTHER_FILES += resources/traces/t2.stl +OTHER_FILES += resources/traces/t3.stl +OTHER_FILES += resources/traces/t4.stl # mcconfigs OTHER_FILES += resources/configs/mcconfigs/fifoStrict.xml @@ -63,6 +68,7 @@ OTHER_FILES += resources/configs/mcconfigs/_old/par_bs.xml OTHER_FILES += resources/configs/mcconfigs/_old/fr_fcfs_bankwise.xml OTHER_FILES += resources/configs/mcconfigs/fr_fcfs.xml OTHER_FILES += resources/configs/mcconfigs/par_bs.xml +OTHER_FILES += resources/configs/mcconfigs/sms.xml # memspecs OTHER_FILES += resources/configs/memspecs/memspec.dtd From c09f0cac0a5d005271311ff3693c8e772c9b85bb Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Mon, 24 Apr 2017 00:29:19 +0200 Subject: [PATCH 20/39] Change trace file names for SMS --- DRAMSys/simulator/resources/resources.pri | 8 ++++---- DRAMSys/simulator/resources/simulations/sms-example.xml | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/DRAMSys/simulator/resources/resources.pri b/DRAMSys/simulator/resources/resources.pri index 412c88be..23f0e606 100644 --- a/DRAMSys/simulator/resources/resources.pri +++ b/DRAMSys/simulator/resources/resources.pri @@ -53,10 +53,10 @@ OTHER_FILES += resources/traces/mediabench-adpcmdecode_32.stl OTHER_FILES += resources/traces/ddr3_example.stl OTHER_FILES += resources/traces/ddr3_single_dev_example.stl OTHER_FILES += resources/traces/ddr3_SAMSUNG_M471B5674QH0_DIMM_example.stl -OTHER_FILES += resources/traces/t1.stl -OTHER_FILES += resources/traces/t2.stl -OTHER_FILES += resources/traces/t3.stl -OTHER_FILES += resources/traces/t4.stl +OTHER_FILES += resources/traces/sms_t1.stl +OTHER_FILES += resources/traces/sms_t2.stl +OTHER_FILES += resources/traces/sms_t3.stl +OTHER_FILES += resources/traces/sms_t4.stl # mcconfigs OTHER_FILES += resources/configs/mcconfigs/fifoStrict.xml diff --git a/DRAMSys/simulator/resources/simulations/sms-example.xml b/DRAMSys/simulator/resources/simulations/sms-example.xml index fbd47695..16383801 100644 --- a/DRAMSys/simulator/resources/simulations/sms-example.xml +++ b/DRAMSys/simulator/resources/simulations/sms-example.xml @@ -44,10 +44,10 @@ - t1.stl - t2.stl - t3.stl - t4.stl + sms_t1.stl + sms_t2.stl + sms_t3.stl + sms_t4.stl From 8a2d4331ec04de7be0eccc3dd8dfefc9df14b058 Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Fri, 28 Apr 2017 15:03:40 +0200 Subject: [PATCH 21/39] Add debugger & fix the drain step to drain each request in each clock cycle --- .../src/controller/scheduler/SMS.cpp | 46 +++++++++++++++---- .../simulator/src/controller/scheduler/SMS.h | 11 +++-- 2 files changed, 46 insertions(+), 11 deletions(-) diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index af4af7be..51b1b2ec 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -7,12 +7,15 @@ void SMS::schedule(gp *payload) { buffer[DramExtension::getExtension(payload).getThread()].emplace_back(payload); inFlightMemRequestCounter[DramExtension::getExtension(payload).getThread()]++; + newRequest.notify(SC_ZERO_TIME); } std::pair SMS::getNextRequest(Bank bank) { if (bankbuffer[bank].empty()) { + debugManager.printDebugMessage(name(), + "Get next request on bank " + to_string(bank.ID()) + " : EMPTY buffer"); return pair(Command::NOP, NULL); } else @@ -26,6 +29,7 @@ std::pair SMS::getNextRequest(Bank bank) bankbuffer[bank].pop_front(); } + debugManager.printDebugMessage(name(), "Get next request on bank " + to_string(bank.ID())); return pair(command, payload); } @@ -42,7 +46,7 @@ void SMS::batchScheduler() while (true) { - wait(memClk); //TODO: Is this correct??? +// wait(memClk); //TODO: Is this correct??? isSJF = distribution(generator); if (!existReadyBatch()) @@ -50,13 +54,17 @@ void SMS::batchScheduler() // pick & drain a ready batch if (batchFormation()) { - isSJF ? selectSJF() : selectRR(); + isSJF ? selectSJF(memClk) : selectRR(memClk); + } + else + { + wait(newRequest); } } else { // pick & drain a ready batch - isSJF ? selectSJF() : selectRR(); + isSJF ? selectSJF(memClk) : selectRR(memClk); } } } @@ -95,11 +103,23 @@ bool SMS::batchFormation(Thread thread) { buffer[thread].pop_front(); } - return !readybatches[thread]->isEmpty(); + + if (readybatches[thread]->isEmpty()) + { + debugManager.printDebugMessage(name(), + "EMPTY buffer, Ready batch for thread: " + to_string(thread.ID()) + " NOT formed"); + return false; + } + else + { + debugManager.printDebugMessage(name(), + "Form ready batch for thread: " + to_string(thread.ID())); + return true; + } } } -void SMS::selectSJF() +void SMS::selectSJF(sc_time memClk) { // find shorstest thread std::vector threadsWithNonEmptyReadybatches; @@ -121,6 +141,8 @@ void SMS::selectSJF() minThread = thread; } } + debugManager.printDebugMessage(name(), + "[SJF] Select ready batch of thread " + to_string(minThread.ID())); // drain to bank buffers std::deque &requestPtrs = readybatches[minThread]->getTransactions(); @@ -128,6 +150,10 @@ void SMS::selectSJF() { Bank bank = DramExtension::getExtension(*payloadPtrIterator).getBank(); bankbuffer[bank].emplace_back(*payloadPtrIterator); + debugManager.printDebugMessage(name(), + "[SJF] Drain request in the ready batch of thread " + to_string(minThread.ID()) + + " to bankbuffer " + to_string(bank.ID())); + wait(memClk); } requestPtrs.clear(); @@ -137,7 +163,7 @@ void SMS::selectSJF() } -void SMS::selectRR() +void SMS::selectRR(sc_time memClk) { static std::map::iterator next = readybatches.begin(); @@ -151,6 +177,8 @@ void SMS::selectRR() next = readybatches.begin(); } } + debugManager.printDebugMessage(name(), + "[RR] Select ready batch of thread " + to_string((*next).first.ID())); // drain to bank buffers std::deque &requestPtrs = (*next).second->getTransactions(); @@ -158,6 +186,10 @@ void SMS::selectRR() { Bank bank = DramExtension::getExtension(*payloadPtrIterator).getBank(); bankbuffer[bank].emplace_back(*payloadPtrIterator); + debugManager.printDebugMessage(name(), + "[RR] Drained request in the ready batch of thread " + to_string((*next).first.ID()) + + " to bankbuffer " + to_string(bank.ID())); + wait(memClk); } requestPtrs.clear(); @@ -179,5 +211,3 @@ bool SMS::existReadyBatch() return false; } - - diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h index 9d2979f4..a1b7ac70 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.h +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h @@ -9,6 +9,7 @@ #include "../core/ControllerCore.h" #include "../core/configuration/Configuration.h" #include "../../common/dramExtension.h" +#include "../../common/DebugManager.h" #define MIN_TOTAL_REQ 16 @@ -17,7 +18,7 @@ using namespace std; class SMS: public sc_module, public IScheduler { public: - SMS(sc_module_name /*_name*/, ControllerCore &controllerCore, unsigned int SJFprobability) : IScheduler(controllerCore), SJFprobability(SJFprobability) + SMS(sc_module_name /*_name*/, ControllerCore &controllerCore, unsigned int SJFprobability) : IScheduler(controllerCore), SJFprobability(SJFprobability), debugManager(DebugManager::getInstance()) { // initialize memory request counter & memory request intensity for each thread unsigned int totalNumThreads = Configuration::getInstance().NumberOfTracePlayers; @@ -51,11 +52,15 @@ private: std::map inFlightMemRequestCounter; unsigned int SJFprobability; + DebugManager& debugManager; + sc_event newRequest; + bool batchFormation(); - void selectSJF(); - void selectRR(); + void selectSJF(sc_time memClk); + void selectRR(sc_time memClk); bool existReadyBatch(); bool batchFormation(Thread thread); + }; #endif // SMS_H From 64ed3107b56cc7280b3848a619c9468db82838c7 Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Sat, 29 Apr 2017 00:26:27 +0200 Subject: [PATCH 22/39] Fix SelectSJF 1. Form new ready batch when searching for SJF 2. Add return value to indicate whether successful selectSJF --- .../src/controller/scheduler/SMS.cpp | 30 ++++++++++++++++--- .../simulator/src/controller/scheduler/SMS.h | 2 +- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index 51b1b2ec..9cacaef8 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -119,20 +119,36 @@ bool SMS::batchFormation(Thread thread) } } -void SMS::selectSJF(sc_time memClk) +bool SMS::selectSJF(sc_time memClk) { - // find shorstest thread + // find threads with non-empty ready batch std::vector threadsWithNonEmptyReadybatches; for (auto& readybatch : readybatches) { if (!readybatch.second->isEmpty()) { + // marked as thread with non-empty ready batch threadsWithNonEmptyReadybatches.push_back(readybatch.first); } + else + { + // form ready batch for this thread + Thread thread = readybatch.first; + while (!buffer[thread].empty() && readybatch.second->addTransaction(buffer[thread].front())) + { + buffer[thread].pop_front(); + } + // marked as thread with non-empty ready batch + if (!readybatch.second->isEmpty()) { + threadsWithNonEmptyReadybatches.push_back(readybatch.first); + } + } } + if (!threadsWithNonEmptyReadybatches.empty()) { + // pick shortest-job thread among threads with non-empty ready batch Thread minThread = threadsWithNonEmptyReadybatches.front(); for (auto& thread : threadsWithNonEmptyReadybatches) { @@ -157,8 +173,14 @@ void SMS::selectSJF(sc_time memClk) } requestPtrs.clear(); - // reform the drained ready batch - // batchFormation(Thread(minThread)); + // a ready batch has been picked up & drained + return true; + } + else + { + // non-existed ready batch to be picked up & drained + // this mean the request buffers are totally empty + return false; } } diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h index a1b7ac70..590aa4ad 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.h +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h @@ -56,7 +56,7 @@ private: sc_event newRequest; bool batchFormation(); - void selectSJF(sc_time memClk); + bool selectSJF(sc_time memClk); void selectRR(sc_time memClk); bool existReadyBatch(); bool batchFormation(Thread thread); From 55d36d60c27eec3cf85e73043dc5eb89c893ac4a Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Sat, 29 Apr 2017 11:19:06 +0200 Subject: [PATCH 23/39] Fix SelectRR & batch scheduler 1. Form new batch for thread with empty ready batch 2. Return boolean indicate successful selectRR --- .../src/controller/scheduler/SMS.cpp | 101 +++++++++++------- .../simulator/src/controller/scheduler/SMS.h | 2 +- 2 files changed, 61 insertions(+), 42 deletions(-) diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index 9cacaef8..06d53552 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -40,31 +40,27 @@ void SMS::batchScheduler() sc_time memClk = Configuration::getInstance().memSpec.clk; std::default_random_engine generator; std::bernoulli_distribution distribution((double) SJFprobability / 100.0); - bool isSJF; + std::map::iterator select = readybatches.begin(); wait(150, SC_NS); // Test Purpose while (true) { -// wait(memClk); //TODO: Is this correct??? - - isSJF = distribution(generator); - if (!existReadyBatch()) + if (distribution(generator)) { - // pick & drain a ready batch - if (batchFormation()) - { - isSJF ? selectSJF(memClk) : selectRR(memClk); - } - else + bool success = selectSJF(memClk); + if (!success) { wait(newRequest); } } else { - // pick & drain a ready batch - isSJF ? selectSJF(memClk) : selectRR(memClk); + bool success = selectRR(memClk, select); + if (!success) + { + wait(newRequest); + } } } } @@ -136,16 +132,16 @@ bool SMS::selectSJF(sc_time memClk) Thread thread = readybatch.first; while (!buffer[thread].empty() && readybatch.second->addTransaction(buffer[thread].front())) { - buffer[thread].pop_front(); + buffer[thread].pop_front(); } // marked as thread with non-empty ready batch - if (!readybatch.second->isEmpty()) { + if (!readybatch.second->isEmpty()) + { threadsWithNonEmptyReadybatches.push_back(readybatch.first); } } } - if (!threadsWithNonEmptyReadybatches.empty()) { // pick shortest-job thread among threads with non-empty ready batch @@ -162,7 +158,8 @@ bool SMS::selectSJF(sc_time memClk) // drain to bank buffers std::deque &requestPtrs = readybatches[minThread]->getTransactions(); - for (auto payloadPtrIterator = requestPtrs.begin(); payloadPtrIterator != requestPtrs.end(); payloadPtrIterator++) + for (auto payloadPtrIterator = requestPtrs.begin(); payloadPtrIterator != requestPtrs.end(); + payloadPtrIterator++) { Bank bank = DramExtension::getExtension(*payloadPtrIterator).getBank(); bankbuffer[bank].emplace_back(*payloadPtrIterator); @@ -185,40 +182,62 @@ bool SMS::selectSJF(sc_time memClk) } -void SMS::selectRR(sc_time memClk) +bool SMS::selectRR(sc_time memClk, std::map::iterator &select) { - static std::map::iterator next = readybatches.begin(); - - if (existReadyBatch()) + // pick a non-empty ready batch + std::map::iterator saved = select; + while ((*select).second->isEmpty()) { - while ((*next).second->isEmpty()) + // form ready batch for this thread + Thread thread = (*select).first; + while (!buffer[thread].empty() && (*select).second->addTransaction(buffer[thread].front())) { - next++; - if (next == readybatches.end()) + buffer[thread].pop_front(); + } + + if ((*select).second->isEmpty()) + { + // cannot form ready batch then move to next thread + select++; + if (select == readybatches.end()) { - next = readybatches.begin(); + select = readybatches.begin(); + } + + if (select == saved) + { + // the next thread is the original thread, that mean req buffer are totally empty + // non-existed ready batch to be picked up & drained + return false; } } + } + debugManager.printDebugMessage(name(), + "[RR] Select ready batch of thread " + to_string((*select).first.ID())); + + // drain to bank buffers + std::deque &requestPtrs = (*select).second->getTransactions(); + for (auto payloadPtrIterator = requestPtrs.begin(); payloadPtrIterator != requestPtrs.end(); + payloadPtrIterator++) + { + Bank bank = DramExtension::getExtension(*payloadPtrIterator).getBank(); + bankbuffer[bank].emplace_back(*payloadPtrIterator); debugManager.printDebugMessage(name(), - "[RR] Select ready batch of thread " + to_string((*next).first.ID())); + "[RR] Drained request in the ready batch of thread " + to_string((*select).first.ID()) + + " to bankbuffer " + to_string(bank.ID())); + wait(memClk); + } + requestPtrs.clear(); - // drain to bank buffers - std::deque &requestPtrs = (*next).second->getTransactions(); - for (auto payloadPtrIterator = requestPtrs.begin(); payloadPtrIterator != requestPtrs.end(); payloadPtrIterator++) - { - Bank bank = DramExtension::getExtension(*payloadPtrIterator).getBank(); - bankbuffer[bank].emplace_back(*payloadPtrIterator); - debugManager.printDebugMessage(name(), - "[RR] Drained request in the ready batch of thread " + to_string((*next).first.ID()) - + " to bankbuffer " + to_string(bank.ID())); - wait(memClk); - } - requestPtrs.clear(); - - // reform the drained ready batch - // batchFormation((*next).first); + // move the select iterator to the next one + select++; + if (select == readybatches.end()) + { + select = readybatches.begin(); } + // a ready batch has been picked up & drained + return true; } bool SMS::existReadyBatch() diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h index 590aa4ad..e9ad838a 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.h +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h @@ -57,7 +57,7 @@ private: bool batchFormation(); bool selectSJF(sc_time memClk); - void selectRR(sc_time memClk); + bool selectRR(sc_time memClk, std::map::iterator &next); bool existReadyBatch(); bool batchFormation(Thread thread); From 3e2a84775c140c0bbe48faa73318c0013998ffae Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Wed, 3 May 2017 18:15:13 +0200 Subject: [PATCH 24/39] Alter RR & SJF implementation: 1. Save selected thread in each SJF selection 2. Change RR policy to select the next thread i.e. relative to last selected thread by RR or SJF 3. Remove unused methods --- .../src/controller/scheduler/SMS.cpp | 123 ++++++------------ .../simulator/src/controller/scheduler/SMS.h | 11 +- 2 files changed, 48 insertions(+), 86 deletions(-) diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index 06d53552..3a7f984d 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -40,82 +40,16 @@ void SMS::batchScheduler() sc_time memClk = Configuration::getInstance().memSpec.clk; std::default_random_engine generator; std::bernoulli_distribution distribution((double) SJFprobability / 100.0); - std::map::iterator select = readybatches.begin(); wait(150, SC_NS); // Test Purpose while (true) { - if (distribution(generator)) - { - bool success = selectSJF(memClk); - if (!success) - { - wait(newRequest); - } - } - else - { - bool success = selectRR(memClk, select); - if (!success) - { - wait(newRequest); - } - } + selectRR_SJF(distribution(generator), memClk); } } -bool SMS::batchFormation() -{ - if (existReadyBatch()) - { - return false; - SC_REPORT_FATAL("SMS", "Form ready batches when exist at least a ready batch"); - } - else - { - bool isBatchForm = false; - bool isBatchFormForThread = false; - unsigned int totalNumThreads = Configuration::getInstance().NumberOfTracePlayers; - for (unsigned int threadID = 1; threadID <= totalNumThreads; threadID++) - { - isBatchFormForThread = batchFormation(Thread(threadID)); - isBatchForm = isBatchForm || isBatchFormForThread; - } - return isBatchForm; - } -} - -bool SMS::batchFormation(Thread thread) -{ - if (!readybatches[thread]->isEmpty()) - { - return false; - SC_REPORT_FATAL("SMS", "Ready batch formation for non empty ready batch"); - } - else - { - while (!buffer[thread].empty() && readybatches[thread]->addTransaction(buffer[thread].front())) - { - buffer[thread].pop_front(); - } - - if (readybatches[thread]->isEmpty()) - { - debugManager.printDebugMessage(name(), - "EMPTY buffer, Ready batch for thread: " + to_string(thread.ID()) + " NOT formed"); - return false; - } - else - { - debugManager.printDebugMessage(name(), - "Form ready batch for thread: " + to_string(thread.ID())); - return true; - } - } -} - -bool SMS::selectSJF(sc_time memClk) +bool SMS::selectSJF(sc_time memClk, std::map::iterator &select) { // find threads with non-empty ready batch std::vector threadsWithNonEmptyReadybatches; @@ -153,6 +87,10 @@ bool SMS::selectSJF(sc_time memClk) minThread = thread; } } + + // save selected thread + select = readybatches.find(Thread(minThread)); + debugManager.printDebugMessage(name(), "[SJF] Select ready batch of thread " + to_string(minThread.ID())); @@ -229,26 +167,49 @@ bool SMS::selectRR(sc_time memClk, std::map::iterator &sele } requestPtrs.clear(); - // move the select iterator to the next one - select++; - if (select == readybatches.end()) - { - select = readybatches.begin(); - } - // a ready batch has been picked up & drained return true; } -bool SMS::existReadyBatch() -{ - for (auto& thread_readybatch : readybatches) +void SMS::selectRR_SJF(bool isSJF, sc_time memClk) { + if (isSJF) { - if (!thread_readybatch.second->isEmpty()) + // select by Shortest Job First policy + bool success = selectSJF(memClk, selected); + if (!success) { - return true; + wait(newRequest); } } - return false; + else + { + // select by Round Robin policy + if (selected == readybatches.end()) + { + // first Round Robin selection + selected = readybatches.begin(); + bool success = selectRR(memClk, selected); + if (!success) + { + wait(newRequest); + } + } + else + { + // subsequent Round Robin selection + // move the select iterator to the next one + selected++; + if (selected == readybatches.end()) + { + selected = readybatches.begin(); + } + bool success = selectRR(memClk, selected); + if (!success) + { + wait(newRequest); + } + } + + } } diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h index e9ad838a..70ee26b0 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.h +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h @@ -27,6 +27,9 @@ public: inFlightMemRequestCounter.emplace(Thread(threadID), 0); readybatches[Thread(threadID)] = new ReadyBatch(); } + + // initialize selected thread iterator + selected = readybatches.end(); SC_THREAD(batchScheduler); } SC_HAS_PROCESS(SMS); @@ -50,17 +53,15 @@ private: std::map> bankbuffer; std::map readybatches; std::map inFlightMemRequestCounter; + std::map::iterator selected; unsigned int SJFprobability; DebugManager& debugManager; sc_event newRequest; - bool batchFormation(); - bool selectSJF(sc_time memClk); + bool selectSJF(sc_time memClk, std::map::iterator &select); bool selectRR(sc_time memClk, std::map::iterator &next); - bool existReadyBatch(); - bool batchFormation(Thread thread); - + void selectRR_SJF(bool isSJF, sc_time memClk); }; #endif // SMS_H From b76688fb5bfbd3ec4b0d1da932c4d0a0f3367e94 Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Wed, 3 May 2017 23:24:51 +0200 Subject: [PATCH 25/39] Change to better variable name --- .../src/controller/scheduler/SMS.cpp | 46 +++++++++---------- .../simulator/src/controller/scheduler/SMS.h | 4 +- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index 3a7f984d..f5054993 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -49,7 +49,7 @@ void SMS::batchScheduler() } } -bool SMS::selectSJF(sc_time memClk, std::map::iterator &select) +bool SMS::selectSJF(sc_time memClk, std::map::iterator &lastSelectedThread) { // find threads with non-empty ready batch std::vector threadsWithNonEmptyReadybatches; @@ -89,7 +89,7 @@ bool SMS::selectSJF(sc_time memClk, std::map::iterator &sel } // save selected thread - select = readybatches.find(Thread(minThread)); + lastSelectedThread = readybatches.find(Thread(minThread)); debugManager.printDebugMessage(name(), "[SJF] Select ready batch of thread " + to_string(minThread.ID())); @@ -120,29 +120,29 @@ bool SMS::selectSJF(sc_time memClk, std::map::iterator &sel } -bool SMS::selectRR(sc_time memClk, std::map::iterator &select) +bool SMS::selectRR(sc_time memClk, std::map::iterator &nextSelectedThread) { // pick a non-empty ready batch - std::map::iterator saved = select; - while ((*select).second->isEmpty()) + std::map::iterator savedOriginalNextSelectedThread = nextSelectedThread; + while ((*nextSelectedThread).second->isEmpty()) { // form ready batch for this thread - Thread thread = (*select).first; - while (!buffer[thread].empty() && (*select).second->addTransaction(buffer[thread].front())) + Thread thread = (*nextSelectedThread).first; + while (!buffer[thread].empty() && (*nextSelectedThread).second->addTransaction(buffer[thread].front())) { buffer[thread].pop_front(); } - if ((*select).second->isEmpty()) + if ((*nextSelectedThread).second->isEmpty()) { // cannot form ready batch then move to next thread - select++; - if (select == readybatches.end()) + nextSelectedThread++; + if (nextSelectedThread == readybatches.end()) { - select = readybatches.begin(); + nextSelectedThread = readybatches.begin(); } - if (select == saved) + if (nextSelectedThread == savedOriginalNextSelectedThread) { // the next thread is the original thread, that mean req buffer are totally empty // non-existed ready batch to be picked up & drained @@ -151,17 +151,17 @@ bool SMS::selectRR(sc_time memClk, std::map::iterator &sele } } debugManager.printDebugMessage(name(), - "[RR] Select ready batch of thread " + to_string((*select).first.ID())); + "[RR] Select ready batch of thread " + to_string((*nextSelectedThread).first.ID())); // drain to bank buffers - std::deque &requestPtrs = (*select).second->getTransactions(); + std::deque &requestPtrs = (*nextSelectedThread).second->getTransactions(); for (auto payloadPtrIterator = requestPtrs.begin(); payloadPtrIterator != requestPtrs.end(); payloadPtrIterator++) { Bank bank = DramExtension::getExtension(*payloadPtrIterator).getBank(); bankbuffer[bank].emplace_back(*payloadPtrIterator); debugManager.printDebugMessage(name(), - "[RR] Drained request in the ready batch of thread " + to_string((*select).first.ID()) + "[RR] Drained request in the ready batch of thread " + to_string((*nextSelectedThread).first.ID()) + " to bankbuffer " + to_string(bank.ID())); wait(memClk); } @@ -175,7 +175,7 @@ void SMS::selectRR_SJF(bool isSJF, sc_time memClk) { if (isSJF) { // select by Shortest Job First policy - bool success = selectSJF(memClk, selected); + bool success = selectSJF(memClk, selectedThread); if (!success) { wait(newRequest); @@ -184,11 +184,11 @@ void SMS::selectRR_SJF(bool isSJF, sc_time memClk) { else { // select by Round Robin policy - if (selected == readybatches.end()) + if (selectedThread == readybatches.end()) { // first Round Robin selection - selected = readybatches.begin(); - bool success = selectRR(memClk, selected); + selectedThread = readybatches.begin(); + bool success = selectRR(memClk, selectedThread); if (!success) { wait(newRequest); @@ -198,12 +198,12 @@ void SMS::selectRR_SJF(bool isSJF, sc_time memClk) { { // subsequent Round Robin selection // move the select iterator to the next one - selected++; - if (selected == readybatches.end()) + selectedThread++; + if (selectedThread == readybatches.end()) { - selected = readybatches.begin(); + selectedThread = readybatches.begin(); } - bool success = selectRR(memClk, selected); + bool success = selectRR(memClk, selectedThread); if (!success) { wait(newRequest); diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h index 70ee26b0..1ca75c70 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.h +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h @@ -29,7 +29,7 @@ public: } // initialize selected thread iterator - selected = readybatches.end(); + selectedThread = readybatches.end(); SC_THREAD(batchScheduler); } SC_HAS_PROCESS(SMS); @@ -53,7 +53,7 @@ private: std::map> bankbuffer; std::map readybatches; std::map inFlightMemRequestCounter; - std::map::iterator selected; + std::map::iterator selectedThread; unsigned int SJFprobability; DebugManager& debugManager; From 7d15ebc45ee82c0dec207bd184fed4038b11c8eb Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Tue, 9 May 2017 19:13:17 +0200 Subject: [PATCH 26/39] Fix undefined symbols for architecture x86_64 "SMS::batchScheduler()", referenced from: SMS::SMS(sc_core::sc_module_name, ControllerCore&, unsigned int) in libDRAMSys.a(Controller.o) "vtable for SMS", referenced from: SMS::SMS(sc_core::sc_module_name, ControllerCore&, unsigned int) in libDRAMSys.a(Controller.o) NOTE: a missing vtable usually means the first non-inline virtual member function has no definition. --- DRAMSys/simulator/library.pro | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/DRAMSys/simulator/library.pro b/DRAMSys/simulator/library.pro index 5e9f63a4..3770561e 100644 --- a/DRAMSys/simulator/library.pro +++ b/DRAMSys/simulator/library.pro @@ -81,6 +81,8 @@ SOURCES += \ src/controller/scheduler/PARBS.cpp \ src/controller/scheduler/Fr_Fcfs.cpp \ src/controller/scheduler/Fifo.cpp \ + src/controller/scheduler/SMS.cpp \ + src/controller/scheduler/ReadyBatch.cpp \ src/controller/core/refresh/RefreshManagerBankwise.cpp \ src/controller/core/refresh/RefreshManager.cpp \ src/controller/core/scheduling/checker/WriteChecker.cpp \ @@ -130,6 +132,8 @@ HEADERS += \ src/controller/scheduler/PARBS.h \ src/controller/scheduler/Fr_Fcfs.h \ src/controller/scheduler/Fifo.h \ + src/controller/scheduler/SMS.h \ + src/controller/scheduler/ReadyBatch.h \ src/controller/Controller.h \ src/controller/core/refresh/RefreshManagerBankwise.h \ src/controller/core/refresh/RefreshManager.h \ From 92bd873a3effc1a9f10d7174837c1d8b1e5ecfa7 Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Tue, 9 May 2017 23:23:44 +0200 Subject: [PATCH 27/39] Fix segmentation fault due to calling methods on NULL ReadyBatch Object --- DRAMSys/simulator/src/controller/scheduler/SMS.cpp | 5 +++++ DRAMSys/simulator/src/simulation/TracePlayerListener.h | 1 + DRAMSys/simulator/src/simulation/TraceSetup.h | 1 + 3 files changed, 7 insertions(+) diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index 82e9f6e0..7f505a5d 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -133,6 +133,11 @@ bool SMS::selectSJF(sc_time memClk, std::map::iterator &las bool SMS::selectRR(sc_time memClk, std::map::iterator &nextSelectedThread) { + // no request for this channel, the readybatches map is empty then return + if (readybatches.empty()) { + return false; + } + // pick a non-empty ready batch std::map::iterator savedOriginalNextSelectedThread = nextSelectedThread; while ((*nextSelectedThread).second->isEmpty()) diff --git a/DRAMSys/simulator/src/simulation/TracePlayerListener.h b/DRAMSys/simulator/src/simulation/TracePlayerListener.h index 95c52773..bec9f043 100644 --- a/DRAMSys/simulator/src/simulation/TracePlayerListener.h +++ b/DRAMSys/simulator/src/simulation/TracePlayerListener.h @@ -43,6 +43,7 @@ class TracePlayerListener public: virtual void tracePlayerTerminates() = 0; virtual void transactionFinished() = 0; + virtual ~TracePlayerListener(){}; }; #endif // TRACEPLAYERLISTENER_H diff --git a/DRAMSys/simulator/src/simulation/TraceSetup.h b/DRAMSys/simulator/src/simulation/TraceSetup.h index a9f0b8e5..a11b4abe 100644 --- a/DRAMSys/simulator/src/simulation/TraceSetup.h +++ b/DRAMSys/simulator/src/simulation/TraceSetup.h @@ -53,6 +53,7 @@ public: virtual void tracePlayerTerminates() override; virtual void transactionFinished() override; + virtual ~traceSetup(){}; private: unsigned int NumberOfTracePlayers; From 9c4cb6f979e82d222c076272b3827e26a80308f4 Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Thu, 11 May 2017 15:28:45 +0200 Subject: [PATCH 28/39] Fix auxiliary stuffs for simulating SMS --- DRAMSys/simulator/resources/resources.pri | 1 + DRAMSys/simulator/src/simulation/main.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/DRAMSys/simulator/resources/resources.pri b/DRAMSys/simulator/resources/resources.pri index dc2a316a..914daa88 100644 --- a/DRAMSys/simulator/resources/resources.pri +++ b/DRAMSys/simulator/resources/resources.pri @@ -70,6 +70,7 @@ OTHER_FILES += resources/configs/mcconfigs/fifoStrict.xml OTHER_FILES += resources/configs/mcconfigs/fifo.xml OTHER_FILES += resources/configs/mcconfigs/fr_fcfs.xml OTHER_FILES += resources/configs/mcconfigs/par_bs.xml +OTHER_FILES += resources/configs/mcconfigs/sms.xml # Memspecs OTHER_FILES += resources/configs/memspecs/memspec.dtd diff --git a/DRAMSys/simulator/src/simulation/main.cpp b/DRAMSys/simulator/src/simulation/main.cpp index 18e00f77..a370a6af 100644 --- a/DRAMSys/simulator/src/simulation/main.cpp +++ b/DRAMSys/simulator/src/simulation/main.cpp @@ -72,7 +72,7 @@ int sc_main(int argc, char **argv) } else { - SimulationXML = resources + "simulations/ddr3-example.xml"; + SimulationXML = resources + "simulations/sms-example.xml"; } std::vector players; From 65c1abcc7af2050e6c51213ffb73ed1c56a3135f Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Thu, 11 May 2017 15:54:53 +0200 Subject: [PATCH 29/39] Simplify picking policy of the batch scheduler --- .../src/controller/scheduler/SMS.cpp | 67 +++++++++---------- .../simulator/src/controller/scheduler/SMS.h | 8 +-- 2 files changed, 35 insertions(+), 40 deletions(-) diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index 7f505a5d..0326d5e1 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -52,7 +52,7 @@ void SMS::batchScheduler() std::default_random_engine generator; std::bernoulli_distribution distribution((double) SJFprobability / 100.0); - wait(150, SC_NS); // Test Purpose +// wait(150, SC_NS); // Test Purpose while (true) { @@ -60,7 +60,7 @@ void SMS::batchScheduler() } } -bool SMS::selectSJF(sc_time memClk, std::map::iterator &lastSelectedThread) +bool SMS::selectSJF(sc_time memClk) { // find threads with non-empty ready batch std::vector threadsWithNonEmptyReadybatches; @@ -93,14 +93,14 @@ bool SMS::selectSJF(sc_time memClk, std::map::iterator &las Thread minThread = threadsWithNonEmptyReadybatches.front(); for (auto& thread : threadsWithNonEmptyReadybatches) { - if (inFlightMemRequestCounter[thread] <= inFlightMemRequestCounter[minThread]) + if (inFlightMemRequestCounter[thread] < inFlightMemRequestCounter[minThread]) { minThread = thread; } } // save selected thread - lastSelectedThread = readybatches.find(Thread(minThread)); + lastSelectedThread = readybatches.find(minThread); debugManager.printDebugMessage(name(), "[SJF] Select ready batch of thread " + to_string(minThread.ID())); @@ -131,14 +131,27 @@ bool SMS::selectSJF(sc_time memClk, std::map::iterator &las } -bool SMS::selectRR(sc_time memClk, std::map::iterator &nextSelectedThread) +bool SMS::selectRR(sc_time memClk) { // no request for this channel, the readybatches map is empty then return if (readybatches.empty()) { return false; } - // pick a non-empty ready batch + // pick the next non-empty ready batch + std::map::iterator nextSelectedThread; + if(lastSelectedThread == readybatches.end()) + { + lastSelectedThread = readybatches.begin(); + nextSelectedThread = lastSelectedThread; + } + else + { + nextSelectedThread = lastSelectedThread; + nextSelectedThread++; + if(nextSelectedThread == readybatches.end()) + nextSelectedThread = readybatches.begin(); + } std::map::iterator savedOriginalNextSelectedThread = nextSelectedThread; while ((*nextSelectedThread).second->isEmpty()) { @@ -166,6 +179,9 @@ bool SMS::selectRR(sc_time memClk, std::map::iterator &next } } } + // save last selected thread + lastSelectedThread = nextSelectedThread; + debugManager.printDebugMessage(name(), "[RR] Select ready batch of thread " + to_string((*nextSelectedThread).first.ID())); @@ -188,44 +204,23 @@ bool SMS::selectRR(sc_time memClk, std::map::iterator &next } void SMS::selectRR_SJF(bool isSJF, sc_time memClk) { + // pick correct policy + bool isSucessfulPick; if (isSJF) { // select by Shortest Job First policy - bool success = selectSJF(memClk, selectedThread); - if (!success) - { - wait(newRequest); - } + isSucessfulPick = selectSJF(memClk); } else { // select by Round Robin policy - if (selectedThread == readybatches.end()) - { - // first Round Robin selection - selectedThread = readybatches.begin(); - bool success = selectRR(memClk, selectedThread); - if (!success) - { - wait(newRequest); - } - } - else - { - // subsequent Round Robin selection - // move the select iterator to the next one - selectedThread++; - if (selectedThread == readybatches.end()) - { - selectedThread = readybatches.begin(); - } - bool success = selectRR(memClk, selectedThread); - if (!success) - { - wait(newRequest); - } - } + isSucessfulPick = selectRR(memClk); + } + // otherwise, wait for new request + if (!isSucessfulPick) + { + wait(newRequest); } } diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h index c3727120..64d2ad62 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.h +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h @@ -21,7 +21,7 @@ public: SMS(sc_module_name /*_name*/, ControllerCore &controllerCore, unsigned int SJFprobability) : IScheduler(controllerCore), SJFprobability(SJFprobability), debugManager(DebugManager::getInstance()) { // initialize selected thread iterator - selectedThread = readybatches.end(); + lastSelectedThread = readybatches.end(); SC_THREAD(batchScheduler); } SC_HAS_PROCESS(SMS); @@ -44,14 +44,14 @@ private: std::map> bankbuffer; std::map readybatches; std::map inFlightMemRequestCounter; - std::map::iterator selectedThread; + std::map::iterator lastSelectedThread; unsigned int SJFprobability; DebugManager& debugManager; sc_event newRequest; - bool selectSJF(sc_time memClk, std::map::iterator &select); - bool selectRR(sc_time memClk, std::map::iterator &next); + bool selectSJF(sc_time memClk); + bool selectRR(sc_time memClk); void selectRR_SJF(bool isSJF, sc_time memClk); }; From ea8213da1763269d09d3594b488fc47c4c07a90d Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Thu, 11 May 2017 23:27:47 +0200 Subject: [PATCH 30/39] Add raw MPKC module for calculating MPKC rate --- .../simulator/src/controller/scheduler/MPKC.h | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 DRAMSys/simulator/src/controller/scheduler/MPKC.h diff --git a/DRAMSys/simulator/src/controller/scheduler/MPKC.h b/DRAMSys/simulator/src/controller/scheduler/MPKC.h new file mode 100644 index 00000000..8b7add90 --- /dev/null +++ b/DRAMSys/simulator/src/controller/scheduler/MPKC.h @@ -0,0 +1,55 @@ +/* + * MPKC.h + * + * Created on: May 11, 2017 + * Author: thanhtran + */ + +#ifndef MPKC_H_ +#define MPKC_H_ + +#include "../../../common/Utils.h" + +using namespace std; + +class MPKC: public sc_module +{ + public: + MPKC(sc_module_name /*_name*/, sc_time memClk) : memClk(memClk) + { + lastGeneratedRequests = std::make_pair(0, 0); + SC_THREAD(updateMPKC); + } + SC_HAS_PROCESS(MPKC); + + void updateMPKC() + { + + while(true) + { + mpkc = 1 / (lastGeneratedRequests.second + numClk*memClk -lastGeneratedRequests.first); + wait(memClk); + numClk++; + } + } + + float getMPKC() + { + return mpkc; + } + + void sendNewRequest(sc_time timeOfGeneration) + { + std::swap(lastGeneratedRequests.first, lastGeneratedRequests.second); + lastGeneratedRequests.second = timeOfGeneration; + numClk = 0; + } + + private: + unsigned int numClk = 0; + sc_time memClk; + float mpkc = 0; + std::pair lastGeneratedRequests; +}; + +#endif /* MPKC_H_ */ From 066569c8560278232a76e08d78b752399fc95cd6 Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Mon, 15 May 2017 16:25:26 +0200 Subject: [PATCH 31/39] Adding MPKC & bypass mechanism --- .../src/controller/scheduler/SMS.cpp | 200 ++++++++++++------ .../simulator/src/controller/scheduler/SMS.h | 37 +++- 2 files changed, 159 insertions(+), 78 deletions(-) diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index 0326d5e1..aab6706e 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -7,23 +7,21 @@ void SMS::schedule(gp *payload) { Thread thread = DramExtension::getExtension(payload).getThread(); - buffer[thread].emplace_back(payload); + requestBuffers[thread].emplace_back(payload); if (inFlightMemRequestCounter.find(thread) == inFlightMemRequestCounter.end()) { inFlightMemRequestCounter[thread] = 0; + cacheMisses[thread] = 0; } inFlightMemRequestCounter[thread]++; - - if (readybatches.find(thread) == readybatches.end()) { - readybatches[thread] = new ReadyBatch(); - } + cacheMisses[thread]++; newRequest.notify(SC_ZERO_TIME); } std::pair SMS::getNextRequest(Bank bank) { - if (bankbuffer[bank].empty()) + if (bankBuffers[bank].empty()) { debugManager.printDebugMessage(name(), "Get next request on bank " + to_string(bank.ID()) + " : EMPTY buffer"); @@ -31,19 +29,18 @@ std::pair SMS::getNextRequest(Bank bank) } else { - gp* payload = bankbuffer[bank].front(); + gp* payload = bankBuffers[bank].front(); Command command = IScheduler::getNextCommand(*payload); if (command == Command::Read || command == Command::ReadA || command == Command::Write || command == Command::WriteA) { inFlightMemRequestCounter[DramExtension::getExtension(payload).getThread()]--; - bankbuffer[bank].pop_front(); + bankBuffers[bank].pop_front(); } debugManager.printDebugMessage(name(), "Get next request on bank " + to_string(bank.ID())); return pair(command, payload); } - } void SMS::batchScheduler() @@ -52,11 +49,23 @@ void SMS::batchScheduler() std::default_random_engine generator; std::bernoulli_distribution distribution((double) SJFprobability / 100.0); -// wait(150, SC_NS); // Test Purpose - while (true) { - selectRR_SJF(distribution(generator), memClk); + updateMPKCs(memClk); + if (isRequestBuffersEmpty() && !existReadyBatches()) { + wait(newRequest); + } else { + batchFormation(memClk); + if (existReadyBatches()) { + if (!isSystemLightlyLoaded() && (existLowIntensityThread() || distribution(generator))) { + selectSJF(memClk); + } else { + selectRR(memClk); + } + } else { + wait(memClk); + } + } } } @@ -66,25 +75,11 @@ bool SMS::selectSJF(sc_time memClk) std::vector threadsWithNonEmptyReadybatches; for (auto& readybatch : readybatches) { - if (!readybatch.second->isEmpty()) + if (!readybatch.second.empty()) { // marked as thread with non-empty ready batch threadsWithNonEmptyReadybatches.push_back(readybatch.first); } - else - { - // form ready batch for this thread - Thread thread = readybatch.first; - while (!buffer[thread].empty() && readybatch.second->addTransaction(buffer[thread].front())) - { - buffer[thread].pop_front(); - } - // marked as thread with non-empty ready batch - if (!readybatch.second->isEmpty()) - { - threadsWithNonEmptyReadybatches.push_back(readybatch.first); - } - } } if (!threadsWithNonEmptyReadybatches.empty()) @@ -106,12 +101,12 @@ bool SMS::selectSJF(sc_time memClk) "[SJF] Select ready batch of thread " + to_string(minThread.ID())); // drain to bank buffers - std::deque &requestPtrs = readybatches[minThread]->getTransactions(); + std::deque &requestPtrs = readybatches[minThread]; for (auto payloadPtrIterator = requestPtrs.begin(); payloadPtrIterator != requestPtrs.end(); payloadPtrIterator++) { Bank bank = DramExtension::getExtension(*payloadPtrIterator).getBank(); - bankbuffer[bank].emplace_back(*payloadPtrIterator); + bankBuffers[bank].emplace_back(*payloadPtrIterator); debugManager.printDebugMessage(name(), "[SJF] Drain request in the ready batch of thread " + to_string(minThread.ID()) + " to bankbuffer " + to_string(bank.ID())); @@ -139,7 +134,7 @@ bool SMS::selectRR(sc_time memClk) } // pick the next non-empty ready batch - std::map::iterator nextSelectedThread; + std::map>::iterator nextSelectedThread; if(lastSelectedThread == readybatches.end()) { lastSelectedThread = readybatches.begin(); @@ -152,31 +147,20 @@ bool SMS::selectRR(sc_time memClk) if(nextSelectedThread == readybatches.end()) nextSelectedThread = readybatches.begin(); } - std::map::iterator savedOriginalNextSelectedThread = nextSelectedThread; - while ((*nextSelectedThread).second->isEmpty()) + std::map>::iterator savedOriginalNextSelectedThread = nextSelectedThread; + while ((*nextSelectedThread).second.empty()) { - // form ready batch for this thread - Thread thread = (*nextSelectedThread).first; - while (!buffer[thread].empty() && (*nextSelectedThread).second->addTransaction(buffer[thread].front())) + nextSelectedThread++; + if (nextSelectedThread == readybatches.end()) { - buffer[thread].pop_front(); + nextSelectedThread = readybatches.begin(); } - if ((*nextSelectedThread).second->isEmpty()) + if (nextSelectedThread == savedOriginalNextSelectedThread) { - // cannot form ready batch then move to next thread - nextSelectedThread++; - if (nextSelectedThread == readybatches.end()) - { - nextSelectedThread = readybatches.begin(); - } - - if (nextSelectedThread == savedOriginalNextSelectedThread) - { - // the next thread is the original thread, that mean req buffer are totally empty - // non-existed ready batch to be picked up & drained - return false; - } + // the next thread is the original thread, that mean req buffer are totally empty + // non-existed ready batch to be picked up & drained + return false; } } // save last selected thread @@ -186,12 +170,12 @@ bool SMS::selectRR(sc_time memClk) "[RR] Select ready batch of thread " + to_string((*nextSelectedThread).first.ID())); // drain to bank buffers - std::deque &requestPtrs = (*nextSelectedThread).second->getTransactions(); + std::deque &requestPtrs = (*nextSelectedThread).second; for (auto payloadPtrIterator = requestPtrs.begin(); payloadPtrIterator != requestPtrs.end(); payloadPtrIterator++) { Bank bank = DramExtension::getExtension(*payloadPtrIterator).getBank(); - bankbuffer[bank].emplace_back(*payloadPtrIterator); + bankBuffers[bank].emplace_back(*payloadPtrIterator); debugManager.printDebugMessage(name(), "[RR] Drained request in the ready batch of thread " + to_string((*nextSelectedThread).first.ID()) + " to bankbuffer " + to_string(bank.ID())); @@ -203,24 +187,106 @@ bool SMS::selectRR(sc_time memClk) return true; } -void SMS::selectRR_SJF(bool isSJF, sc_time memClk) { - // pick correct policy - bool isSucessfulPick; - if (isSJF) - { - // select by Shortest Job First policy - isSucessfulPick = selectSJF(memClk); +bool SMS::isSystemLightlyLoaded() { + unsigned int totalRequest = 0; + for (auto& bankBuffer : bankBuffers) { + totalRequest += bankBuffer.second.size(); } - else - { - // select by Round Robin policy - isSucessfulPick = selectRR(memClk); + return (totalRequest <= LOW_SYSTEM_LOAD); +} + +bool SMS::existLowIntensityThread() { + for (auto& mpkcPerThread : MPKCs) { + if (mpkcPerThread.second < LOW_MPKC) { + return true; + } + } + return false; +} + +bool SMS::isThresholdAgeExceeded(Thread thread, sc_time memClk, std::deque::iterator begin, std::deque::iterator end) { + // find the oldest request in the thread's batch + sc_time oldestGenerationTime = sc_time_stamp(); + for (auto reqIter = begin; reqIter != end; reqIter++) { + sc_time reqGenerationTime = GenerationExtension::getExtension(*reqIter).TimeOfGeneration(); + if (reqGenerationTime < oldestGenerationTime) { + oldestGenerationTime = reqGenerationTime; + } } - // otherwise, wait for new request - if (!isSucessfulPick) - { - wait(newRequest); + // check threshold age according to the thread's MPKC + sc_time oldestRequestAge = sc_time_stamp() - oldestGenerationTime; + if ((MPKCs[thread] <= MEDIUM_MPKC) && (oldestRequestAge > (MEDIUM_THRESHOLD_AGE * memClk))) { + return true; + } else if ((MPKCs[thread] > MEDIUM_MPKC) && (oldestRequestAge > (HIGH_THRESHOLD_AGE * memClk))) { + return true; + } else { + return false; } } +void SMS::updateMPKCs(sc_time memClk) { + if (sc_time_stamp() % (MPKC_RESET_CYCLE * memClk) <= memClk) { + // reset for every 10k clk cycles + for (auto& mpkc : MPKCs) { + mpkc.second = 0; + } + } else { + // update MPKC for every thread + for (auto& mpkc : MPKCs) { + mpkc.second = (cacheMisses[mpkc.first] * 1000.0 * memClk) / (sc_time_stamp()); + } + } +} + +bool SMS::isExceededReqBufferSize(Thread thread) { + return requestBuffers[thread].size() == REQUEST_BUFFER_SIZE; +} + +void SMS::batchFormation(sc_time memClk) { + for (auto& requestBuffer : requestBuffers) { + if (!requestBuffer.second.empty() && !readybatches[requestBuffer.first].empty()) { + if (MPKCs[requestBuffer.first] < LOW_MPKC || isSystemLightlyLoaded()) { + // bypass requests by forming batch with only one request (threshold age is ZERO) + readybatches[requestBuffer.first].emplace_back(requestBuffer.second.front()); + requestBuffer.second.pop_front(); + } else { + // forming batch with FIFO size & threshold age constraints + auto firstDifferentRowAccessReqIter = requestBuffer.second.begin(); + Row firstRow = DramExtension::getRow(*firstDifferentRowAccessReqIter); + while (firstDifferentRowAccessReqIter != requestBuffer.second.end() && DramExtension::getRow(*firstDifferentRowAccessReqIter) == firstRow) { + firstDifferentRowAccessReqIter++; + } + // deem this batch ready + if ((firstDifferentRowAccessReqIter != requestBuffer.second.end()) + || isExceededReqBufferSize(requestBuffer.first) + || isThresholdAgeExceeded(requestBuffer.first, memClk, requestBuffer.second.begin(), firstDifferentRowAccessReqIter)) { + do { + readybatches[requestBuffer.first].emplace_back(requestBuffer.second.front()); + requestBuffer.second.pop_front(); + } while (requestBuffer.second.begin() != firstDifferentRowAccessReqIter); + } + } + } + } +} + +bool SMS::isRequestBuffersEmpty() { + for (auto& requestBuffer : requestBuffers) { + if (!requestBuffer.second.empty()) { + return false; + } + } + return true; +} + +bool SMS::existReadyBatches() { + for (auto& readybatch : readybatches) { + if (readybatch.second.empty()) { + return true; + } + } + return false; +} + + diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h index 64d2ad62..ee4afd79 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.h +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h @@ -11,7 +11,13 @@ #include "../../common/dramExtension.h" #include "../../common/DebugManager.h" -#define MIN_TOTAL_REQ 16 +#define LOW_SYSTEM_LOAD 16 +#define LOW_MPKC 1 +#define MEDIUM_MPKC 10 +#define MEDIUM_THRESHOLD_AGE 50 +#define HIGH_THRESHOLD_AGE 200 +#define MPKC_RESET_CYCLE 10000 +#define REQUEST_BUFFER_SIZE 10 using namespace std; @@ -28,10 +34,6 @@ public: virtual ~SMS() { - for (auto& thread_readybatch : readybatches) - { - delete thread_readybatch.second; - } } virtual void schedule(gp *payload) override; @@ -40,19 +42,32 @@ public: void batchScheduler(); private: - std::map> buffer; - std::map> bankbuffer; - std::map readybatches; + std::map> requestBuffers; + std::map> bankBuffers; + std::map> readybatches; + std::map inFlightMemRequestCounter; - std::map::iterator lastSelectedThread; + std::map cacheMisses; + std::map MPKCs; unsigned int SJFprobability; - DebugManager& debugManager; + std::map>::iterator lastSelectedThread; sc_event newRequest; + DebugManager& debugManager; + bool selectSJF(sc_time memClk); bool selectRR(sc_time memClk); - void selectRR_SJF(bool isSJF, sc_time memClk); + void batchFormation(sc_time memClk); + + bool existLowIntensityThread(); + bool isSystemLightlyLoaded(); + bool isThresholdAgeExceeded(Thread thread, sc_time memClk, std::deque::iterator begin, std::deque::iterator end); + bool isExceededReqBufferSize(Thread thread); + void updateMPKCs(sc_time memClk); + + bool isRequestBuffersEmpty(); + bool existReadyBatches(); }; #endif // SMS_H From d489db6a46e51b91da262e9c6c7bad40da0b72b5 Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Tue, 16 May 2017 01:35:10 +0200 Subject: [PATCH 32/39] Fix bug --- .../resources/configs/mcconfigs/sms.xml | 1 + .../src/controller/scheduler/SMS.cpp | 21 ++++++++++++------- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/DRAMSys/simulator/resources/configs/mcconfigs/sms.xml b/DRAMSys/simulator/resources/configs/mcconfigs/sms.xml index 19490a2c..84551d57 100644 --- a/DRAMSys/simulator/resources/configs/mcconfigs/sms.xml +++ b/DRAMSys/simulator/resources/configs/mcconfigs/sms.xml @@ -14,4 +14,5 @@ + \ No newline at end of file diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index aab6706e..24022e1c 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -6,6 +6,7 @@ using namespace std; void SMS::schedule(gp *payload) { Thread thread = DramExtension::getExtension(payload).getThread(); + bool wasEmpty = isRequestBuffersEmpty(); requestBuffers[thread].emplace_back(payload); @@ -16,7 +17,9 @@ void SMS::schedule(gp *payload) inFlightMemRequestCounter[thread]++; cacheMisses[thread]++; - newRequest.notify(SC_ZERO_TIME); + if (wasEmpty) { + newRequest.notify(SC_ZERO_TIME); + } } std::pair SMS::getNextRequest(Bank bank) @@ -228,14 +231,16 @@ bool SMS::isThresholdAgeExceeded(Thread thread, sc_time memClk, std::deque: void SMS::updateMPKCs(sc_time memClk) { if (sc_time_stamp() % (MPKC_RESET_CYCLE * memClk) <= memClk) { // reset for every 10k clk cycles - for (auto& mpkc : MPKCs) { - mpkc.second = 0; + for (auto& cacheMiss : cacheMisses) { + MPKCs[cacheMiss.first] = 0; } + debugManager.printDebugMessage(name(), "Reset MKKCs"); } else { // update MPKC for every thread - for (auto& mpkc : MPKCs) { - mpkc.second = (cacheMisses[mpkc.first] * 1000.0 * memClk) / (sc_time_stamp()); + for (auto& cacheMiss : cacheMisses) { + MPKCs[cacheMiss.first] = (cacheMiss.second * 1000.0 * memClk) / (sc_time_stamp()); } + debugManager.printDebugMessage(name(), "Update MPKCs"); } } @@ -245,11 +250,12 @@ bool SMS::isExceededReqBufferSize(Thread thread) { void SMS::batchFormation(sc_time memClk) { for (auto& requestBuffer : requestBuffers) { - if (!requestBuffer.second.empty() && !readybatches[requestBuffer.first].empty()) { + if (!requestBuffer.second.empty() && readybatches[requestBuffer.first].empty()) { if (MPKCs[requestBuffer.first] < LOW_MPKC || isSystemLightlyLoaded()) { // bypass requests by forming batch with only one request (threshold age is ZERO) readybatches[requestBuffer.first].emplace_back(requestBuffer.second.front()); requestBuffer.second.pop_front(); + debugManager.printDebugMessage(name(), "Bypass requests by forming batch of thread " + to_string(requestBuffer.first.ID())); } else { // forming batch with FIFO size & threshold age constraints auto firstDifferentRowAccessReqIter = requestBuffer.second.begin(); @@ -265,6 +271,7 @@ void SMS::batchFormation(sc_time memClk) { readybatches[requestBuffer.first].emplace_back(requestBuffer.second.front()); requestBuffer.second.pop_front(); } while (requestBuffer.second.begin() != firstDifferentRowAccessReqIter); + debugManager.printDebugMessage(name(), "Deem batch ready - thread " + to_string(requestBuffer.first.ID())); } } } @@ -282,7 +289,7 @@ bool SMS::isRequestBuffersEmpty() { bool SMS::existReadyBatches() { for (auto& readybatch : readybatches) { - if (readybatch.second.empty()) { + if (!readybatch.second.empty()) { return true; } } From dab223757258de670c8b41b829ff546c064a3fd5 Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Tue, 16 May 2017 01:38:53 +0200 Subject: [PATCH 33/39] First try to form multiple ready batches --- .../src/controller/scheduler/SMS.cpp | 194 +++++++++++++++++- .../simulator/src/controller/scheduler/SMS.h | 9 +- 2 files changed, 198 insertions(+), 5 deletions(-) diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index 24022e1c..ba1d2199 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -72,6 +72,48 @@ void SMS::batchScheduler() } } +/** + * Pick a Thread according to Shortest-Job Policy + * Save the picked one into lastSelectedThread + * @return true if it can, otherwise false + */ +bool SMS::pickSJF() +{ + // find threads with non-empty request buffers + std::vector threadsWithNonEmptyRequestBuffer; + for (auto& requestBuffer : requestBuffers) + { + if (!requestBuffer.second.empty()) + { + // marked as thread with non-empty request buffer + threadsWithNonEmptyRequestBuffer.push_back(requestBuffer.first); + } + } + + if (!threadsWithNonEmptyRequestBuffer.empty()) + { + // pick shortest-job thread among threads with non-empty request buffer + Thread minThread = threadsWithNonEmptyRequestBuffer.front(); + for (auto& thread : threadsWithNonEmptyRequestBuffer) + { + if (inFlightMemRequestCounter[thread] < inFlightMemRequestCounter[minThread]) + { + minThread = thread; + } + } + + // save selected thread + lastSelectedThread = readybatches.find(minThread); + debugManager.printDebugMessage(name(), + "[SJF] Select ready batch of thread " + to_string(minThread.ID())); + return true; + } + else + { + return false; + } +} + bool SMS::selectSJF(sc_time memClk) { // find threads with non-empty ready batch @@ -126,7 +168,78 @@ bool SMS::selectSJF(sc_time memClk) // this mean the request buffers are totally empty return false; } +} +/** + * Drain the picked request buffer into bank buffers + * by move request one-by-one from start of the request buffer till last parameter + * @param memClk + * @param last + */ +void SMS::drain(sc_time memClk, std::deque::iterator last) +{ + unsigned int batchSize = std::distance((*lastSelectedThread).second.begin(), last) + 1; + for (unsigned int i = 1; i <= batchSize; i++) + { + Bank bank = DramExtension::getExtension(*((*lastSelectedThread).second.begin())).getBank(); + // if(bankBuffers[bank].size() == Configuration::getInstance().BankBufferSize) + // { + // wait(bankBufferIsNotFull); + // } + wait(memClk); + bankBuffers[bank].emplace_back(*((*lastSelectedThread).second.begin())); + (*lastSelectedThread).second.pop_front(); + + debugManager.printDebugMessage(name(), + "[SJF] Drain request in the ready batch of thread " + + to_string((*lastSelectedThread).first.ID()) + " to bankbuffer " + + to_string(bank.ID())); + } +} + +/** + * Pick a Thread according to Round-Robin Policy + * Save the picked one into lastSelectedThread + * @return true if it can pick one, otherwise false + */ +bool SMS::pickRR() +{ + std::map>::iterator nextSelectedThread; + if (lastSelectedThread == requestBuffers.end()) + { + lastSelectedThread = requestBuffers.begin(); + nextSelectedThread = lastSelectedThread; + } + else + { + nextSelectedThread = lastSelectedThread; + nextSelectedThread++; + if (nextSelectedThread == requestBuffers.end()) + nextSelectedThread = requestBuffers.begin(); + } + + std::map>::iterator savedOriginalNextSelectedThread = nextSelectedThread; + + while ((*nextSelectedThread).second.empty()) + { + nextSelectedThread++; + if (nextSelectedThread == requestBuffers.end()) + { + nextSelectedThread = requestBuffers.begin(); + } + + if (nextSelectedThread == savedOriginalNextSelectedThread) + { + // the next thread is the original thread, that mean req buffer are totally empty + // non-existed ready batch to be picked up & drained + return false; + } + } + // save last selected thread + lastSelectedThread = nextSelectedThread; + debugManager.printDebugMessage(name(), + "[RR] Select ready batch of thread " + to_string((*nextSelectedThread).first.ID())); + return true; } bool SMS::selectRR(sc_time memClk) @@ -138,7 +251,7 @@ bool SMS::selectRR(sc_time memClk) // pick the next non-empty ready batch std::map>::iterator nextSelectedThread; - if(lastSelectedThread == readybatches.end()) + if (lastSelectedThread == readybatches.end()) { lastSelectedThread = readybatches.begin(); nextSelectedThread = lastSelectedThread; @@ -147,7 +260,7 @@ bool SMS::selectRR(sc_time memClk) { nextSelectedThread = lastSelectedThread; nextSelectedThread++; - if(nextSelectedThread == readybatches.end()) + if (nextSelectedThread == readybatches.end()) nextSelectedThread = readybatches.begin(); } std::map>::iterator savedOriginalNextSelectedThread = nextSelectedThread; @@ -232,7 +345,7 @@ void SMS::updateMPKCs(sc_time memClk) { if (sc_time_stamp() % (MPKC_RESET_CYCLE * memClk) <= memClk) { // reset for every 10k clk cycles for (auto& cacheMiss : cacheMisses) { - MPKCs[cacheMiss.first] = 0; + MPKCs[cacheMiss.first] = 0; } debugManager.printDebugMessage(name(), "Reset MKKCs"); } else { @@ -265,7 +378,7 @@ void SMS::batchFormation(sc_time memClk) { } // deem this batch ready if ((firstDifferentRowAccessReqIter != requestBuffer.second.end()) - || isExceededReqBufferSize(requestBuffer.first) + || isExceededReqBufferSize(requestBuffer.first) || isThresholdAgeExceeded(requestBuffer.first, memClk, requestBuffer.second.begin(), firstDifferentRowAccessReqIter)) { do { readybatches[requestBuffer.first].emplace_back(requestBuffer.second.front()); @@ -296,4 +409,77 @@ bool SMS::existReadyBatches() { return false; } +/** + * Form batch from begin iterator parameter of a request buffer + * If this batch is deemed ready, save the iterator pointing to its last element + * @param memClk + * @param begin + * @return true if this batch is ready, otherwise false + */ +bool SMS::batchFormation(sc_time memClk, std::pair> &requestBuffer, + std::deque::iterator beginIter) +{ + if (requestBuffer.second.empty()) + { + return false; + } + if (requestBuffer.second.end() == beginIter) + { + return false; + } + + if (MPKCs[requestBuffer.first] < LOW_MPKC || isSystemLightlyLoaded()) + { + // bypass requests by forming batch with only one request (threshold age is ZERO) + readyBatchesIter[requestBuffer.first].push_back(beginIter); + return true; + } + else + { + // forming batch with FIFO size & threshold age constraints + auto firstDifferentRowAccessReqIter = beginIter; + Row firstRow = DramExtension::getRow(*beginIter); + while (firstDifferentRowAccessReqIter != requestBuffer.second.end() + && DramExtension::getRow(*firstDifferentRowAccessReqIter) == firstRow) + { + firstDifferentRowAccessReqIter++; + } + + // deem this batch ready + if ((firstDifferentRowAccessReqIter != requestBuffer.second.end()) + || isExceededReqBufferSize(requestBuffer.first) + || isThresholdAgeExceeded(requestBuffer.first, memClk, beginIter, + firstDifferentRowAccessReqIter)) + { + firstDifferentRowAccessReqIter--; + readyBatchesIter[requestBuffer.first].push_back(firstDifferentRowAccessReqIter); + debugManager.printDebugMessage(name(), + "Deem batch ready - thread " + to_string(requestBuffer.first.ID())); + return true; + } + else + { + return false; + } + } +} + +void SMS::multiBatchFormation(sc_time memClk) +{ + for (auto& requestBuffer : requestBuffers) + { + bool formed; + do + { + if (readyBatchesIter[requestBuffer.first].empty()) + { + formed = batchFormation(memClk, (std::pair>&)requestBuffer, requestBuffer.second.begin()); + } + else + { + formed = batchFormation(memClk, (std::pair>&)requestBuffer, readyBatchesIter[requestBuffer.first].back() + 1); + } + } while (formed); + } +} diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h index ee4afd79..6e4297ba 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.h +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h @@ -27,7 +27,8 @@ public: SMS(sc_module_name /*_name*/, ControllerCore &controllerCore, unsigned int SJFprobability) : IScheduler(controllerCore), SJFprobability(SJFprobability), debugManager(DebugManager::getInstance()) { // initialize selected thread iterator - lastSelectedThread = readybatches.end(); + lastSelectedThread = readybatches.end(); +// lastSelectedThread = requestBuffers.end(); SC_THREAD(batchScheduler); } SC_HAS_PROCESS(SMS); @@ -45,6 +46,7 @@ private: std::map> requestBuffers; std::map> bankBuffers; std::map> readybatches; + std::map::iterator>> readyBatchesIter; std::map inFlightMemRequestCounter; std::map cacheMisses; @@ -59,6 +61,11 @@ private: bool selectSJF(sc_time memClk); bool selectRR(sc_time memClk); void batchFormation(sc_time memClk); + bool batchFormation(sc_time memClk, std::pair> &requestBuffer, std::deque::iterator beginIter); + void multiBatchFormation(sc_time memClk); + bool pickSJF(); + bool pickRR(); + void drain(sc_time memClk, std::deque::iterator last); bool existLowIntensityThread(); bool isSystemLightlyLoaded(); From 6d739c64f1d38f86548840da235a03d2c454ff60 Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Tue, 16 May 2017 02:03:10 +0200 Subject: [PATCH 34/39] Finish multiple ready batch formation --- .../src/controller/scheduler/SMS.cpp | 35 ++++++++++++++----- .../simulator/src/controller/scheduler/SMS.h | 4 +-- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index ba1d2199..14d63207 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -54,19 +54,36 @@ void SMS::batchScheduler() while (true) { +// updateMPKCs(memClk); +// if (isRequestBuffersEmpty() && !existReadyBatches()) { +// wait(newRequest); +// } else { +// batchFormation(memClk); +// if (existReadyBatches()) { +// if (!isSystemLightlyLoaded() && (existLowIntensityThread() || distribution(generator))) { +// selectSJF(memClk); +// } else { +// selectRR(memClk); +// } +// } else { +// wait(memClk); +// } +// } updateMPKCs(memClk); - if (isRequestBuffersEmpty() && !existReadyBatches()) { - wait(newRequest); + if (isRequestBuffersEmpty()) { + wait(newRequest); } else { - batchFormation(memClk); - if (existReadyBatches()) { - if (!isSystemLightlyLoaded() && (existLowIntensityThread() || distribution(generator))) { - selectSJF(memClk); - } else { - selectRR(memClk); + multiBatchFormation(memClk); + if (!isSystemLightlyLoaded() && (existLowIntensityThread() || distribution(generator))) { + if (pickSJF()) { + drain(memClk, readyBatchesIter[(*lastSelectedThread).first].front()); + readyBatchesIter[(*lastSelectedThread).first].pop_front(); } } else { - wait(memClk); + if (pickRR()) { + drain(memClk, readyBatchesIter[(*lastSelectedThread).first].front()); + readyBatchesIter[(*lastSelectedThread).first].pop_front(); + } } } } diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h index 6e4297ba..c786fbcc 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.h +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h @@ -27,8 +27,8 @@ public: SMS(sc_module_name /*_name*/, ControllerCore &controllerCore, unsigned int SJFprobability) : IScheduler(controllerCore), SJFprobability(SJFprobability), debugManager(DebugManager::getInstance()) { // initialize selected thread iterator - lastSelectedThread = readybatches.end(); -// lastSelectedThread = requestBuffers.end(); +// lastSelectedThread = readybatches.end(); + lastSelectedThread = requestBuffers.end(); SC_THREAD(batchScheduler); } SC_HAS_PROCESS(SMS); From ab2b87aaeb65e89f78f68581fce47f7a6f690203 Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Thu, 1 Jun 2017 02:24:05 +0200 Subject: [PATCH 35/39] Fix bug 1. Trying to drain request from empty request buffers & empty ready batch iterators 2. lastSelectedThread Iterator pointing to readybatchIters instead --- .../resources/simulations/sms-example.xml | 4 + .../src/controller/scheduler/SMS.cpp | 237 +++--------------- .../simulator/src/controller/scheduler/SMS.h | 12 +- 3 files changed, 48 insertions(+), 205 deletions(-) diff --git a/DRAMSys/simulator/resources/simulations/sms-example.xml b/DRAMSys/simulator/resources/simulations/sms-example.xml index d1a2f734..d40e0e8c 100644 --- a/DRAMSys/simulator/resources/simulations/sms-example.xml +++ b/DRAMSys/simulator/resources/simulations/sms-example.xml @@ -12,10 +12,14 @@ + ddr3_example.stl sms_t1.stl sms_t2.stl sms_t3.stl sms_t4.stl + stream.stl + random.stl + chstone-adpcm_32.stl diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index 14d63207..d4336415 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -54,36 +54,25 @@ void SMS::batchScheduler() while (true) { -// updateMPKCs(memClk); -// if (isRequestBuffersEmpty() && !existReadyBatches()) { -// wait(newRequest); -// } else { -// batchFormation(memClk); -// if (existReadyBatches()) { -// if (!isSystemLightlyLoaded() && (existLowIntensityThread() || distribution(generator))) { -// selectSJF(memClk); -// } else { -// selectRR(memClk); -// } -// } else { -// wait(memClk); -// } -// } updateMPKCs(memClk); if (isRequestBuffersEmpty()) { wait(newRequest); } else { multiBatchFormation(memClk); - if (!isSystemLightlyLoaded() && (existLowIntensityThread() || distribution(generator))) { - if (pickSJF()) { - drain(memClk, readyBatchesIter[(*lastSelectedThread).first].front()); - readyBatchesIter[(*lastSelectedThread).first].pop_front(); + if (existReadyBatches()) { + if (!isSystemLightlyLoaded() && (existLowIntensityThread() || distribution(generator))) { + if (pickSJF()) { + drain(memClk, (*lastSelectedThread).second.front()); + (*lastSelectedThread).second.pop_front(); + } + } else { + if (pickRR()) { + drain(memClk, (*lastSelectedThread).second.front()); + (*lastSelectedThread).second.pop_front(); + } } } else { - if (pickRR()) { - drain(memClk, readyBatchesIter[(*lastSelectedThread).first].front()); - readyBatchesIter[(*lastSelectedThread).first].pop_front(); - } + wait(memClk); } } } @@ -96,22 +85,22 @@ void SMS::batchScheduler() */ bool SMS::pickSJF() { - // find threads with non-empty request buffers - std::vector threadsWithNonEmptyRequestBuffer; - for (auto& requestBuffer : requestBuffers) + // find threads with ready batches + std::vector threadsWithReadyBatches; + for (auto& each : readyBatchIters) { - if (!requestBuffer.second.empty()) + if (!each.second.empty()) { // marked as thread with non-empty request buffer - threadsWithNonEmptyRequestBuffer.push_back(requestBuffer.first); + threadsWithReadyBatches.push_back(each.first); } } - if (!threadsWithNonEmptyRequestBuffer.empty()) + if (!threadsWithReadyBatches.empty()) { // pick shortest-job thread among threads with non-empty request buffer - Thread minThread = threadsWithNonEmptyRequestBuffer.front(); - for (auto& thread : threadsWithNonEmptyRequestBuffer) + Thread minThread = threadsWithReadyBatches.front(); + for (auto& thread : threadsWithReadyBatches) { if (inFlightMemRequestCounter[thread] < inFlightMemRequestCounter[minThread]) { @@ -120,7 +109,7 @@ bool SMS::pickSJF() } // save selected thread - lastSelectedThread = readybatches.find(minThread); + lastSelectedThread = readyBatchIters.find(minThread); debugManager.printDebugMessage(name(), "[SJF] Select ready batch of thread " + to_string(minThread.ID())); return true; @@ -131,62 +120,6 @@ bool SMS::pickSJF() } } -bool SMS::selectSJF(sc_time memClk) -{ - // find threads with non-empty ready batch - std::vector threadsWithNonEmptyReadybatches; - for (auto& readybatch : readybatches) - { - if (!readybatch.second.empty()) - { - // marked as thread with non-empty ready batch - threadsWithNonEmptyReadybatches.push_back(readybatch.first); - } - } - - if (!threadsWithNonEmptyReadybatches.empty()) - { - // pick shortest-job thread among threads with non-empty ready batch - Thread minThread = threadsWithNonEmptyReadybatches.front(); - for (auto& thread : threadsWithNonEmptyReadybatches) - { - if (inFlightMemRequestCounter[thread] < inFlightMemRequestCounter[minThread]) - { - minThread = thread; - } - } - - // save selected thread - lastSelectedThread = readybatches.find(minThread); - - debugManager.printDebugMessage(name(), - "[SJF] Select ready batch of thread " + to_string(minThread.ID())); - - // drain to bank buffers - std::deque &requestPtrs = readybatches[minThread]; - for (auto payloadPtrIterator = requestPtrs.begin(); payloadPtrIterator != requestPtrs.end(); - payloadPtrIterator++) - { - Bank bank = DramExtension::getExtension(*payloadPtrIterator).getBank(); - bankBuffers[bank].emplace_back(*payloadPtrIterator); - debugManager.printDebugMessage(name(), - "[SJF] Drain request in the ready batch of thread " + to_string(minThread.ID()) - + " to bankbuffer " + to_string(bank.ID())); - wait(memClk); - } - requestPtrs.clear(); - - // a ready batch has been picked up & drained - return true; - } - else - { - // non-existed ready batch to be picked up & drained - // this mean the request buffers are totally empty - return false; - } -} - /** * Drain the picked request buffer into bank buffers * by move request one-by-one from start of the request buffer till last parameter @@ -195,17 +128,18 @@ bool SMS::selectSJF(sc_time memClk) */ void SMS::drain(sc_time memClk, std::deque::iterator last) { - unsigned int batchSize = std::distance((*lastSelectedThread).second.begin(), last) + 1; + Thread selectedThread = (*lastSelectedThread).first; + unsigned int batchSize = std::distance(requestBuffers[selectedThread].begin(), last) + 1; for (unsigned int i = 1; i <= batchSize; i++) { - Bank bank = DramExtension::getExtension(*((*lastSelectedThread).second.begin())).getBank(); + Bank bank = DramExtension::getExtension(requestBuffers[selectedThread].front()).getBank(); // if(bankBuffers[bank].size() == Configuration::getInstance().BankBufferSize) // { // wait(bankBufferIsNotFull); // } wait(memClk); - bankBuffers[bank].emplace_back(*((*lastSelectedThread).second.begin())); - (*lastSelectedThread).second.pop_front(); + bankBuffers[bank].emplace_back(requestBuffers[selectedThread].front()); + requestBuffers[selectedThread].pop_front(); debugManager.printDebugMessage(name(), "[SJF] Drain request in the ready batch of thread " @@ -221,28 +155,28 @@ void SMS::drain(sc_time memClk, std::deque::iterator last) */ bool SMS::pickRR() { - std::map>::iterator nextSelectedThread; - if (lastSelectedThread == requestBuffers.end()) + std::map>::iterator nextSelectedThread; + if (lastSelectedThread == readyBatchIters.end()) { - lastSelectedThread = requestBuffers.begin(); + lastSelectedThread = readyBatchIters.begin(); nextSelectedThread = lastSelectedThread; } else { nextSelectedThread = lastSelectedThread; nextSelectedThread++; - if (nextSelectedThread == requestBuffers.end()) - nextSelectedThread = requestBuffers.begin(); + if (nextSelectedThread == readyBatchIters.end()) + nextSelectedThread = readyBatchIters.begin(); } - std::map>::iterator savedOriginalNextSelectedThread = nextSelectedThread; + std::map>::iterator savedOriginalNextSelectedThread = nextSelectedThread; while ((*nextSelectedThread).second.empty()) { nextSelectedThread++; - if (nextSelectedThread == requestBuffers.end()) + if (nextSelectedThread == readyBatchIters.end()) { - nextSelectedThread = requestBuffers.begin(); + nextSelectedThread = readyBatchIters.begin(); } if (nextSelectedThread == savedOriginalNextSelectedThread) @@ -259,67 +193,6 @@ bool SMS::pickRR() return true; } -bool SMS::selectRR(sc_time memClk) -{ - // no request for this channel, the readybatches map is empty then return - if (readybatches.empty()) { - return false; - } - - // pick the next non-empty ready batch - std::map>::iterator nextSelectedThread; - if (lastSelectedThread == readybatches.end()) - { - lastSelectedThread = readybatches.begin(); - nextSelectedThread = lastSelectedThread; - } - else - { - nextSelectedThread = lastSelectedThread; - nextSelectedThread++; - if (nextSelectedThread == readybatches.end()) - nextSelectedThread = readybatches.begin(); - } - std::map>::iterator savedOriginalNextSelectedThread = nextSelectedThread; - while ((*nextSelectedThread).second.empty()) - { - nextSelectedThread++; - if (nextSelectedThread == readybatches.end()) - { - nextSelectedThread = readybatches.begin(); - } - - if (nextSelectedThread == savedOriginalNextSelectedThread) - { - // the next thread is the original thread, that mean req buffer are totally empty - // non-existed ready batch to be picked up & drained - return false; - } - } - // save last selected thread - lastSelectedThread = nextSelectedThread; - - debugManager.printDebugMessage(name(), - "[RR] Select ready batch of thread " + to_string((*nextSelectedThread).first.ID())); - - // drain to bank buffers - std::deque &requestPtrs = (*nextSelectedThread).second; - for (auto payloadPtrIterator = requestPtrs.begin(); payloadPtrIterator != requestPtrs.end(); - payloadPtrIterator++) - { - Bank bank = DramExtension::getExtension(*payloadPtrIterator).getBank(); - bankBuffers[bank].emplace_back(*payloadPtrIterator); - debugManager.printDebugMessage(name(), - "[RR] Drained request in the ready batch of thread " + to_string((*nextSelectedThread).first.ID()) - + " to bankbuffer " + to_string(bank.ID())); - wait(memClk); - } - requestPtrs.clear(); - - // a ready batch has been picked up & drained - return true; -} - bool SMS::isSystemLightlyLoaded() { unsigned int totalRequest = 0; for (auto& bankBuffer : bankBuffers) { @@ -378,36 +251,6 @@ bool SMS::isExceededReqBufferSize(Thread thread) { return requestBuffers[thread].size() == REQUEST_BUFFER_SIZE; } -void SMS::batchFormation(sc_time memClk) { - for (auto& requestBuffer : requestBuffers) { - if (!requestBuffer.second.empty() && readybatches[requestBuffer.first].empty()) { - if (MPKCs[requestBuffer.first] < LOW_MPKC || isSystemLightlyLoaded()) { - // bypass requests by forming batch with only one request (threshold age is ZERO) - readybatches[requestBuffer.first].emplace_back(requestBuffer.second.front()); - requestBuffer.second.pop_front(); - debugManager.printDebugMessage(name(), "Bypass requests by forming batch of thread " + to_string(requestBuffer.first.ID())); - } else { - // forming batch with FIFO size & threshold age constraints - auto firstDifferentRowAccessReqIter = requestBuffer.second.begin(); - Row firstRow = DramExtension::getRow(*firstDifferentRowAccessReqIter); - while (firstDifferentRowAccessReqIter != requestBuffer.second.end() && DramExtension::getRow(*firstDifferentRowAccessReqIter) == firstRow) { - firstDifferentRowAccessReqIter++; - } - // deem this batch ready - if ((firstDifferentRowAccessReqIter != requestBuffer.second.end()) - || isExceededReqBufferSize(requestBuffer.first) - || isThresholdAgeExceeded(requestBuffer.first, memClk, requestBuffer.second.begin(), firstDifferentRowAccessReqIter)) { - do { - readybatches[requestBuffer.first].emplace_back(requestBuffer.second.front()); - requestBuffer.second.pop_front(); - } while (requestBuffer.second.begin() != firstDifferentRowAccessReqIter); - debugManager.printDebugMessage(name(), "Deem batch ready - thread " + to_string(requestBuffer.first.ID())); - } - } - } - } -} - bool SMS::isRequestBuffersEmpty() { for (auto& requestBuffer : requestBuffers) { if (!requestBuffer.second.empty()) { @@ -418,8 +261,8 @@ bool SMS::isRequestBuffersEmpty() { } bool SMS::existReadyBatches() { - for (auto& readybatch : readybatches) { - if (!readybatch.second.empty()) { + for (auto& each : readyBatchIters) { + if (!each.second.empty()) { return true; } } @@ -449,7 +292,7 @@ bool SMS::batchFormation(sc_time memClk, std::pair> &req if (MPKCs[requestBuffer.first] < LOW_MPKC || isSystemLightlyLoaded()) { // bypass requests by forming batch with only one request (threshold age is ZERO) - readyBatchesIter[requestBuffer.first].push_back(beginIter); + readyBatchIters[requestBuffer.first].push_back(beginIter); return true; } else @@ -470,7 +313,7 @@ bool SMS::batchFormation(sc_time memClk, std::pair> &req firstDifferentRowAccessReqIter)) { firstDifferentRowAccessReqIter--; - readyBatchesIter[requestBuffer.first].push_back(firstDifferentRowAccessReqIter); + readyBatchIters[requestBuffer.first].push_back(firstDifferentRowAccessReqIter); debugManager.printDebugMessage(name(), "Deem batch ready - thread " + to_string(requestBuffer.first.ID())); return true; @@ -489,13 +332,13 @@ void SMS::multiBatchFormation(sc_time memClk) bool formed; do { - if (readyBatchesIter[requestBuffer.first].empty()) + if (readyBatchIters[requestBuffer.first].empty()) { formed = batchFormation(memClk, (std::pair>&)requestBuffer, requestBuffer.second.begin()); } else { - formed = batchFormation(memClk, (std::pair>&)requestBuffer, readyBatchesIter[requestBuffer.first].back() + 1); + formed = batchFormation(memClk, (std::pair>&)requestBuffer, readyBatchIters[requestBuffer.first].back() + 1); } } while (formed); } diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h index c786fbcc..df9c132f 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.h +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h @@ -20,6 +20,7 @@ #define REQUEST_BUFFER_SIZE 10 using namespace std; +typedef std::deque::iterator gp_deque_iterator; class SMS: public sc_module, public IScheduler { @@ -27,8 +28,7 @@ public: SMS(sc_module_name /*_name*/, ControllerCore &controllerCore, unsigned int SJFprobability) : IScheduler(controllerCore), SJFprobability(SJFprobability), debugManager(DebugManager::getInstance()) { // initialize selected thread iterator -// lastSelectedThread = readybatches.end(); - lastSelectedThread = requestBuffers.end(); + lastSelectedThread = readyBatchIters.end(); SC_THREAD(batchScheduler); } SC_HAS_PROCESS(SMS); @@ -45,22 +45,18 @@ public: private: std::map> requestBuffers; std::map> bankBuffers; - std::map> readybatches; - std::map::iterator>> readyBatchesIter; + std::map> readyBatchIters; std::map inFlightMemRequestCounter; std::map cacheMisses; std::map MPKCs; unsigned int SJFprobability; - std::map>::iterator lastSelectedThread; + std::map>::iterator lastSelectedThread; sc_event newRequest; DebugManager& debugManager; - bool selectSJF(sc_time memClk); - bool selectRR(sc_time memClk); - void batchFormation(sc_time memClk); bool batchFormation(sc_time memClk, std::pair> &requestBuffer, std::deque::iterator beginIter); void multiBatchFormation(sc_time memClk); bool pickSJF(); From dca7d88a68608ab36940700da034ab03b5c6dec3 Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Mon, 12 Jun 2017 12:34:53 +0200 Subject: [PATCH 36/39] Clean up unused classes & Add notes about SMS scheduler --- DRAMSys/simulator/library.pro | 2 - .../simulator/src/controller/scheduler/MPKC.h | 55 ----------------- .../src/controller/scheduler/ReadyBatch.cpp | 59 ------------------- .../src/controller/scheduler/ReadyBatch.h | 30 ---------- .../simulator/src/controller/scheduler/SMS.h | 10 +++- 5 files changed, 9 insertions(+), 147 deletions(-) delete mode 100644 DRAMSys/simulator/src/controller/scheduler/MPKC.h delete mode 100644 DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp delete mode 100644 DRAMSys/simulator/src/controller/scheduler/ReadyBatch.h diff --git a/DRAMSys/simulator/library.pro b/DRAMSys/simulator/library.pro index 3770561e..4cac1673 100644 --- a/DRAMSys/simulator/library.pro +++ b/DRAMSys/simulator/library.pro @@ -82,7 +82,6 @@ SOURCES += \ src/controller/scheduler/Fr_Fcfs.cpp \ src/controller/scheduler/Fifo.cpp \ src/controller/scheduler/SMS.cpp \ - src/controller/scheduler/ReadyBatch.cpp \ src/controller/core/refresh/RefreshManagerBankwise.cpp \ src/controller/core/refresh/RefreshManager.cpp \ src/controller/core/scheduling/checker/WriteChecker.cpp \ @@ -133,7 +132,6 @@ HEADERS += \ src/controller/scheduler/Fr_Fcfs.h \ src/controller/scheduler/Fifo.h \ src/controller/scheduler/SMS.h \ - src/controller/scheduler/ReadyBatch.h \ src/controller/Controller.h \ src/controller/core/refresh/RefreshManagerBankwise.h \ src/controller/core/refresh/RefreshManager.h \ diff --git a/DRAMSys/simulator/src/controller/scheduler/MPKC.h b/DRAMSys/simulator/src/controller/scheduler/MPKC.h deleted file mode 100644 index 8b7add90..00000000 --- a/DRAMSys/simulator/src/controller/scheduler/MPKC.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * MPKC.h - * - * Created on: May 11, 2017 - * Author: thanhtran - */ - -#ifndef MPKC_H_ -#define MPKC_H_ - -#include "../../../common/Utils.h" - -using namespace std; - -class MPKC: public sc_module -{ - public: - MPKC(sc_module_name /*_name*/, sc_time memClk) : memClk(memClk) - { - lastGeneratedRequests = std::make_pair(0, 0); - SC_THREAD(updateMPKC); - } - SC_HAS_PROCESS(MPKC); - - void updateMPKC() - { - - while(true) - { - mpkc = 1 / (lastGeneratedRequests.second + numClk*memClk -lastGeneratedRequests.first); - wait(memClk); - numClk++; - } - } - - float getMPKC() - { - return mpkc; - } - - void sendNewRequest(sc_time timeOfGeneration) - { - std::swap(lastGeneratedRequests.first, lastGeneratedRequests.second); - lastGeneratedRequests.second = timeOfGeneration; - numClk = 0; - } - - private: - unsigned int numClk = 0; - sc_time memClk; - float mpkc = 0; - std::pair lastGeneratedRequests; -}; - -#endif /* MPKC_H_ */ diff --git a/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp deleted file mode 100644 index 55118d15..00000000 --- a/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp +++ /dev/null @@ -1,59 +0,0 @@ -#include "ReadyBatch.h" - -ReadyBatch::ReadyBatch() -{ - fifosize = Configuration::getInstance().ReadyBatchSize; - thresholdAge = sc_time(Configuration::getInstance().ReadyBatchThresholdAge, SC_NS); -} - -ReadyBatch::~ReadyBatch() -{ - -} - -//unsigned int ReadyBatch::getNumRequests() -//{ -// return readybatch.size(); -//} - -Row ReadyBatch::getRow() -{ - return DramExtension::getExtension(readybatch.front()).getRow(); -} - -//sc_time ReadyBatch::getTimeOfOldestRequest() -//{ -// sc_time oldestTime = sc_time_stamp(); -// for (auto reqPayload = readybatch.begin(); reqPayload != readybatch.end(); reqPayload++) -// { -// sc_time requestTimeOfGeneration = GenerationExtension::getExtension(*reqPayload).TimeOfGeneration(); -// if (requestTimeOfGeneration < oldestTime) -// { -// oldestTime = requestTimeOfGeneration; -// } -// } -// return oldestTime; -//} - -bool ReadyBatch::addTransaction(gp* payload) -{ -// sc_time currentAge = sc_time_stamp() - getTimeOfOldestRequest(); - Row newRow = DramExtension::getExtension(payload).getRow(); - Row oldRow = readybatch.empty()? newRow : getRow(); - if (/*getNumRequests() == fifosize || currentAge >= thresholdAge || */newRow != oldRow) { - return false; - } else { - readybatch.emplace_back(payload); - return true; - } -} - -std::deque& ReadyBatch::getTransactions() -{ - return readybatch; -} - -bool ReadyBatch::isEmpty() -{ - return readybatch.empty(); -} diff --git a/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.h b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.h deleted file mode 100644 index 1b0f304c..00000000 --- a/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef READYBATCH_H -#define READYBATCH_H - -#include "tlm.h" -#include "../../common/dramExtension.h" -#include "../core/configuration/Configuration.h" - -typedef tlm::tlm_generic_payload gp; - -using namespace std; - -class ReadyBatch -{ -public: - ReadyBatch(); - bool addTransaction(gp* payload); -// unsigned int getNumRequests(); - std::deque& getTransactions(); - bool isEmpty(); - ~ReadyBatch(); -private: - std::deque readybatch; - unsigned int fifosize; - sc_time thresholdAge; - - Row getRow(); -// sc_time getTimeOfOldestRequest(); -}; - -#endif // READYBATCH_H diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h index df9c132f..73675a41 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.h +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h @@ -5,7 +5,6 @@ #include #include "sysc/utils/sc_report.h" #include "IScheduler.h" -#include "ReadyBatch.h" #include "../core/ControllerCore.h" #include "../core/configuration/Configuration.h" #include "../../common/dramExtension.h" @@ -22,6 +21,15 @@ using namespace std; typedef std::deque::iterator gp_deque_iterator; +/** + * SMS - Staged Memory Scheduler involves 3 steps: + * 1. Arrage request in to each buffer of each thread + * 2. Forming ready batches for each thread, i.e all requests access the same row. The batch is deemed + * ready when the next request accesses different row OR When the buffer is full OR When this batch + * is too old + * 3. Send batches to bank buffers. The rules to send batches are Shortest-Job-First OR Round-Robin + * How we select the rule depends on the probability we setup earlier. + */ class SMS: public sc_module, public IScheduler { public: From f09d47e1438c9595dd98f80b5ddb78de41f34d9d Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Wed, 21 Jun 2017 15:41:11 +0200 Subject: [PATCH 37/39] Remove unused parameters and add Request Buffer's Size parameter in SMS xml config file --- DRAMSys/simulator/resources/configs/mcconfigs/sms.xml | 6 ++---- .../src/controller/core/configuration/Configuration.cpp | 6 ++---- .../src/controller/core/configuration/Configuration.h | 3 +-- DRAMSys/simulator/src/controller/scheduler/SMS.cpp | 2 +- DRAMSys/simulator/src/controller/scheduler/SMS.h | 1 - 5 files changed, 6 insertions(+), 12 deletions(-) diff --git a/DRAMSys/simulator/resources/configs/mcconfigs/sms.xml b/DRAMSys/simulator/resources/configs/mcconfigs/sms.xml index 84551d57..088a9f66 100644 --- a/DRAMSys/simulator/resources/configs/mcconfigs/sms.xml +++ b/DRAMSys/simulator/resources/configs/mcconfigs/sms.xml @@ -3,10 +3,8 @@ - - - - + + diff --git a/DRAMSys/simulator/src/controller/core/configuration/Configuration.cpp b/DRAMSys/simulator/src/controller/core/configuration/Configuration.cpp index e410f639..f0fd7f68 100644 --- a/DRAMSys/simulator/src/controller/core/configuration/Configuration.cpp +++ b/DRAMSys/simulator/src/controller/core/configuration/Configuration.cpp @@ -146,10 +146,8 @@ void Configuration::setParameter(std::string name, std::string value) } else { SJFProbability = string2int(value); } - else if (name == "ReadyBatchSize") - ReadyBatchSize = string2int(value); - else if (name == "ReadyBatchThresholdAge") - ReadyBatchThresholdAge = string2int(value); + else if (name == "RequestBufferSize") + RequestBufferSize = string2int(value); else if(name == "Capsize") Capsize = string2int(value); else if(name == "PowerDownTimeout") diff --git a/DRAMSys/simulator/src/controller/core/configuration/Configuration.h b/DRAMSys/simulator/src/controller/core/configuration/Configuration.h index c52f4655..2f158053 100644 --- a/DRAMSys/simulator/src/controller/core/configuration/Configuration.h +++ b/DRAMSys/simulator/src/controller/core/configuration/Configuration.h @@ -63,8 +63,7 @@ struct Configuration unsigned int MaxNrOfTransactions = 8; std::string Scheduler; unsigned int SJFProbability; - unsigned int ReadyBatchSize; - unsigned int ReadyBatchThresholdAge; + unsigned int RequestBufferSize; unsigned int Capsize = 5; sc_time getPowerDownTimeout(){return powerDownTimeoutInClk*memSpec.clk;} EPowerDownMode PowerDownMode = EPowerDownMode::Staggered; diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index d4336415..7b89d885 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -248,7 +248,7 @@ void SMS::updateMPKCs(sc_time memClk) { } bool SMS::isExceededReqBufferSize(Thread thread) { - return requestBuffers[thread].size() == REQUEST_BUFFER_SIZE; + return requestBuffers[thread].size() == Configuration::getInstance().RequestBufferSize; } bool SMS::isRequestBuffersEmpty() { diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h index 73675a41..3d4282aa 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.h +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h @@ -16,7 +16,6 @@ #define MEDIUM_THRESHOLD_AGE 50 #define HIGH_THRESHOLD_AGE 200 #define MPKC_RESET_CYCLE 10000 -#define REQUEST_BUFFER_SIZE 10 using namespace std; typedef std::deque::iterator gp_deque_iterator; From 64b105d5c7776d6f203d442a0a9a018f5bfddea0 Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Wed, 21 Jun 2017 16:42:47 +0200 Subject: [PATCH 38/39] Fix Disable Refresh Issue --- .../simulator/src/controller/Controller.cpp | 32 +++++++++++++++++++ DRAMSys/simulator/src/controller/Controller.h | 2 ++ .../src/controller/scheduler/Fifo.cpp | 5 +++ .../simulator/src/controller/scheduler/Fifo.h | 1 + .../src/controller/scheduler/FifoStrict.cpp | 4 +++ .../src/controller/scheduler/FifoStrict.h | 1 + .../src/controller/scheduler/Fr_Fcfs.cpp | 5 +++ .../src/controller/scheduler/Fr_Fcfs.h | 1 + .../src/controller/scheduler/IScheduler.h | 1 + .../src/controller/scheduler/SMS.cpp | 12 +++++++ .../simulator/src/controller/scheduler/SMS.h | 1 + 11 files changed, 65 insertions(+) diff --git a/DRAMSys/simulator/src/controller/Controller.cpp b/DRAMSys/simulator/src/controller/Controller.cpp index 8e307173..bf68d7d4 100644 --- a/DRAMSys/simulator/src/controller/Controller.cpp +++ b/DRAMSys/simulator/src/controller/Controller.cpp @@ -300,6 +300,11 @@ void Controller::frontendPEQCallback(tlm_generic_payload &payload, const tlm_pha scheduler->schedule(&payload); scheduleNextFromScheduler(DramExtension::getExtension(payload).getBank()); } + else if (phase == PendingRequest) + { + // Schedule a pending request. + scheduleNextFromScheduler(DramExtension::getExtension(payload).getBank()); + } else if (phase == END_RESP) { if (backpressure != NULL) @@ -365,6 +370,7 @@ void Controller::scheduleNextFromScheduler(Bank bank) return; } + bool rescheduled = true; pair nextRequest = scheduler->getNextRequest(bank); if(nextRequest.second != NULL) { @@ -372,7 +378,17 @@ void Controller::scheduleNextFromScheduler(Bank bank) controllerCore->scheduleRequest(nextRequest.first, *nextRequest.second); printDebugMessage("\t-> Next payload was scheduled by core [" + commandToString(nextRequest.first) + "]"); } + else + { + gp* pendingRequest = scheduler->getPendingRequest(bank); + if (pendingRequest != NULL) + { + rescheduled = true; + frontendPEQ.notify(*(pendingRequest), PendingRequest, Configuration::getInstance().memSpec.clk); + } + } + queue blocked; while (!blockedRequests.empty()) { bank = blockedRequests.front(); blockedRequests.pop(); @@ -383,7 +399,23 @@ void Controller::scheduleNextFromScheduler(Bank bank) controllerCore->scheduleRequest(nextRequest.first, *nextRequest.second); printDebugMessage("\t-> Next payload was scheduled by core [" + commandToString(nextRequest.first) + "] (unblocked)"); } + else + { + gp* pendingRequest = scheduler->getPendingRequest(bank); + if(pendingRequest != NULL) + { + //Pending request + if(!rescheduled) + { + rescheduled = true; + frontendPEQ.notify(*(pendingRequest), PendingRequest, Configuration::getInstance().memSpec.clk); + } + else + blocked.push(bank); + } + } } + blockedRequests = blocked; } void Controller::sendToFrontend(tlm_generic_payload &payload, const tlm_phase &phase, const sc_time &delay) diff --git a/DRAMSys/simulator/src/controller/Controller.h b/DRAMSys/simulator/src/controller/Controller.h index 682a29b0..b5f67ff7 100644 --- a/DRAMSys/simulator/src/controller/Controller.h +++ b/DRAMSys/simulator/src/controller/Controller.h @@ -73,6 +73,8 @@ using namespace std; using namespace tlm; +DECLARE_EXTENDED_PHASE(PendingRequest); + struct Controller: public sc_module, public IController { public: diff --git a/DRAMSys/simulator/src/controller/scheduler/Fifo.cpp b/DRAMSys/simulator/src/controller/scheduler/Fifo.cpp index beb57612..7d7a90e1 100644 --- a/DRAMSys/simulator/src/controller/scheduler/Fifo.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/Fifo.cpp @@ -60,4 +60,9 @@ pair Fifo::getNextRequest(Bank bank) return pair(Command::NOP, NULL); } +gp* Fifo::getPendingRequest(Bank bank) +{ + return NULL; +} + diff --git a/DRAMSys/simulator/src/controller/scheduler/Fifo.h b/DRAMSys/simulator/src/controller/scheduler/Fifo.h index 0576bb32..1b060b12 100644 --- a/DRAMSys/simulator/src/controller/scheduler/Fifo.h +++ b/DRAMSys/simulator/src/controller/scheduler/Fifo.h @@ -52,6 +52,7 @@ public: void schedule(gp* payload) override; std::pair getNextRequest(Bank bank) override; + virtual gp* getPendingRequest(Bank bank) override; private: std::map> buffer; diff --git a/DRAMSys/simulator/src/controller/scheduler/FifoStrict.cpp b/DRAMSys/simulator/src/controller/scheduler/FifoStrict.cpp index f9881fee..6e8bd292 100644 --- a/DRAMSys/simulator/src/controller/scheduler/FifoStrict.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/FifoStrict.cpp @@ -128,3 +128,7 @@ std::pair FifoStrict::getNextRequest(Bank b return pair(Command::NOP, NULL); } +gp* FifoStrict::getPendingRequest(Bank bank) +{ + return NULL; +} diff --git a/DRAMSys/simulator/src/controller/scheduler/FifoStrict.h b/DRAMSys/simulator/src/controller/scheduler/FifoStrict.h index 1cc9ece0..855f7ff3 100644 --- a/DRAMSys/simulator/src/controller/scheduler/FifoStrict.h +++ b/DRAMSys/simulator/src/controller/scheduler/FifoStrict.h @@ -56,6 +56,7 @@ public: void schedule(gp* payload) override; std::pair getNextRequest(Bank bank) override; + virtual gp* getPendingRequest(Bank bank) override; private: std::deque> buffer; diff --git a/DRAMSys/simulator/src/controller/scheduler/Fr_Fcfs.cpp b/DRAMSys/simulator/src/controller/scheduler/Fr_Fcfs.cpp index 30750c7f..5b022ca6 100644 --- a/DRAMSys/simulator/src/controller/scheduler/Fr_Fcfs.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/Fr_Fcfs.cpp @@ -121,3 +121,8 @@ deque::iterator FR_FCFS::FindRowHit(Bank bank) return queue.end(); } + +gp* FR_FCFS::getPendingRequest(Bank bank) +{ + return NULL; +} diff --git a/DRAMSys/simulator/src/controller/scheduler/Fr_Fcfs.h b/DRAMSys/simulator/src/controller/scheduler/Fr_Fcfs.h index 187b81ab..9347c21f 100644 --- a/DRAMSys/simulator/src/controller/scheduler/Fr_Fcfs.h +++ b/DRAMSys/simulator/src/controller/scheduler/Fr_Fcfs.h @@ -53,6 +53,7 @@ public: void schedule(gp* payload) override; std::pair getNextRequest(Bank bank) override; + virtual gp* getPendingRequest(Bank bank) override; private: std::map> buffer; diff --git a/DRAMSys/simulator/src/controller/scheduler/IScheduler.h b/DRAMSys/simulator/src/controller/scheduler/IScheduler.h index a951d015..efeebdc4 100644 --- a/DRAMSys/simulator/src/controller/scheduler/IScheduler.h +++ b/DRAMSys/simulator/src/controller/scheduler/IScheduler.h @@ -54,6 +54,7 @@ public: virtual void schedule(gp* payload) = 0; virtual std::pair getNextRequest(Bank bank) = 0; + virtual gp* getPendingRequest(Bank bank) = 0; static std::string sendername; protected: diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index 7b89d885..64882dc3 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -343,3 +343,15 @@ void SMS::multiBatchFormation(sc_time memClk) } while (formed); } } + +gp* SMS::getPendingRequest(Bank bank) +{ + for (auto& requestBuffer : requestBuffers) { + for (auto& request : requestBuffer.second) { + if (DramExtension::getBank(request) == bank) { + return request; + } + } + } + return NULL; +} diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h index 3d4282aa..2843b990 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.h +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h @@ -46,6 +46,7 @@ public: virtual void schedule(gp *payload) override; virtual std::pair getNextRequest(Bank bank) override; + virtual gp* getPendingRequest(Bank bank) override; void batchScheduler(); From a5e62f75abe55d66f6ee08a13f170a739c58d03f Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Thu, 22 Jun 2017 12:37:46 +0200 Subject: [PATCH 39/39] Revert back to use default simulation file --- DRAMSys/simulator/src/simulation/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DRAMSys/simulator/src/simulation/main.cpp b/DRAMSys/simulator/src/simulation/main.cpp index 72c31f8b..60246caf 100644 --- a/DRAMSys/simulator/src/simulation/main.cpp +++ b/DRAMSys/simulator/src/simulation/main.cpp @@ -72,7 +72,7 @@ int sc_main(int argc, char **argv) } else { - SimulationXML = resources + "simulations/sms-example.xml"; + SimulationXML = resources + "simulations/ddr3-example.xml"; } std::vector players;