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:
@@ -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()
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user