From 7f9569f25d474987696cff1ad689efcaf79ee7be Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Sun, 16 Jul 2017 04:19:51 +0200 Subject: [PATCH 1/3] Optimize with passing const references --- .../resources/configs/mcconfigs/sms.xml | 4 +- .../resources/simulations/sms-example.xml | 11 +- .../src/controller/scheduler/SMS.cpp | 159 ++++++++---------- .../simulator/src/controller/scheduler/SMS.h | 20 +-- 4 files changed, 92 insertions(+), 102 deletions(-) diff --git a/DRAMSys/simulator/resources/configs/mcconfigs/sms.xml b/DRAMSys/simulator/resources/configs/mcconfigs/sms.xml index 088a9f66..f2ac6c19 100644 --- a/DRAMSys/simulator/resources/configs/mcconfigs/sms.xml +++ b/DRAMSys/simulator/resources/configs/mcconfigs/sms.xml @@ -1,7 +1,7 @@ - + @@ -13,4 +13,4 @@ - \ No newline at end of file + diff --git a/DRAMSys/simulator/resources/simulations/sms-example.xml b/DRAMSys/simulator/resources/simulations/sms-example.xml index d40e0e8c..3b412664 100644 --- a/DRAMSys/simulator/resources/simulations/sms-example.xml +++ b/DRAMSys/simulator/resources/simulations/sms-example.xml @@ -12,14 +12,15 @@ - ddr3_example.stl + + + random.stl + chstone-adpcm_32.stl + stream.stl diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index 64882dc3..8eedea6a 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -61,15 +61,13 @@ void SMS::batchScheduler() multiBatchFormation(memClk); if (existReadyBatches()) { if (!isSystemLightlyLoaded() && (existLowIntensityThread() || distribution(generator))) { - if (pickSJF()) { - drain(memClk, (*lastSelectedThread).second.front()); - (*lastSelectedThread).second.pop_front(); - } + pickSJF(); + drain(memClk); + (*lastSelectedThread).second.pop_front(); } else { - if (pickRR()) { - drain(memClk, (*lastSelectedThread).second.front()); - (*lastSelectedThread).second.pop_front(); - } + pickRR(); + drain(memClk); + (*lastSelectedThread).second.pop_front(); } } else { wait(memClk); @@ -87,7 +85,7 @@ bool SMS::pickSJF() { // find threads with ready batches std::vector threadsWithReadyBatches; - for (auto& each : readyBatchIters) + for (const auto &each : readyBatchIters) { if (!each.second.empty()) { @@ -99,8 +97,8 @@ bool SMS::pickSJF() if (!threadsWithReadyBatches.empty()) { // pick shortest-job thread among threads with non-empty request buffer - Thread minThread = threadsWithReadyBatches.front(); - for (auto& thread : threadsWithReadyBatches) + Thread &minThread = threadsWithReadyBatches.front(); + for (const auto &thread : threadsWithReadyBatches) { if (inFlightMemRequestCounter[thread] < inFlightMemRequestCounter[minThread]) { @@ -126,17 +124,19 @@ bool SMS::pickSJF() * @param memClk * @param last */ -void SMS::drain(sc_time memClk, std::deque::iterator last) +void SMS::drain(const sc_time &memClk) { - Thread selectedThread = (*lastSelectedThread).first; + if (lastSelectedThread->second.empty()) { + return; + } + const Thread &selectedThread = lastSelectedThread->first; + const std::deque::iterator &last = lastSelectedThread->second.front(); + assert(last != requestBuffers[selectedThread].end()); unsigned int batchSize = std::distance(requestBuffers[selectedThread].begin(), last) + 1; + assert(batchSize > 0 && batchSize <= requestBuffers[selectedThread].size()); for (unsigned int i = 1; i <= batchSize; i++) { Bank bank = DramExtension::getExtension(requestBuffers[selectedThread].front()).getBank(); - // if(bankBuffers[bank].size() == Configuration::getInstance().BankBufferSize) - // { - // wait(bankBufferIsNotFull); - // } wait(memClk); bankBuffers[bank].emplace_back(requestBuffers[selectedThread].front()); requestBuffers[selectedThread].pop_front(); @@ -155,54 +155,42 @@ void SMS::drain(sc_time memClk, std::deque::iterator last) */ bool SMS::pickRR() { - std::map>::iterator nextSelectedThread; - if (lastSelectedThread == readyBatchIters.end()) - { - lastSelectedThread = readyBatchIters.begin(); - nextSelectedThread = lastSelectedThread; - } - else - { - nextSelectedThread = lastSelectedThread; - nextSelectedThread++; - if (nextSelectedThread == readyBatchIters.end()) - nextSelectedThread = readyBatchIters.begin(); - } - - std::map>::iterator savedOriginalNextSelectedThread = nextSelectedThread; - - while ((*nextSelectedThread).second.empty()) - { - nextSelectedThread++; - if (nextSelectedThread == readyBatchIters.end()) + if (lastSelectedThread == readyBatchIters.end()) { - nextSelectedThread = readyBatchIters.begin(); + lastSelectedThread = readyBatchIters.begin(); + if (!(*lastSelectedThread).second.empty()) { + return true; + } } - if (nextSelectedThread == savedOriginalNextSelectedThread) + std::map>::iterator savedOriginalNextSelectedThread = lastSelectedThread; + + do { - // 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; + lastSelectedThread++; + if (lastSelectedThread == readyBatchIters.end()) { + lastSelectedThread = readyBatchIters.begin(); + } + if (lastSelectedThread == savedOriginalNextSelectedThread) { + return false; + } + } while ((*lastSelectedThread).second.empty()); + + debugManager.printDebugMessage(name(), + "[RR] Select ready batch of thread " + to_string((*lastSelectedThread).first.ID())); + return true; } -bool SMS::isSystemLightlyLoaded() { +bool SMS::isSystemLightlyLoaded() const { unsigned int totalRequest = 0; - for (auto& bankBuffer : bankBuffers) { + for (const auto &bankBuffer : bankBuffers) { totalRequest += bankBuffer.second.size(); } return (totalRequest <= LOW_SYSTEM_LOAD); } -bool SMS::existLowIntensityThread() { - for (auto& mpkcPerThread : MPKCs) { +bool SMS::existLowIntensityThread() const { + for (const auto &mpkcPerThread : MPKCs) { if (mpkcPerThread.second < LOW_MPKC) { return true; } @@ -210,7 +198,7 @@ bool SMS::existLowIntensityThread() { return false; } -bool SMS::isThresholdAgeExceeded(Thread thread, sc_time memClk, std::deque::iterator begin, std::deque::iterator end) { +bool SMS::isThresholdAgeExceeded(const Thread &thread, sc_time const &memClk, std::deque::iterator const &begin, std::deque::iterator const &end) { // find the oldest request in the thread's batch sc_time oldestGenerationTime = sc_time_stamp(); for (auto reqIter = begin; reqIter != end; reqIter++) { @@ -231,28 +219,28 @@ bool SMS::isThresholdAgeExceeded(Thread thread, sc_time memClk, std::deque: } } -void SMS::updateMPKCs(sc_time memClk) { +void SMS::updateMPKCs(sc_time const &memClk) { if (sc_time_stamp() % (MPKC_RESET_CYCLE * memClk) <= memClk) { // reset for every 10k clk cycles - for (auto& cacheMiss : cacheMisses) { + for (const auto &cacheMiss : cacheMisses) { MPKCs[cacheMiss.first] = 0; } debugManager.printDebugMessage(name(), "Reset MKKCs"); } else { // update MPKC for every thread - for (auto& cacheMiss : cacheMisses) { + for (const auto &cacheMiss : cacheMisses) { MPKCs[cacheMiss.first] = (cacheMiss.second * 1000.0 * memClk) / (sc_time_stamp()); } debugManager.printDebugMessage(name(), "Update MPKCs"); } } -bool SMS::isExceededReqBufferSize(Thread thread) { +bool SMS::isExceededReqBufferSize(Thread const &thread) { return requestBuffers[thread].size() == Configuration::getInstance().RequestBufferSize; } -bool SMS::isRequestBuffersEmpty() { - for (auto& requestBuffer : requestBuffers) { +bool SMS::isRequestBuffersEmpty() const { + for (const auto &requestBuffer : requestBuffers) { if (!requestBuffer.second.empty()) { return false; } @@ -260,8 +248,8 @@ bool SMS::isRequestBuffersEmpty() { return true; } -bool SMS::existReadyBatches() { - for (auto& each : readyBatchIters) { +bool SMS::existReadyBatches() const { + for (const auto &each : readyBatchIters) { if (!each.second.empty()) { return true; } @@ -276,46 +264,47 @@ bool SMS::existReadyBatches() { * @param begin * @return true if this batch is ready, otherwise false */ -bool SMS::batchFormation(sc_time memClk, std::pair> &requestBuffer, - std::deque::iterator beginIter) +bool SMS::batchFormation(sc_time const &memClk, Thread const &thread, std::deque const &requestBuffer, std::deque::iterator const &beginIter) { - if (requestBuffer.second.empty()) + if (requestBuffer.empty()) { return false; } - if (requestBuffer.second.end() == beginIter) + if (requestBuffer.end() == beginIter) { return false; } - if (MPKCs[requestBuffer.first] < LOW_MPKC || isSystemLightlyLoaded()) + if (MPKCs[thread] < LOW_MPKC || isSystemLightlyLoaded()) { // bypass requests by forming batch with only one request (threshold age is ZERO) - readyBatchIters[requestBuffer.first].push_back(beginIter); + readyBatchIters[thread].push_back(beginIter); return true; } else { // forming batch with FIFO size & threshold age constraints - auto firstDifferentRowAccessReqIter = beginIter; + std::deque::iterator firstDifferentRowAccessReqIter = beginIter; Row firstRow = DramExtension::getRow(*beginIter); - while (firstDifferentRowAccessReqIter != requestBuffer.second.end() + while (firstDifferentRowAccessReqIter != requestBuffer.end() && DramExtension::getRow(*firstDifferentRowAccessReqIter) == firstRow) { - firstDifferentRowAccessReqIter++; + ++firstDifferentRowAccessReqIter; + if (firstDifferentRowAccessReqIter == requestBuffer.end ()) { + break; + } } // deem this batch ready - if ((firstDifferentRowAccessReqIter != requestBuffer.second.end()) - || isExceededReqBufferSize(requestBuffer.first) - || isThresholdAgeExceeded(requestBuffer.first, memClk, beginIter, - firstDifferentRowAccessReqIter)) + if ((firstDifferentRowAccessReqIter != requestBuffer.end()) + || isExceededReqBufferSize(thread) + || isThresholdAgeExceeded(thread, memClk, beginIter, firstDifferentRowAccessReqIter)) { - firstDifferentRowAccessReqIter--; - readyBatchIters[requestBuffer.first].push_back(firstDifferentRowAccessReqIter); + --firstDifferentRowAccessReqIter; + readyBatchIters[thread].push_back(firstDifferentRowAccessReqIter); debugManager.printDebugMessage(name(), - "Deem batch ready - thread " + to_string(requestBuffer.first.ID())); + "Deem batch ready - thread " + to_string(thread.ID())); return true; } else @@ -325,29 +314,29 @@ bool SMS::batchFormation(sc_time memClk, std::pair> &req } } -void SMS::multiBatchFormation(sc_time memClk) +void SMS::multiBatchFormation(sc_time const &memClk) { - for (auto& requestBuffer : requestBuffers) + for (auto &requestBuffer : requestBuffers) { bool formed; do { if (readyBatchIters[requestBuffer.first].empty()) { - formed = batchFormation(memClk, (std::pair>&)requestBuffer, requestBuffer.second.begin()); + formed = batchFormation(memClk, requestBuffer.first, requestBuffer.second, requestBuffer.second.begin()); } else { - formed = batchFormation(memClk, (std::pair>&)requestBuffer, readyBatchIters[requestBuffer.first].back() + 1); + formed = batchFormation(memClk, requestBuffer.first, requestBuffer.second, readyBatchIters[requestBuffer.first].back() + 1); } - } while (formed); + } while (!requestBuffer.second.empty() && formed); } } gp* SMS::getPendingRequest(Bank bank) { - for (auto& requestBuffer : requestBuffers) { - for (auto& request : requestBuffer.second) { + for (const auto &requestBuffer : requestBuffers) { + for (const auto &request : requestBuffer.second) { if (DramExtension::getBank(request) == bank) { return request; } diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h index 2843b990..bdb5c783 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.h +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h @@ -65,20 +65,20 @@ private: DebugManager& debugManager; - bool batchFormation(sc_time memClk, std::pair> &requestBuffer, std::deque::iterator beginIter); - void multiBatchFormation(sc_time memClk); + bool batchFormation(sc_time const &memClk, Thread const &thread, const std::deque &requestBuffer, const std::deque::iterator &beginIter); + void multiBatchFormation(const sc_time &memClk); bool pickSJF(); bool pickRR(); - void drain(sc_time memClk, std::deque::iterator last); + void drain(const 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 existLowIntensityThread() const; + bool isSystemLightlyLoaded() const; + bool isThresholdAgeExceeded(const Thread &thread, const sc_time &memClk, const std::deque::iterator &begin, const std::deque::iterator &end); + bool isExceededReqBufferSize(Thread const &thread); + void updateMPKCs(const sc_time &memClk); - bool isRequestBuffersEmpty(); - bool existReadyBatches(); + bool isRequestBuffersEmpty() const; + bool existReadyBatches() const; }; #endif // SMS_H From 6c5fb579d460e9e7d281e86222855f2ee08d1487 Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Wed, 19 Jul 2017 18:39:00 +0200 Subject: [PATCH 2/3] Change to use batch size to store each batch location due iterator invalidation of deque container when push and pop --- .../simulator/src/common/dramExtension.cpp | 10 ++ DRAMSys/simulator/src/common/dramExtension.h | 2 + .../src/controller/scheduler/SMS.cpp | 113 +++++++++++------- .../simulator/src/controller/scheduler/SMS.h | 14 +-- 4 files changed, 87 insertions(+), 52 deletions(-) diff --git a/DRAMSys/simulator/src/common/dramExtension.cpp b/DRAMSys/simulator/src/common/dramExtension.cpp index 3887f8df..a0a44015 100644 --- a/DRAMSys/simulator/src/common/dramExtension.cpp +++ b/DRAMSys/simulator/src/common/dramExtension.cpp @@ -169,6 +169,16 @@ GenerationExtension& GenerationExtension::getExtension(const tlm::tlm_generic_pa return *result; } +sc_time GenerationExtension::getTimeOfGeneration(const tlm::tlm_generic_payload *payload) +{ + return GenerationExtension::getExtension(payload).TimeOfGeneration(); +} + +sc_time GenerationExtension::getTimeOfGeneration(const tlm::tlm_generic_payload &payload) +{ + return GenerationExtension::getTimeOfGeneration(&payload); +} + //THREAD bool operator ==(const Thread& lhs, const Thread& rhs) { diff --git a/DRAMSys/simulator/src/common/dramExtension.h b/DRAMSys/simulator/src/common/dramExtension.h index 24865e80..ab30decf 100644 --- a/DRAMSys/simulator/src/common/dramExtension.h +++ b/DRAMSys/simulator/src/common/dramExtension.h @@ -212,6 +212,8 @@ public: virtual void copy_from(const tlm_extension_base& ext); static GenerationExtension& getExtension(const tlm::tlm_generic_payload *payload); sc_time TimeOfGeneration() const {return timeOfGeneration;} + static sc_time getTimeOfGeneration(const tlm::tlm_generic_payload *payload); + static sc_time getTimeOfGeneration(const tlm::tlm_generic_payload &payload); private: sc_time timeOfGeneration; diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index 8eedea6a..5d103522 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -62,13 +62,10 @@ void SMS::batchScheduler() if (existReadyBatches()) { if (!isSystemLightlyLoaded() && (existLowIntensityThread() || distribution(generator))) { pickSJF(); - drain(memClk); - (*lastSelectedThread).second.pop_front(); } else { pickRR(); - drain(memClk); - (*lastSelectedThread).second.pop_front(); } + drainOnePayloadFromReadybatch(memClk); } else { wait(memClk); } @@ -85,7 +82,7 @@ bool SMS::pickSJF() { // find threads with ready batches std::vector threadsWithReadyBatches; - for (const auto &each : readyBatchIters) + for (const auto &each : readyBatchInclusiveEndLocs) { if (!each.second.empty()) { @@ -107,7 +104,7 @@ bool SMS::pickSJF() } // save selected thread - lastSelectedThread = readyBatchIters.find(minThread); + lastSelectedThread = readyBatchInclusiveEndLocs.find(minThread); debugManager.printDebugMessage(name(), "[SJF] Select ready batch of thread " + to_string(minThread.ID())); return true; @@ -124,28 +121,36 @@ bool SMS::pickSJF() * @param memClk * @param last */ -void SMS::drain(const sc_time &memClk) +void SMS::drainOnePayloadFromReadybatch(const sc_time &memClk) { if (lastSelectedThread->second.empty()) { return; } const Thread &selectedThread = lastSelectedThread->first; - const std::deque::iterator &last = lastSelectedThread->second.front(); - assert(last != requestBuffers[selectedThread].end()); - unsigned int batchSize = std::distance(requestBuffers[selectedThread].begin(), last) + 1; - assert(batchSize > 0 && batchSize <= requestBuffers[selectedThread].size()); - for (unsigned int i = 1; i <= batchSize; i++) + + const size_t &inclusiveEndLoc = lastSelectedThread->second.front(); + assert(inclusiveEndLoc < requestBuffers.size()); + + for (size_t i = 0; i <= inclusiveEndLoc; ++i) { - Bank bank = DramExtension::getExtension(requestBuffers[selectedThread].front()).getBank(); wait(memClk); + Bank bank = DramExtension::getExtension(requestBuffers[selectedThread].front()).getBank(); bankBuffers[bank].emplace_back(requestBuffers[selectedThread].front()); requestBuffers[selectedThread].pop_front(); + // decrement inclusive end locations of ready batches + // except this ready batch + for (size_t i = 1; i < readyBatchInclusiveEndLocs.size(); ++i) + { + --readyBatchInclusiveEndLocs[selectedThread][i]; + } + debugManager.printDebugMessage(name(), "[SJF] Drain request in the ready batch of thread " + to_string((*lastSelectedThread).first.ID()) + " to bankbuffer " + to_string(bank.ID())); } + lastSelectedThread->second.pop_front(); } /** @@ -155,21 +160,21 @@ void SMS::drain(const sc_time &memClk) */ bool SMS::pickRR() { - if (lastSelectedThread == readyBatchIters.end()) + if (lastSelectedThread == readyBatchInclusiveEndLocs.end()) { - lastSelectedThread = readyBatchIters.begin(); + lastSelectedThread = readyBatchInclusiveEndLocs.begin(); if (!(*lastSelectedThread).second.empty()) { return true; } } - std::map>::iterator savedOriginalNextSelectedThread = lastSelectedThread; + std::map>::iterator savedOriginalNextSelectedThread = lastSelectedThread; do { lastSelectedThread++; - if (lastSelectedThread == readyBatchIters.end()) { - lastSelectedThread = readyBatchIters.begin(); + if (lastSelectedThread == readyBatchInclusiveEndLocs.end()) { + lastSelectedThread = readyBatchInclusiveEndLocs.begin(); } if (lastSelectedThread == savedOriginalNextSelectedThread) { return false; @@ -198,11 +203,12 @@ bool SMS::existLowIntensityThread() const { return false; } -bool SMS::isThresholdAgeExceeded(const Thread &thread, sc_time const &memClk, std::deque::iterator const &begin, std::deque::iterator const &end) { +bool SMS::isThresholdAgeExceeded(const Thread &thread, sc_time const &memClk, size_t const &inclusiveBeginLoc, size_t const &exclusiveEndLoc) { + assert((exclusiveEndLoc - inclusiveBeginLoc) >= 1); // 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(); + for (size_t i = inclusiveBeginLoc; i != exclusiveEndLoc; ++i) { + sc_time reqGenerationTime = GenerationExtension::getExtension(requestBuffers[thread][i]).TimeOfGeneration(); if (reqGenerationTime < oldestGenerationTime) { oldestGenerationTime = reqGenerationTime; } @@ -235,8 +241,8 @@ void SMS::updateMPKCs(sc_time const &memClk) { } } -bool SMS::isExceededReqBufferSize(Thread const &thread) { - return requestBuffers[thread].size() == Configuration::getInstance().RequestBufferSize; +bool SMS::isExceededReqBufferSize(size_t const &exclusiveEndLoc) { + return exclusiveEndLoc <= Configuration::getInstance().RequestBufferSize; } bool SMS::isRequestBuffersEmpty() const { @@ -249,7 +255,7 @@ bool SMS::isRequestBuffersEmpty() const { } bool SMS::existReadyBatches() const { - for (const auto &each : readyBatchIters) { + for (const auto &each : readyBatchInclusiveEndLocs) { if (!each.second.empty()) { return true; } @@ -264,14 +270,15 @@ bool SMS::existReadyBatches() const { * @param begin * @return true if this batch is ready, otherwise false */ -bool SMS::batchFormation(sc_time const &memClk, Thread const &thread, std::deque const &requestBuffer, std::deque::iterator const &beginIter) +bool SMS::batchFormation(sc_time const &memClk, Thread const &thread, std::deque const &requestBuffer, size_t const &inclusiveBeginLoc) { if (requestBuffer.empty()) { return false; } - if (requestBuffer.end() == beginIter) + assert(inclusiveBeginLoc <= requestBuffer.size()); + if (requestBuffer.size() == inclusiveBeginLoc) { return false; } @@ -279,30 +286,46 @@ bool SMS::batchFormation(sc_time const &memClk, Thread const &thread, std::deque if (MPKCs[thread] < LOW_MPKC || isSystemLightlyLoaded()) { // bypass requests by forming batch with only one request (threshold age is ZERO) - readyBatchIters[thread].push_back(beginIter); + readyBatchInclusiveEndLocs[thread].push_back(inclusiveBeginLoc); return true; } else { // forming batch with FIFO size & threshold age constraints - std::deque::iterator firstDifferentRowAccessReqIter = beginIter; - Row firstRow = DramExtension::getRow(*beginIter); - while (firstDifferentRowAccessReqIter != requestBuffer.end() - && DramExtension::getRow(*firstDifferentRowAccessReqIter) == firstRow) + size_t firstDifferentRowAccessReqLoc = inclusiveBeginLoc; + Row firstRow = DramExtension::getRow(requestBuffer[inclusiveBeginLoc]); + bool isBatchReady = false; + size_t bufferSize = requestBuffer.size(); + while (firstDifferentRowAccessReqLoc != bufferSize + && DramExtension::getRow(requestBuffer[firstDifferentRowAccessReqLoc]) == firstRow) { - ++firstDifferentRowAccessReqIter; - if (firstDifferentRowAccessReqIter == requestBuffer.end ()) { - break; - } + ++firstDifferentRowAccessReqLoc; + if (firstDifferentRowAccessReqLoc < bufferSize) + { + if (DramExtension::getRow(requestBuffer[firstDifferentRowAccessReqLoc]) != firstRow + || isExceededReqBufferSize(firstDifferentRowAccessReqLoc) + || isThresholdAgeExceeded(thread, memClk, inclusiveBeginLoc, firstDifferentRowAccessReqLoc)) + { + isBatchReady = true; + break; + } + } + else + { + if (isExceededReqBufferSize(firstDifferentRowAccessReqLoc) + || isThresholdAgeExceeded(thread, memClk, inclusiveBeginLoc, firstDifferentRowAccessReqLoc)) + { + isBatchReady = true; + break; + } + } } - // deem this batch ready - if ((firstDifferentRowAccessReqIter != requestBuffer.end()) - || isExceededReqBufferSize(thread) - || isThresholdAgeExceeded(thread, memClk, beginIter, firstDifferentRowAccessReqIter)) + // store this ready batch location + if (isBatchReady) { - --firstDifferentRowAccessReqIter; - readyBatchIters[thread].push_back(firstDifferentRowAccessReqIter); + --firstDifferentRowAccessReqLoc; + readyBatchInclusiveEndLocs[thread].push_back(firstDifferentRowAccessReqLoc); debugManager.printDebugMessage(name(), "Deem batch ready - thread " + to_string(thread.ID())); return true; @@ -318,16 +341,16 @@ void SMS::multiBatchFormation(sc_time const &memClk) { for (auto &requestBuffer : requestBuffers) { - bool formed; + bool formed = false; do { - if (readyBatchIters[requestBuffer.first].empty()) + if (readyBatchInclusiveEndLocs[requestBuffer.first].empty()) { - formed = batchFormation(memClk, requestBuffer.first, requestBuffer.second, requestBuffer.second.begin()); + formed = batchFormation(memClk, requestBuffer.first, requestBuffer.second, 0); } else { - formed = batchFormation(memClk, requestBuffer.first, requestBuffer.second, readyBatchIters[requestBuffer.first].back() + 1); + formed = batchFormation(memClk, requestBuffer.first, requestBuffer.second, readyBatchInclusiveEndLocs[requestBuffer.first].back() + 1); } } while (!requestBuffer.second.empty() && formed); } diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h index bdb5c783..bbfffae1 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.h +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h @@ -35,7 +35,7 @@ public: SMS(sc_module_name /*_name*/, ControllerCore &controllerCore, unsigned int SJFprobability) : IScheduler(controllerCore), SJFprobability(SJFprobability), debugManager(DebugManager::getInstance()) { // initialize selected thread iterator - lastSelectedThread = readyBatchIters.end(); + lastSelectedThread = readyBatchInclusiveEndLocs.end(); SC_THREAD(batchScheduler); } SC_HAS_PROCESS(SMS); @@ -53,28 +53,28 @@ public: private: std::map> requestBuffers; std::map> bankBuffers; - std::map> readyBatchIters; + std::map> readyBatchInclusiveEndLocs; 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 batchFormation(sc_time const &memClk, Thread const &thread, const std::deque &requestBuffer, const std::deque::iterator &beginIter); + bool batchFormation(sc_time const &memClk, Thread const &thread, const std::deque &requestBuffer, const size_t &inclusiveBeginLoc); void multiBatchFormation(const sc_time &memClk); bool pickSJF(); bool pickRR(); - void drain(const sc_time &memClk); + void drainOnePayloadFromReadybatch(const sc_time &memClk); bool existLowIntensityThread() const; bool isSystemLightlyLoaded() const; - bool isThresholdAgeExceeded(const Thread &thread, const sc_time &memClk, const std::deque::iterator &begin, const std::deque::iterator &end); - bool isExceededReqBufferSize(Thread const &thread); + bool isThresholdAgeExceeded(const Thread &thread, const sc_time &memClk, const size_t &inclusiveBeginLoc, const size_t &exclusiveEndLoc); + bool isExceededReqBufferSize(size_t const &exclusiveEndLoc); void updateMPKCs(const sc_time &memClk); bool isRequestBuffersEmpty() const; From 9ed018089515f17fc303a92e1a2142bacf6544af Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Wed, 19 Jul 2017 19:06:53 +0200 Subject: [PATCH 3/3] Fix segmentation fault on wrong ranges --- .../src/controller/scheduler/SMS.cpp | 482 +++++++++--------- .../simulator/src/controller/scheduler/SMS.h | 6 +- 2 files changed, 244 insertions(+), 244 deletions(-) diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index 5d103522..a6547998 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -5,72 +5,72 @@ using namespace std; void SMS::schedule(gp *payload) { - Thread thread = DramExtension::getExtension(payload).getThread(); - bool wasEmpty = isRequestBuffersEmpty(); + Thread thread = DramExtension::getExtension(payload).getThread(); + bool wasEmpty = isRequestBuffersEmpty(); - requestBuffers[thread].emplace_back(payload); + requestBuffers[thread].emplace_back(payload); - if (inFlightMemRequestCounter.find(thread) == inFlightMemRequestCounter.end()) { - inFlightMemRequestCounter[thread] = 0; - cacheMisses[thread] = 0; - } - inFlightMemRequestCounter[thread]++; - cacheMisses[thread]++; + if (inFlightMemRequestCounter.find(thread) == inFlightMemRequestCounter.end()) { + inFlightMemRequestCounter[thread] = 0; + cacheMisses[thread] = 0; + } + inFlightMemRequestCounter[thread]++; + cacheMisses[thread]++; - if (wasEmpty) { - newRequest.notify(SC_ZERO_TIME); - } + if (wasEmpty) { + newRequest.notify(SC_ZERO_TIME); + } } std::pair SMS::getNextRequest(Bank bank) { - if (bankBuffers[bank].empty()) - { - debugManager.printDebugMessage(name(), - "Get next request on bank " + to_string(bank.ID()) + " : EMPTY buffer"); - return pair(Command::NOP, NULL); - } - else - { - gp* payload = bankBuffers[bank].front(); - Command command = IScheduler::getNextCommand(*payload); - if (command == Command::Read || command == Command::ReadA || command == Command::Write - || command == Command::WriteA) + if (bankBuffers[bank].empty()) { - inFlightMemRequestCounter[DramExtension::getExtension(payload).getThread()]--; - bankBuffers[bank].pop_front(); + debugManager.printDebugMessage(name(), + "Get next request on bank " + to_string(bank.ID()) + " : EMPTY buffer"); + return pair(Command::NOP, NULL); } + else + { + 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()]--; + bankBuffers[bank].pop_front(); + } - debugManager.printDebugMessage(name(), "Get next request on bank " + to_string(bank.ID())); - return pair(command, payload); - } + debugManager.printDebugMessage(name(), "Get next request on bank " + to_string(bank.ID())); + return pair(command, payload); + } } void SMS::batchScheduler() { - sc_time memClk = Configuration::getInstance().memSpec.clk; - std::default_random_engine generator; - std::bernoulli_distribution distribution((double) SJFprobability / 100.0); + sc_time memClk = Configuration::getInstance().memSpec.clk; + std::default_random_engine generator; + std::bernoulli_distribution distribution((double) SJFprobability / 100.0); - while (true) - { - updateMPKCs(memClk); - if (isRequestBuffersEmpty()) { - wait(newRequest); - } else { - multiBatchFormation(memClk); - if (existReadyBatches()) { - if (!isSystemLightlyLoaded() && (existLowIntensityThread() || distribution(generator))) { - pickSJF(); + while (true) + { + updateMPKCs(memClk); + if (isRequestBuffersEmpty()) { + wait(newRequest); } else { - pickRR(); + multiBatchFormation(memClk); + if (existReadyBatches()) { + if (!isSystemLightlyLoaded() && (existLowIntensityThread() || distribution(generator))) { + pickSJF(); + } else { + pickRR(); + } + drainOnePayloadFromReadybatch(memClk); + } else { + wait(memClk); + } } - drainOnePayloadFromReadybatch(memClk); - } else { - wait(memClk); - } } - } } /** @@ -80,39 +80,39 @@ void SMS::batchScheduler() */ bool SMS::pickSJF() { - // find threads with ready batches - std::vector threadsWithReadyBatches; - for (const auto &each : readyBatchInclusiveEndLocs) - { - if (!each.second.empty()) + // find threads with ready batches + std::vector threadsWithReadyBatches; + for (const auto &each : readyBatchInclusiveEndLocs) { - // marked as thread with non-empty request buffer - threadsWithReadyBatches.push_back(each.first); - } - } - - if (!threadsWithReadyBatches.empty()) - { - // pick shortest-job thread among threads with non-empty request buffer - Thread &minThread = threadsWithReadyBatches.front(); - for (const auto &thread : threadsWithReadyBatches) - { - if (inFlightMemRequestCounter[thread] < inFlightMemRequestCounter[minThread]) - { - minThread = thread; - } + if (!each.second.empty()) + { + // marked as thread with non-empty request buffer + threadsWithReadyBatches.push_back(each.first); + } } - // save selected thread - lastSelectedThread = readyBatchInclusiveEndLocs.find(minThread); - debugManager.printDebugMessage(name(), - "[SJF] Select ready batch of thread " + to_string(minThread.ID())); - return true; - } - else - { - return false; - } + if (!threadsWithReadyBatches.empty()) + { + // pick shortest-job thread among threads with non-empty request buffer + Thread &minThread = threadsWithReadyBatches.front(); + for (const auto &thread : threadsWithReadyBatches) + { + if (inFlightMemRequestCounter[thread] < inFlightMemRequestCounter[minThread]) + { + minThread = thread; + } + } + + // save selected thread + lastSelectedThread = readyBatchInclusiveEndLocs.find(minThread); + debugManager.printDebugMessage(name(), + "[SJF] Select ready batch of thread " + to_string(minThread.ID())); + return true; + } + else + { + return false; + } } /** @@ -123,34 +123,34 @@ bool SMS::pickSJF() */ void SMS::drainOnePayloadFromReadybatch(const sc_time &memClk) { - if (lastSelectedThread->second.empty()) { + if (lastSelectedThread->second.empty()) { return; - } - const Thread &selectedThread = lastSelectedThread->first; - - const size_t &inclusiveEndLoc = lastSelectedThread->second.front(); - assert(inclusiveEndLoc < requestBuffers.size()); - - for (size_t i = 0; i <= inclusiveEndLoc; ++i) - { - wait(memClk); - Bank bank = DramExtension::getExtension(requestBuffers[selectedThread].front()).getBank(); - bankBuffers[bank].emplace_back(requestBuffers[selectedThread].front()); - requestBuffers[selectedThread].pop_front(); - - // decrement inclusive end locations of ready batches - // except this ready batch - for (size_t i = 1; i < readyBatchInclusiveEndLocs.size(); ++i) - { - --readyBatchInclusiveEndLocs[selectedThread][i]; } + const Thread &selectedThread = lastSelectedThread->first; - debugManager.printDebugMessage(name(), - "[SJF] Drain request in the ready batch of thread " - + to_string((*lastSelectedThread).first.ID()) + " to bankbuffer " - + to_string(bank.ID())); - } - lastSelectedThread->second.pop_front(); + const size_t &inclusiveEndLoc = lastSelectedThread->second.front(); + assert(inclusiveEndLoc < requestBuffers.size()); + + for (size_t i = 0; i <= inclusiveEndLoc; ++i) + { + wait(memClk); + Bank bank = DramExtension::getExtension(requestBuffers[selectedThread].front()).getBank(); + bankBuffers[bank].emplace_back(requestBuffers[selectedThread].front()); + requestBuffers[selectedThread].pop_front(); + + // decrement inclusive end locations of ready batches + // except this ready batch + for (size_t i = 1; i < readyBatchInclusiveEndLocs[selectedThread].size(); ++i) + { + --readyBatchInclusiveEndLocs[selectedThread][i]; + } + + debugManager.printDebugMessage(name(), + "[SJF] Drain request in the ready batch of thread " + + to_string((*lastSelectedThread).first.ID()) + " to bankbuffer " + + to_string(bank.ID())); + } + lastSelectedThread->second.pop_front(); } /** @@ -162,105 +162,105 @@ bool SMS::pickRR() { if (lastSelectedThread == readyBatchInclusiveEndLocs.end()) { - lastSelectedThread = readyBatchInclusiveEndLocs.begin(); - if (!(*lastSelectedThread).second.empty()) { - return true; - } + lastSelectedThread = readyBatchInclusiveEndLocs.begin(); + if (!(*lastSelectedThread).second.empty()) { + return true; + } } std::map>::iterator savedOriginalNextSelectedThread = lastSelectedThread; do { - lastSelectedThread++; - if (lastSelectedThread == readyBatchInclusiveEndLocs.end()) { - lastSelectedThread = readyBatchInclusiveEndLocs.begin(); - } - if (lastSelectedThread == savedOriginalNextSelectedThread) { - return false; - } + lastSelectedThread++; + if (lastSelectedThread == readyBatchInclusiveEndLocs.end()) { + lastSelectedThread = readyBatchInclusiveEndLocs.begin(); + } + if (lastSelectedThread == savedOriginalNextSelectedThread) { + return false; + } } while ((*lastSelectedThread).second.empty()); debugManager.printDebugMessage(name(), - "[RR] Select ready batch of thread " + to_string((*lastSelectedThread).first.ID())); + "[RR] Select ready batch of thread " + to_string((*lastSelectedThread).first.ID())); return true; } bool SMS::isSystemLightlyLoaded() const { - unsigned int totalRequest = 0; - for (const auto &bankBuffer : bankBuffers) { - totalRequest += bankBuffer.second.size(); - } - return (totalRequest <= LOW_SYSTEM_LOAD); + unsigned int totalRequest = 0; + for (const auto &bankBuffer : bankBuffers) { + totalRequest += bankBuffer.second.size(); + } + return (totalRequest <= LOW_SYSTEM_LOAD); } bool SMS::existLowIntensityThread() const { - for (const auto &mpkcPerThread : MPKCs) { - if (mpkcPerThread.second < LOW_MPKC) { - return true; + for (const auto &mpkcPerThread : MPKCs) { + if (mpkcPerThread.second < LOW_MPKC) { + return true; + } } - } - return false; + return false; } bool SMS::isThresholdAgeExceeded(const Thread &thread, sc_time const &memClk, size_t const &inclusiveBeginLoc, size_t const &exclusiveEndLoc) { - assert((exclusiveEndLoc - inclusiveBeginLoc) >= 1); - // find the oldest request in the thread's batch - sc_time oldestGenerationTime = sc_time_stamp(); - for (size_t i = inclusiveBeginLoc; i != exclusiveEndLoc; ++i) { - sc_time reqGenerationTime = GenerationExtension::getExtension(requestBuffers[thread][i]).TimeOfGeneration(); - if (reqGenerationTime < oldestGenerationTime) { - oldestGenerationTime = reqGenerationTime; + assert((exclusiveEndLoc - inclusiveBeginLoc) >= 1); + // find the oldest request in the thread's batch + sc_time oldestGenerationTime = sc_time_stamp(); + for (size_t i = inclusiveBeginLoc; i != exclusiveEndLoc; ++i) { + sc_time reqGenerationTime = GenerationExtension::getExtension(requestBuffers[thread][i]).TimeOfGeneration(); + if (reqGenerationTime < oldestGenerationTime) { + oldestGenerationTime = reqGenerationTime; + } } - } - // 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; - } + // 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 const &memClk) { - if (sc_time_stamp() % (MPKC_RESET_CYCLE * memClk) <= memClk) { - // reset for every 10k clk cycles - for (const auto &cacheMiss : cacheMisses) { - MPKCs[cacheMiss.first] = 0; + if (sc_time_stamp() % (MPKC_RESET_CYCLE * memClk) <= memClk) { + // reset for every 10k clk cycles + for (const auto &cacheMiss : cacheMisses) { + MPKCs[cacheMiss.first] = 0; + } + debugManager.printDebugMessage(name(), "Reset MKKCs"); + } else { + // update MPKC for every thread + for (const auto &cacheMiss : cacheMisses) { + MPKCs[cacheMiss.first] = (cacheMiss.second * 1000.0 * memClk) / (sc_time_stamp()); + } + debugManager.printDebugMessage(name(), "Update MPKCs"); } - debugManager.printDebugMessage(name(), "Reset MKKCs"); - } else { - // update MPKC for every thread - for (const auto &cacheMiss : cacheMisses) { - MPKCs[cacheMiss.first] = (cacheMiss.second * 1000.0 * memClk) / (sc_time_stamp()); - } - debugManager.printDebugMessage(name(), "Update MPKCs"); - } } bool SMS::isExceededReqBufferSize(size_t const &exclusiveEndLoc) { - return exclusiveEndLoc <= Configuration::getInstance().RequestBufferSize; + return exclusiveEndLoc <= Configuration::getInstance().RequestBufferSize; } bool SMS::isRequestBuffersEmpty() const { - for (const auto &requestBuffer : requestBuffers) { - if (!requestBuffer.second.empty()) { - return false; + for (const auto &requestBuffer : requestBuffers) { + if (!requestBuffer.second.empty()) { + return false; + } } - } - return true; + return true; } bool SMS::existReadyBatches() const { - for (const auto &each : readyBatchInclusiveEndLocs) { - if (!each.second.empty()) { - return true; + for (const auto &each : readyBatchInclusiveEndLocs) { + if (!each.second.empty()) { + return true; + } } - } - return false; + return false; } /** @@ -272,98 +272,98 @@ bool SMS::existReadyBatches() const { */ bool SMS::batchFormation(sc_time const &memClk, Thread const &thread, std::deque const &requestBuffer, size_t const &inclusiveBeginLoc) { - if (requestBuffer.empty()) - { - return false; - } - - assert(inclusiveBeginLoc <= requestBuffer.size()); - if (requestBuffer.size() == inclusiveBeginLoc) - { - return false; - } - - if (MPKCs[thread] < LOW_MPKC || isSystemLightlyLoaded()) - { - // bypass requests by forming batch with only one request (threshold age is ZERO) - readyBatchInclusiveEndLocs[thread].push_back(inclusiveBeginLoc); - return true; - } - else - { - // forming batch with FIFO size & threshold age constraints - size_t firstDifferentRowAccessReqLoc = inclusiveBeginLoc; - Row firstRow = DramExtension::getRow(requestBuffer[inclusiveBeginLoc]); - bool isBatchReady = false; - size_t bufferSize = requestBuffer.size(); - while (firstDifferentRowAccessReqLoc != bufferSize - && DramExtension::getRow(requestBuffer[firstDifferentRowAccessReqLoc]) == firstRow) + if (requestBuffer.empty()) { - ++firstDifferentRowAccessReqLoc; - if (firstDifferentRowAccessReqLoc < bufferSize) - { - if (DramExtension::getRow(requestBuffer[firstDifferentRowAccessReqLoc]) != firstRow - || isExceededReqBufferSize(firstDifferentRowAccessReqLoc) - || isThresholdAgeExceeded(thread, memClk, inclusiveBeginLoc, firstDifferentRowAccessReqLoc)) - { - isBatchReady = true; - break; - } - } - else - { - if (isExceededReqBufferSize(firstDifferentRowAccessReqLoc) - || isThresholdAgeExceeded(thread, memClk, inclusiveBeginLoc, firstDifferentRowAccessReqLoc)) - { - isBatchReady = true; - break; - } - } + return false; } - // store this ready batch location - if (isBatchReady) + assert(inclusiveBeginLoc <= requestBuffer.size()); + if (requestBuffer.size() == inclusiveBeginLoc) { - --firstDifferentRowAccessReqLoc; - readyBatchInclusiveEndLocs[thread].push_back(firstDifferentRowAccessReqLoc); - debugManager.printDebugMessage(name(), - "Deem batch ready - thread " + to_string(thread.ID())); - return true; + return false; + } + + if (MPKCs[thread] < LOW_MPKC || isSystemLightlyLoaded()) + { + // bypass requests by forming batch with only one request (threshold age is ZERO) + readyBatchInclusiveEndLocs[thread].push_back(inclusiveBeginLoc); + return true; } else { - return false; + // forming batch with FIFO size & threshold age constraints + size_t firstDifferentRowAccessReqLoc = inclusiveBeginLoc; + Row firstRow = DramExtension::getRow(requestBuffer[inclusiveBeginLoc]); + bool isBatchReady = false; + size_t bufferSize = requestBuffer.size(); + while (firstDifferentRowAccessReqLoc != bufferSize + && DramExtension::getRow(requestBuffer[firstDifferentRowAccessReqLoc]) == firstRow) + { + ++firstDifferentRowAccessReqLoc; + if (firstDifferentRowAccessReqLoc < bufferSize) + { + if (DramExtension::getRow(requestBuffer[firstDifferentRowAccessReqLoc]) != firstRow + || isExceededReqBufferSize(firstDifferentRowAccessReqLoc) + || isThresholdAgeExceeded(thread, memClk, inclusiveBeginLoc, firstDifferentRowAccessReqLoc)) + { + isBatchReady = true; + break; + } + } + else + { + if (isExceededReqBufferSize(firstDifferentRowAccessReqLoc) + || isThresholdAgeExceeded(thread, memClk, inclusiveBeginLoc, firstDifferentRowAccessReqLoc)) + { + isBatchReady = true; + break; + } + } + } + + // store this ready batch location + if (isBatchReady) + { + --firstDifferentRowAccessReqLoc; + readyBatchInclusiveEndLocs[thread].push_back(firstDifferentRowAccessReqLoc); + debugManager.printDebugMessage(name(), + "Deem batch ready - thread " + to_string(thread.ID())); + return true; + } + else + { + return false; + } } - } } void SMS::multiBatchFormation(sc_time const &memClk) { - for (auto &requestBuffer : requestBuffers) - { - bool formed = false; - do + for (auto &requestBuffer : requestBuffers) { - if (readyBatchInclusiveEndLocs[requestBuffer.first].empty()) - { - formed = batchFormation(memClk, requestBuffer.first, requestBuffer.second, 0); - } - else - { - formed = batchFormation(memClk, requestBuffer.first, requestBuffer.second, readyBatchInclusiveEndLocs[requestBuffer.first].back() + 1); - } - } while (!requestBuffer.second.empty() && formed); - } + bool formed = false; + do + { + if (readyBatchInclusiveEndLocs[requestBuffer.first].empty()) + { + formed = batchFormation(memClk, requestBuffer.first, requestBuffer.second, 0); + } + else + { + formed = batchFormation(memClk, requestBuffer.first, requestBuffer.second, readyBatchInclusiveEndLocs[requestBuffer.first].back() + 1); + } + } while (!requestBuffer.second.empty() && formed); + } } gp* SMS::getPendingRequest(Bank bank) { - for (const auto &requestBuffer : requestBuffers) { - for (const auto &request : requestBuffer.second) { - if (DramExtension::getBank(request) == bank) { - return request; - } + for (const auto &requestBuffer : requestBuffers) { + for (const auto &request : requestBuffer.second) { + if (DramExtension::getBank(request) == bank) { + return request; + } + } } - } - return NULL; + return NULL; } diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h index bbfffae1..1b869cae 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.h +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h @@ -34,9 +34,9 @@ class SMS: public sc_module, public IScheduler public: SMS(sc_module_name /*_name*/, ControllerCore &controllerCore, unsigned int SJFprobability) : IScheduler(controllerCore), SJFprobability(SJFprobability), debugManager(DebugManager::getInstance()) { - // initialize selected thread iterator - lastSelectedThread = readyBatchInclusiveEndLocs.end(); - SC_THREAD(batchScheduler); + // initialize selected thread iterator + lastSelectedThread = readyBatchInclusiveEndLocs.end(); + SC_THREAD(batchScheduler); } SC_HAS_PROCESS(SMS);