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/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 64882dc3..a6547998 100644
--- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp
+++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp
@@ -5,77 +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))) {
- if (pickSJF()) {
- drain(memClk, (*lastSelectedThread).second.front());
- (*lastSelectedThread).second.pop_front();
- }
+ while (true)
+ {
+ updateMPKCs(memClk);
+ if (isRequestBuffersEmpty()) {
+ wait(newRequest);
} else {
- if (pickRR()) {
- drain(memClk, (*lastSelectedThread).second.front());
- (*lastSelectedThread).second.pop_front();
- }
+ multiBatchFormation(memClk);
+ if (existReadyBatches()) {
+ if (!isSystemLightlyLoaded() && (existLowIntensityThread() || distribution(generator))) {
+ pickSJF();
+ } else {
+ pickRR();
+ }
+ drainOnePayloadFromReadybatch(memClk);
+ } else {
+ wait(memClk);
+ }
}
- } else {
- wait(memClk);
- }
}
- }
}
/**
@@ -85,39 +80,39 @@ void SMS::batchScheduler()
*/
bool SMS::pickSJF()
{
- // find threads with ready batches
- std::vector threadsWithReadyBatches;
- for (auto& each : readyBatchIters)
- {
- 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 (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 = readyBatchIters.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;
+ }
}
/**
@@ -126,26 +121,36 @@ bool SMS::pickSJF()
* @param memClk
* @param last
*/
-void SMS::drain(sc_time memClk, std::deque::iterator last)
+void SMS::drainOnePayloadFromReadybatch(const sc_time &memClk)
{
- 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(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();
+ if (lastSelectedThread->second.empty()) {
+ return;
+ }
+ 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()));
- }
+ 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();
}
/**
@@ -155,118 +160,107 @@ 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 == readyBatchInclusiveEndLocs.end())
{
- nextSelectedThread = readyBatchIters.begin();
+ lastSelectedThread = readyBatchInclusiveEndLocs.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 == readyBatchInclusiveEndLocs.end()) {
+ lastSelectedThread = readyBatchInclusiveEndLocs.begin();
+ }
+ if (lastSelectedThread == savedOriginalNextSelectedThread) {
+ return false;
+ }
+ } while ((*lastSelectedThread).second.empty());
-bool SMS::isSystemLightlyLoaded() {
- unsigned int totalRequest = 0;
- for (auto& bankBuffer : bankBuffers) {
- totalRequest += bankBuffer.second.size();
- }
- 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;
- }
- }
-
- // 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))) {
+ debugManager.printDebugMessage(name(),
+ "[RR] Select ready batch of thread " + to_string((*lastSelectedThread).first.ID()));
return true;
- } else if ((MPKCs[thread] > MEDIUM_MPKC) && (oldestRequestAge > (HIGH_THRESHOLD_AGE * memClk))) {
- return true;
- } else {
+}
+
+bool SMS::isSystemLightlyLoaded() const {
+ 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;
+ }
+ }
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& cacheMiss : cacheMisses) {
- MPKCs[cacheMiss.first] = 0;
+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;
+ }
}
- debugManager.printDebugMessage(name(), "Reset MKKCs");
- } else {
- // update MPKC for every thread
- for (auto& cacheMiss : cacheMisses) {
- MPKCs[cacheMiss.first] = (cacheMiss.second * 1000.0 * memClk) / (sc_time_stamp());
+
+ // 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;
}
- debugManager.printDebugMessage(name(), "Update MPKCs");
- }
}
-bool SMS::isExceededReqBufferSize(Thread thread) {
- return requestBuffers[thread].size() == Configuration::getInstance().RequestBufferSize;
+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;
+ }
+ 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::isRequestBuffersEmpty() {
- for (auto& requestBuffer : requestBuffers) {
- if (!requestBuffer.second.empty()) {
- return false;
- }
- }
- return true;
+bool SMS::isExceededReqBufferSize(size_t const &exclusiveEndLoc) {
+ return exclusiveEndLoc <= Configuration::getInstance().RequestBufferSize;
}
-bool SMS::existReadyBatches() {
- for (auto& each : readyBatchIters) {
- if (!each.second.empty()) {
- return true;
+bool SMS::isRequestBuffersEmpty() const {
+ for (const auto &requestBuffer : requestBuffers) {
+ if (!requestBuffer.second.empty()) {
+ return false;
+ }
}
- }
- return false;
+ return true;
+}
+
+bool SMS::existReadyBatches() const {
+ for (const auto &each : readyBatchInclusiveEndLocs) {
+ if (!each.second.empty()) {
+ return true;
+ }
+ }
+ return false;
}
/**
@@ -276,82 +270,100 @@ 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, size_t const &inclusiveBeginLoc)
{
- 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)
- readyBatchIters[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)
+ if (requestBuffer.empty())
{
- firstDifferentRowAccessReqIter++;
+ return false;
}
- // deem this batch ready
- if ((firstDifferentRowAccessReqIter != requestBuffer.second.end())
- || isExceededReqBufferSize(requestBuffer.first)
- || isThresholdAgeExceeded(requestBuffer.first, memClk, beginIter,
- firstDifferentRowAccessReqIter))
+ assert(inclusiveBeginLoc <= requestBuffer.size());
+ if (requestBuffer.size() == inclusiveBeginLoc)
{
- firstDifferentRowAccessReqIter--;
- readyBatchIters[requestBuffer.first].push_back(firstDifferentRowAccessReqIter);
- debugManager.printDebugMessage(name(),
- "Deem batch ready - thread " + to_string(requestBuffer.first.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 memClk)
+void SMS::multiBatchFormation(sc_time const &memClk)
{
- for (auto& requestBuffer : requestBuffers)
- {
- bool formed;
- do
+ for (auto &requestBuffer : requestBuffers)
{
- if (readyBatchIters[requestBuffer.first].empty())
- {
- formed = batchFormation(memClk, (std::pair>&)requestBuffer, requestBuffer.second.begin());
- }
- else
- {
- formed = batchFormation(memClk, (std::pair>&)requestBuffer, readyBatchIters[requestBuffer.first].back() + 1);
- }
- } while (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 (auto& requestBuffer : requestBuffers) {
- for (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 2843b990..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 = readyBatchIters.end();
- SC_THREAD(batchScheduler);
+ // initialize selected thread iterator
+ lastSelectedThread = readyBatchInclusiveEndLocs.end();
+ SC_THREAD(batchScheduler);
}
SC_HAS_PROCESS(SMS);
@@ -53,32 +53,32 @@ 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 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 size_t &inclusiveBeginLoc);
+ void multiBatchFormation(const sc_time &memClk);
bool pickSJF();
bool pickRR();
- void drain(sc_time memClk, std::deque::iterator last);
+ void drainOnePayloadFromReadybatch(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 size_t &inclusiveBeginLoc, const size_t &exclusiveEndLoc);
+ bool isExceededReqBufferSize(size_t const &exclusiveEndLoc);
+ void updateMPKCs(const sc_time &memClk);
- bool isRequestBuffersEmpty();
- bool existReadyBatches();
+ bool isRequestBuffersEmpty() const;
+ bool existReadyBatches() const;
};
#endif // SMS_H