From 3521cafa814ca0da85e61fe4fe5dc34998227c7d Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Wed, 22 Mar 2017 12:44:33 +0100 Subject: [PATCH] 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