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