diff --git a/DRAMSys/simulator/resources/simulations/sms-example.xml b/DRAMSys/simulator/resources/simulations/sms-example.xml
index d1a2f734..d40e0e8c 100644
--- a/DRAMSys/simulator/resources/simulations/sms-example.xml
+++ b/DRAMSys/simulator/resources/simulations/sms-example.xml
@@ -12,10 +12,14 @@
+ ddr3_example.stl
sms_t1.stl
sms_t2.stl
sms_t3.stl
sms_t4.stl
+ stream.stl
+ random.stl
+ chstone-adpcm_32.stl
diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp
index 14d63207..d4336415 100644
--- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp
+++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp
@@ -54,36 +54,25 @@ void SMS::batchScheduler()
while (true)
{
-// updateMPKCs(memClk);
-// if (isRequestBuffersEmpty() && !existReadyBatches()) {
-// wait(newRequest);
-// } else {
-// batchFormation(memClk);
-// if (existReadyBatches()) {
-// if (!isSystemLightlyLoaded() && (existLowIntensityThread() || distribution(generator))) {
-// selectSJF(memClk);
-// } else {
-// selectRR(memClk);
-// }
-// } else {
-// wait(memClk);
-// }
-// }
updateMPKCs(memClk);
if (isRequestBuffersEmpty()) {
wait(newRequest);
} else {
multiBatchFormation(memClk);
- if (!isSystemLightlyLoaded() && (existLowIntensityThread() || distribution(generator))) {
- if (pickSJF()) {
- drain(memClk, readyBatchesIter[(*lastSelectedThread).first].front());
- readyBatchesIter[(*lastSelectedThread).first].pop_front();
+ if (existReadyBatches()) {
+ if (!isSystemLightlyLoaded() && (existLowIntensityThread() || distribution(generator))) {
+ if (pickSJF()) {
+ drain(memClk, (*lastSelectedThread).second.front());
+ (*lastSelectedThread).second.pop_front();
+ }
+ } else {
+ if (pickRR()) {
+ drain(memClk, (*lastSelectedThread).second.front());
+ (*lastSelectedThread).second.pop_front();
+ }
}
} else {
- if (pickRR()) {
- drain(memClk, readyBatchesIter[(*lastSelectedThread).first].front());
- readyBatchesIter[(*lastSelectedThread).first].pop_front();
- }
+ wait(memClk);
}
}
}
@@ -96,22 +85,22 @@ void SMS::batchScheduler()
*/
bool SMS::pickSJF()
{
- // find threads with non-empty request buffers
- std::vector threadsWithNonEmptyRequestBuffer;
- for (auto& requestBuffer : requestBuffers)
+ // find threads with ready batches
+ std::vector threadsWithReadyBatches;
+ for (auto& each : readyBatchIters)
{
- if (!requestBuffer.second.empty())
+ if (!each.second.empty())
{
// marked as thread with non-empty request buffer
- threadsWithNonEmptyRequestBuffer.push_back(requestBuffer.first);
+ threadsWithReadyBatches.push_back(each.first);
}
}
- if (!threadsWithNonEmptyRequestBuffer.empty())
+ if (!threadsWithReadyBatches.empty())
{
// pick shortest-job thread among threads with non-empty request buffer
- Thread minThread = threadsWithNonEmptyRequestBuffer.front();
- for (auto& thread : threadsWithNonEmptyRequestBuffer)
+ Thread minThread = threadsWithReadyBatches.front();
+ for (auto& thread : threadsWithReadyBatches)
{
if (inFlightMemRequestCounter[thread] < inFlightMemRequestCounter[minThread])
{
@@ -120,7 +109,7 @@ bool SMS::pickSJF()
}
// save selected thread
- lastSelectedThread = readybatches.find(minThread);
+ lastSelectedThread = readyBatchIters.find(minThread);
debugManager.printDebugMessage(name(),
"[SJF] Select ready batch of thread " + to_string(minThread.ID()));
return true;
@@ -131,62 +120,6 @@ bool SMS::pickSJF()
}
}
-bool SMS::selectSJF(sc_time memClk)
-{
- // find threads with non-empty ready batch
- std::vector threadsWithNonEmptyReadybatches;
- for (auto& readybatch : readybatches)
- {
- if (!readybatch.second.empty())
- {
- // marked as thread with non-empty ready batch
- threadsWithNonEmptyReadybatches.push_back(readybatch.first);
- }
- }
-
- if (!threadsWithNonEmptyReadybatches.empty())
- {
- // pick shortest-job thread among threads with non-empty ready batch
- Thread minThread = threadsWithNonEmptyReadybatches.front();
- for (auto& thread : threadsWithNonEmptyReadybatches)
- {
- if (inFlightMemRequestCounter[thread] < inFlightMemRequestCounter[minThread])
- {
- minThread = thread;
- }
- }
-
- // save selected thread
- lastSelectedThread = readybatches.find(minThread);
-
- debugManager.printDebugMessage(name(),
- "[SJF] Select ready batch of thread " + to_string(minThread.ID()));
-
- // drain to bank buffers
- std::deque &requestPtrs = readybatches[minThread];
- for (auto payloadPtrIterator = requestPtrs.begin(); payloadPtrIterator != requestPtrs.end();
- payloadPtrIterator++)
- {
- Bank bank = DramExtension::getExtension(*payloadPtrIterator).getBank();
- bankBuffers[bank].emplace_back(*payloadPtrIterator);
- debugManager.printDebugMessage(name(),
- "[SJF] Drain request in the ready batch of thread " + to_string(minThread.ID())
- + " to bankbuffer " + to_string(bank.ID()));
- wait(memClk);
- }
- requestPtrs.clear();
-
- // a ready batch has been picked up & drained
- return true;
- }
- else
- {
- // non-existed ready batch to be picked up & drained
- // this mean the request buffers are totally empty
- return false;
- }
-}
-
/**
* Drain the picked request buffer into bank buffers
* by move request one-by-one from start of the request buffer till last parameter
@@ -195,17 +128,18 @@ bool SMS::selectSJF(sc_time memClk)
*/
void SMS::drain(sc_time memClk, std::deque::iterator last)
{
- unsigned int batchSize = std::distance((*lastSelectedThread).second.begin(), last) + 1;
+ 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(*((*lastSelectedThread).second.begin())).getBank();
+ Bank bank = DramExtension::getExtension(requestBuffers[selectedThread].front()).getBank();
// if(bankBuffers[bank].size() == Configuration::getInstance().BankBufferSize)
// {
// wait(bankBufferIsNotFull);
// }
wait(memClk);
- bankBuffers[bank].emplace_back(*((*lastSelectedThread).second.begin()));
- (*lastSelectedThread).second.pop_front();
+ bankBuffers[bank].emplace_back(requestBuffers[selectedThread].front());
+ requestBuffers[selectedThread].pop_front();
debugManager.printDebugMessage(name(),
"[SJF] Drain request in the ready batch of thread "
@@ -221,28 +155,28 @@ void SMS::drain(sc_time memClk, std::deque::iterator last)
*/
bool SMS::pickRR()
{
- std::map>::iterator nextSelectedThread;
- if (lastSelectedThread == requestBuffers.end())
+ std::map>::iterator nextSelectedThread;
+ if (lastSelectedThread == readyBatchIters.end())
{
- lastSelectedThread = requestBuffers.begin();
+ lastSelectedThread = readyBatchIters.begin();
nextSelectedThread = lastSelectedThread;
}
else
{
nextSelectedThread = lastSelectedThread;
nextSelectedThread++;
- if (nextSelectedThread == requestBuffers.end())
- nextSelectedThread = requestBuffers.begin();
+ if (nextSelectedThread == readyBatchIters.end())
+ nextSelectedThread = readyBatchIters.begin();
}
- std::map>::iterator savedOriginalNextSelectedThread = nextSelectedThread;
+ std::map>::iterator savedOriginalNextSelectedThread = nextSelectedThread;
while ((*nextSelectedThread).second.empty())
{
nextSelectedThread++;
- if (nextSelectedThread == requestBuffers.end())
+ if (nextSelectedThread == readyBatchIters.end())
{
- nextSelectedThread = requestBuffers.begin();
+ nextSelectedThread = readyBatchIters.begin();
}
if (nextSelectedThread == savedOriginalNextSelectedThread)
@@ -259,67 +193,6 @@ bool SMS::pickRR()
return true;
}
-bool SMS::selectRR(sc_time memClk)
-{
- // no request for this channel, the readybatches map is empty then return
- if (readybatches.empty()) {
- return false;
- }
-
- // pick the next non-empty ready batch
- std::map>::iterator nextSelectedThread;
- if (lastSelectedThread == readybatches.end())
- {
- lastSelectedThread = readybatches.begin();
- nextSelectedThread = lastSelectedThread;
- }
- else
- {
- nextSelectedThread = lastSelectedThread;
- nextSelectedThread++;
- if (nextSelectedThread == readybatches.end())
- nextSelectedThread = readybatches.begin();
- }
- std::map>::iterator savedOriginalNextSelectedThread = nextSelectedThread;
- while ((*nextSelectedThread).second.empty())
- {
- nextSelectedThread++;
- if (nextSelectedThread == readybatches.end())
- {
- nextSelectedThread = readybatches.begin();
- }
-
- if (nextSelectedThread == savedOriginalNextSelectedThread)
- {
- // 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()));
-
- // drain to bank buffers
- std::deque &requestPtrs = (*nextSelectedThread).second;
- for (auto payloadPtrIterator = requestPtrs.begin(); payloadPtrIterator != requestPtrs.end();
- payloadPtrIterator++)
- {
- Bank bank = DramExtension::getExtension(*payloadPtrIterator).getBank();
- bankBuffers[bank].emplace_back(*payloadPtrIterator);
- debugManager.printDebugMessage(name(),
- "[RR] Drained request in the ready batch of thread " + to_string((*nextSelectedThread).first.ID())
- + " to bankbuffer " + to_string(bank.ID()));
- wait(memClk);
- }
- requestPtrs.clear();
-
- // a ready batch has been picked up & drained
- return true;
-}
-
bool SMS::isSystemLightlyLoaded() {
unsigned int totalRequest = 0;
for (auto& bankBuffer : bankBuffers) {
@@ -378,36 +251,6 @@ bool SMS::isExceededReqBufferSize(Thread thread) {
return requestBuffers[thread].size() == REQUEST_BUFFER_SIZE;
}
-void SMS::batchFormation(sc_time memClk) {
- for (auto& requestBuffer : requestBuffers) {
- if (!requestBuffer.second.empty() && readybatches[requestBuffer.first].empty()) {
- if (MPKCs[requestBuffer.first] < LOW_MPKC || isSystemLightlyLoaded()) {
- // bypass requests by forming batch with only one request (threshold age is ZERO)
- readybatches[requestBuffer.first].emplace_back(requestBuffer.second.front());
- requestBuffer.second.pop_front();
- debugManager.printDebugMessage(name(), "Bypass requests by forming batch of thread " + to_string(requestBuffer.first.ID()));
- } else {
- // forming batch with FIFO size & threshold age constraints
- auto firstDifferentRowAccessReqIter = requestBuffer.second.begin();
- Row firstRow = DramExtension::getRow(*firstDifferentRowAccessReqIter);
- while (firstDifferentRowAccessReqIter != requestBuffer.second.end() && DramExtension::getRow(*firstDifferentRowAccessReqIter) == firstRow) {
- firstDifferentRowAccessReqIter++;
- }
- // deem this batch ready
- if ((firstDifferentRowAccessReqIter != requestBuffer.second.end())
- || isExceededReqBufferSize(requestBuffer.first)
- || isThresholdAgeExceeded(requestBuffer.first, memClk, requestBuffer.second.begin(), firstDifferentRowAccessReqIter)) {
- do {
- readybatches[requestBuffer.first].emplace_back(requestBuffer.second.front());
- requestBuffer.second.pop_front();
- } while (requestBuffer.second.begin() != firstDifferentRowAccessReqIter);
- debugManager.printDebugMessage(name(), "Deem batch ready - thread " + to_string(requestBuffer.first.ID()));
- }
- }
- }
- }
-}
-
bool SMS::isRequestBuffersEmpty() {
for (auto& requestBuffer : requestBuffers) {
if (!requestBuffer.second.empty()) {
@@ -418,8 +261,8 @@ bool SMS::isRequestBuffersEmpty() {
}
bool SMS::existReadyBatches() {
- for (auto& readybatch : readybatches) {
- if (!readybatch.second.empty()) {
+ for (auto& each : readyBatchIters) {
+ if (!each.second.empty()) {
return true;
}
}
@@ -449,7 +292,7 @@ bool SMS::batchFormation(sc_time memClk, std::pair> &req
if (MPKCs[requestBuffer.first] < LOW_MPKC || isSystemLightlyLoaded())
{
// bypass requests by forming batch with only one request (threshold age is ZERO)
- readyBatchesIter[requestBuffer.first].push_back(beginIter);
+ readyBatchIters[requestBuffer.first].push_back(beginIter);
return true;
}
else
@@ -470,7 +313,7 @@ bool SMS::batchFormation(sc_time memClk, std::pair> &req
firstDifferentRowAccessReqIter))
{
firstDifferentRowAccessReqIter--;
- readyBatchesIter[requestBuffer.first].push_back(firstDifferentRowAccessReqIter);
+ readyBatchIters[requestBuffer.first].push_back(firstDifferentRowAccessReqIter);
debugManager.printDebugMessage(name(),
"Deem batch ready - thread " + to_string(requestBuffer.first.ID()));
return true;
@@ -489,13 +332,13 @@ void SMS::multiBatchFormation(sc_time memClk)
bool formed;
do
{
- if (readyBatchesIter[requestBuffer.first].empty())
+ if (readyBatchIters[requestBuffer.first].empty())
{
formed = batchFormation(memClk, (std::pair>&)requestBuffer, requestBuffer.second.begin());
}
else
{
- formed = batchFormation(memClk, (std::pair>&)requestBuffer, readyBatchesIter[requestBuffer.first].back() + 1);
+ formed = batchFormation(memClk, (std::pair>&)requestBuffer, readyBatchIters[requestBuffer.first].back() + 1);
}
} while (formed);
}
diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h
index c786fbcc..df9c132f 100644
--- a/DRAMSys/simulator/src/controller/scheduler/SMS.h
+++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h
@@ -20,6 +20,7 @@
#define REQUEST_BUFFER_SIZE 10
using namespace std;
+typedef std::deque::iterator gp_deque_iterator;
class SMS: public sc_module, public IScheduler
{
@@ -27,8 +28,7 @@ public:
SMS(sc_module_name /*_name*/, ControllerCore &controllerCore, unsigned int SJFprobability) : IScheduler(controllerCore), SJFprobability(SJFprobability), debugManager(DebugManager::getInstance())
{
// initialize selected thread iterator
-// lastSelectedThread = readybatches.end();
- lastSelectedThread = requestBuffers.end();
+ lastSelectedThread = readyBatchIters.end();
SC_THREAD(batchScheduler);
}
SC_HAS_PROCESS(SMS);
@@ -45,22 +45,18 @@ public:
private:
std::map> requestBuffers;
std::map> bankBuffers;
- std::map> readybatches;
- std::map::iterator>> readyBatchesIter;
+ std::map> readyBatchIters;
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 selectSJF(sc_time memClk);
- bool selectRR(sc_time memClk);
- void batchFormation(sc_time memClk);
bool batchFormation(sc_time memClk, std::pair> &requestBuffer, std::deque::iterator beginIter);
void multiBatchFormation(sc_time memClk);
bool pickSJF();