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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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 904aef9361e7440f3fa5a42795867b45f8952864 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89der=20F=2E=20Zulian?= Date: Fri, 16 Jun 2017 10:53:16 +0200 Subject: [PATCH 37/43] Update path of gem5 files. --- DRAMSys/gem5/gem5.pro | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/DRAMSys/gem5/gem5.pro b/DRAMSys/gem5/gem5.pro index cb3dcc2d..fe171ebd 100644 --- a/DRAMSys/gem5/gem5.pro +++ b/DRAMSys/gem5/gem5.pro @@ -48,7 +48,7 @@ INCLUDEPATH += ../simulator/src/common/third_party/DRAMPower/src/libdrampower INCLUDEPATH += $${gem5_root}/build/$${gem5_arch}/ INCLUDEPATH += $${gem5_root}/util/tlm/examples/slave_port INCLUDEPATH += $${gem5_root}/util/tlm/examples/common -INCLUDEPATH += $${gem5_root}/util/tlm/ +INCLUDEPATH += $${gem5_root}/util/tlm/src/ INCLUDEPATH += $${gem5_root}/util/systemc LIBS += -L$${systemc_home}/lib-$${systemc_target_arch} -lsystemc @@ -63,13 +63,13 @@ SOURCES += $${gem5_root}/util/systemc/sc_module.cc SOURCES += $${gem5_root}/util/systemc/stats.cc SOURCES += $${gem5_root}/util/tlm/examples/common/cli_parser.cc SOURCES += $${gem5_root}/util/tlm/examples/common/report_handler.cc -SOURCES += $${gem5_root}/util/tlm/master_transactor.cc -SOURCES += $${gem5_root}/util/tlm/sc_master_port.cc -SOURCES += $${gem5_root}/util/tlm/sc_slave_port.cc -SOURCES += $${gem5_root}/util/tlm/slave_transactor.cc -SOURCES += $${gem5_root}/util/tlm/sc_ext.cc -SOURCES += $${gem5_root}/util/tlm/sc_mm.cc -SOURCES += $${gem5_root}/util/tlm/sim_control.cc +SOURCES += $${gem5_root}/util/tlm/src/master_transactor.cc +SOURCES += $${gem5_root}/util/tlm/src/sc_master_port.cc +SOURCES += $${gem5_root}/util/tlm/src/sc_slave_port.cc +SOURCES += $${gem5_root}/util/tlm/src/slave_transactor.cc +SOURCES += $${gem5_root}/util/tlm/src/sc_ext.cc +SOURCES += $${gem5_root}/util/tlm/src/sc_mm.cc +SOURCES += $${gem5_root}/util/tlm/src/sim_control.cc SOURCES += main.cpp From 6ebf9b5ac7803f146ac40261fa7f0756046acf12 Mon Sep 17 00:00:00 2001 From: Matthias Jung Date: Tue, 20 Jun 2017 00:34:42 +0200 Subject: [PATCH 38/43] added a script for generating the memory hog traces --- .../simulator/resources/scripts/memoryHog.pl | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 DRAMSys/simulator/resources/scripts/memoryHog.pl diff --git a/DRAMSys/simulator/resources/scripts/memoryHog.pl b/DRAMSys/simulator/resources/scripts/memoryHog.pl new file mode 100644 index 00000000..29e68597 --- /dev/null +++ b/DRAMSys/simulator/resources/scripts/memoryHog.pl @@ -0,0 +1,21 @@ +#!/usr/bin/perl -w +use warnings; +use strict; + +open(LINEAR, "> ../traces/linear.stl"); +open(RANDOM, "> ../traces/random.stl"); + +my $length = shift || die ("please give length of traces"); +my $size = 0x40; + +for(my $i=0; $i < $length; $i++) +{ + my $r = int(rand($length)); + #print $r." ".($size*$r)."\n"; + print LINEAR "$i: read ".sprintf("0x%x",($size*$i))."\n"; + print RANDOM "$i: read ".sprintf("0x%x",($size*$r))."\n"; +} + + +close(LINEAR); +close(RANDOM); From 9ed9ba480bf077b263a36f776d6dd2138193ebae Mon Sep 17 00:00:00 2001 From: Matthias Jung Date: Tue, 20 Jun 2017 17:07:25 +0200 Subject: [PATCH 39/43] Commented the FR_FCFS scheduler since the original implementation the comments are missed. I just added the comments such that anybody can understand it. --- .../src/controller/scheduler/Fr_Fcfs.cpp | 46 +++++++++++++++++-- 1 file changed, 41 insertions(+), 5 deletions(-) diff --git a/DRAMSys/simulator/src/controller/scheduler/Fr_Fcfs.cpp b/DRAMSys/simulator/src/controller/scheduler/Fr_Fcfs.cpp index a9053f94..30750c7f 100644 --- a/DRAMSys/simulator/src/controller/scheduler/Fr_Fcfs.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/Fr_Fcfs.cpp @@ -42,20 +42,43 @@ using namespace std; - +// The FR_FCFS is descibed in a 2000 paper from Rixner et al.: +// Memory Access Scheduling +// +// The FR_FCFS scheduler features for each bank in the DRAM a specific +// scheduling buffer for example: +// +// Bank0: OOOOOOOO +// Bank1: OOXXXXXX +// ... ^ ^ +// ... | | +// ... back | +// ... front +// ... +// Bank6: OOOOO0XX +// Bank7: XXXXXXXX void FR_FCFS::schedule(gp *payload) { - buffer[DramExtension::getExtension(payload).getBank()].emplace_back(payload); + + // FIXME: Question: what if the buffer is full? IMHO the schedule function + // should provide a true or false when the placement into the buffer worked + // out or not (?). + buffer[DramExtension::getExtension(payload).getBank()] + .emplace_back(payload); } std::pair FR_FCFS::getNextRequest(Bank bank) { + // If the bank is empty like Bank0 in the example we do nothing if(buffer[bank].empty()) { return pair(Command::NOP, NULL); } + // In FR_FCFS row hits have always the highest priority, therefore we search + // for row hits. If we find a row hit, we remove the transaction from the + // queue and send it to the DRAM. deque::iterator it = FindRowHit(bank); if(it != buffer[bank].end()) { @@ -64,9 +87,19 @@ std::pair FR_FCFS::getNextRequest(Bank bank) return pair(getReadWriteCommand(*payload), payload); } - return pair(getNextCommand(buffer[bank].front()), buffer[bank].front()); + // If there is no row hit, the FR_FCFS takes always the oldest transaction + // in the buffer, i.e. the transaction in the front. + return pair(getNextCommand(buffer[bank].front()), + buffer[bank].front()); } +// This function searches for a row hit in the scheduling queue of the specific +// bank. If no row hit is found the end of the queue is returned. +// +// Note: end() Returns an iterator referring to the past-the-end element in the +// deque container. The past-the-end element is the theoretical element that +// would follow the last element in the deque container. It does not point to +// any element, and thus shall not be dereferenced. deque::iterator FR_FCFS::FindRowHit(Bank bank) { deque &queue = buffer[bank]; @@ -74,14 +107,17 @@ deque::iterator FR_FCFS::FindRowHit(Bank bank) if(!controllerCore.getRowBufferStates().rowBufferIsOpen(bank)) return queue.end(); + // Traverse the scheduling queue of the specific bank: for(auto it = queue.begin(); it!=queue.end(); it++) { gp* payload = *it; - //Found row-hit - if(DramExtension::getRow(payload) == controllerCore.getRowBufferStates().getRowInRowBuffer(bank)) + //Found row-hit and return the according iterator + if(DramExtension::getRow(payload) + == controllerCore.getRowBufferStates().getRowInRowBuffer(bank)) { return it; } } + return queue.end(); } From f09d47e1438c9595dd98f80b5ddb78de41f34d9d Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Wed, 21 Jun 2017 15:41:11 +0200 Subject: [PATCH 40/43] 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 41/43] 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 de7381ae49152263bd80f990a2588b40593d6a9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89der=20F=2E=20Zulian?= Date: Thu, 22 Jun 2017 12:05:40 +0200 Subject: [PATCH 42/43] Fix some segfaults. In the current implementation the object deletion order is important. Messages regarding power and energy are printed inside the Dram destructor. The controller object was destructed and then called by the Dram object. The behavior varies with compiler (clang or gcc). It seems that clang deletes objects later than gcc masking some bugs. --- DRAMSys/simulator/src/simulation/DRAMSys.cpp | 10 +++++----- DRAMSys/simulator/src/simulation/main.cpp | 9 ++++++--- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/DRAMSys/simulator/src/simulation/DRAMSys.cpp b/DRAMSys/simulator/src/simulation/DRAMSys.cpp index 41b80d42..515c292c 100644 --- a/DRAMSys/simulator/src/simulation/DRAMSys.cpp +++ b/DRAMSys/simulator/src/simulation/DRAMSys.cpp @@ -245,11 +245,6 @@ DRAMSys::~DRAMSys() delete arbiter; - for (auto controller : controllers) - { - delete controller; - } - for (auto dram : drams) { delete dram; @@ -264,6 +259,11 @@ DRAMSys::~DRAMSys() { delete tlmChecker; } + + for (auto controller : controllers) + { + delete controller; + } } void DRAMSys::report(string message) diff --git a/DRAMSys/simulator/src/simulation/main.cpp b/DRAMSys/simulator/src/simulation/main.cpp index 18e00f77..60246caf 100644 --- a/DRAMSys/simulator/src/simulation/main.cpp +++ b/DRAMSys/simulator/src/simulation/main.cpp @@ -78,15 +78,15 @@ int sc_main(int argc, char **argv) std::vector players; // Instantiate DRAMSys: - DRAMSys dramSys("DRAMSys", SimulationXML, resources); + DRAMSys *dramSys = new DRAMSys("DRAMSys", SimulationXML, resources); // Instantiate STL Players: - traceSetup(SimulationXML, resources, &players); + traceSetup *ts = new traceSetup(SimulationXML, resources, &players); // Bind STL Players with DRAMSys: for(auto& p : players) { - p->iSocket.bind(dramSys.tSocket); + p->iSocket.bind(dramSys->tSocket); } // Store the starting of the simulation in wallclock time: @@ -105,5 +105,8 @@ int sc_main(int argc, char **argv) double elapsed_secs = double(clock() - simStartTime) / CLOCKS_PER_SEC; cout << "Simulation took " + to_string(elapsed_secs) + " seconds" << endl; + delete dramSys; + delete ts; + return 0; } From a5e62f75abe55d66f6ee08a13f170a739c58d03f Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Thu, 22 Jun 2017 12:37:46 +0200 Subject: [PATCH 43/43] 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;