From 7f9569f25d474987696cff1ad689efcaf79ee7be Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Sun, 16 Jul 2017 04:19:51 +0200 Subject: [PATCH] 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