Fix SelectRR & batch scheduler

1. Form new batch for thread with empty ready batch
2. Return boolean indicate successful selectRR
This commit is contained in:
Thanh C. Tran
2017-04-29 11:19:06 +02:00
parent 64ed3107b5
commit 55d36d60c2
2 changed files with 61 additions and 42 deletions

View File

@@ -40,31 +40,27 @@ void SMS::batchScheduler()
sc_time memClk = Configuration::getInstance().memSpec.clk;
std::default_random_engine generator;
std::bernoulli_distribution distribution((double) SJFprobability / 100.0);
bool isSJF;
std::map<Thread, ReadyBatch*>::iterator select = readybatches.begin();
wait(150, SC_NS); // Test Purpose
while (true)
{
// wait(memClk); //TODO: Is this correct???
isSJF = distribution(generator);
if (!existReadyBatch())
if (distribution(generator))
{
// pick & drain a ready batch
if (batchFormation())
{
isSJF ? selectSJF(memClk) : selectRR(memClk);
}
else
bool success = selectSJF(memClk);
if (!success)
{
wait(newRequest);
}
}
else
{
// pick & drain a ready batch
isSJF ? selectSJF(memClk) : selectRR(memClk);
bool success = selectRR(memClk, select);
if (!success)
{
wait(newRequest);
}
}
}
}
@@ -136,16 +132,16 @@ bool SMS::selectSJF(sc_time memClk)
Thread thread = readybatch.first;
while (!buffer[thread].empty() && readybatch.second->addTransaction(buffer[thread].front()))
{
buffer[thread].pop_front();
buffer[thread].pop_front();
}
// marked as thread with non-empty ready batch
if (!readybatch.second->isEmpty()) {
if (!readybatch.second->isEmpty())
{
threadsWithNonEmptyReadybatches.push_back(readybatch.first);
}
}
}
if (!threadsWithNonEmptyReadybatches.empty())
{
// pick shortest-job thread among threads with non-empty ready batch
@@ -162,7 +158,8 @@ bool SMS::selectSJF(sc_time memClk)
// drain to bank buffers
std::deque<gp*> &requestPtrs = readybatches[minThread]->getTransactions();
for (auto payloadPtrIterator = requestPtrs.begin(); payloadPtrIterator != requestPtrs.end(); payloadPtrIterator++)
for (auto payloadPtrIterator = requestPtrs.begin(); payloadPtrIterator != requestPtrs.end();
payloadPtrIterator++)
{
Bank bank = DramExtension::getExtension(*payloadPtrIterator).getBank();
bankbuffer[bank].emplace_back(*payloadPtrIterator);
@@ -185,40 +182,62 @@ bool SMS::selectSJF(sc_time memClk)
}
void SMS::selectRR(sc_time memClk)
bool SMS::selectRR(sc_time memClk, std::map<Thread, ReadyBatch*>::iterator &select)
{
static std::map<Thread, ReadyBatch*>::iterator next = readybatches.begin();
if (existReadyBatch())
// pick a non-empty ready batch
std::map<Thread, ReadyBatch*>::iterator saved = select;
while ((*select).second->isEmpty())
{
while ((*next).second->isEmpty())
// form ready batch for this thread
Thread thread = (*select).first;
while (!buffer[thread].empty() && (*select).second->addTransaction(buffer[thread].front()))
{
next++;
if (next == readybatches.end())
buffer[thread].pop_front();
}
if ((*select).second->isEmpty())
{
// cannot form ready batch then move to next thread
select++;
if (select == readybatches.end())
{
next = readybatches.begin();
select = readybatches.begin();
}
if (select == saved)
{
// 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;
}
}
}
debugManager.printDebugMessage(name(),
"[RR] Select ready batch of thread " + to_string((*select).first.ID()));
// drain to bank buffers
std::deque<gp*> &requestPtrs = (*select).second->getTransactions();
for (auto payloadPtrIterator = requestPtrs.begin(); payloadPtrIterator != requestPtrs.end();
payloadPtrIterator++)
{
Bank bank = DramExtension::getExtension(*payloadPtrIterator).getBank();
bankbuffer[bank].emplace_back(*payloadPtrIterator);
debugManager.printDebugMessage(name(),
"[RR] Select ready batch of thread " + to_string((*next).first.ID()));
"[RR] Drained request in the ready batch of thread " + to_string((*select).first.ID())
+ " to bankbuffer " + to_string(bank.ID()));
wait(memClk);
}
requestPtrs.clear();
// drain to bank buffers
std::deque<gp*> &requestPtrs = (*next).second->getTransactions();
for (auto payloadPtrIterator = requestPtrs.begin(); payloadPtrIterator != requestPtrs.end(); payloadPtrIterator++)
{
Bank bank = DramExtension::getExtension(*payloadPtrIterator).getBank();
bankbuffer[bank].emplace_back(*payloadPtrIterator);
debugManager.printDebugMessage(name(),
"[RR] Drained request in the ready batch of thread " + to_string((*next).first.ID())
+ " to bankbuffer " + to_string(bank.ID()));
wait(memClk);
}
requestPtrs.clear();
// reform the drained ready batch
// batchFormation((*next).first);
// move the select iterator to the next one
select++;
if (select == readybatches.end())
{
select = readybatches.begin();
}
// a ready batch has been picked up & drained
return true;
}
bool SMS::existReadyBatch()

View File

@@ -57,7 +57,7 @@ private:
bool batchFormation();
bool selectSJF(sc_time memClk);
void selectRR(sc_time memClk);
bool selectRR(sc_time memClk, std::map<Thread, ReadyBatch*>::iterator &next);
bool existReadyBatch();
bool batchFormation(Thread thread);