1st implementation SMS batch scheduler

This commit is contained in:
Thanh C. Tran
2017-03-01 17:22:01 +01:00
parent 413916f402
commit df9368b1fd
4 changed files with 211 additions and 3 deletions

View File

@@ -5,6 +5,16 @@ using namespace std;
void SMS::schedule(gp *payload)
{
buffer[DramExtension::getExtension(payload).getThread()].emplace_back(payload);
Thread thread = DramExtension::getExtension(payload).getThread();
// update memory request counter
memrequestcounter[thread]++;
inFlightMemRequestCounter[thread]++;
// update memory request intensity
sc_time lastrequestTimeOfGeneration = GenerationExtension::getExtension(payload).TimeOfGeneration();
sc_time memClk = Configuration::getInstance().memSpec.clk;
memoryIntensity[thread] = (memrequestcounter[thread] * 1000.0 * memClk) / lastrequestTimeOfGeneration; // in MPKC
}
std::pair<Command, gp*> SMS::getNextRequest(Bank bank)
@@ -20,6 +30,7 @@ std::pair<Command, gp*> SMS::getNextRequest(Bank bank)
if (command == Command::Read || command == Command::ReadA || command == Command::Write
|| command == Command::WriteA)
{
inFlightMemRequestCounter[DramExtension::getExtension(payload).getThread()]--;
bankbuffer[bank].pop_front();
}
@@ -27,3 +38,162 @@ std::pair<Command, gp*> SMS::getNextRequest(Bank bank)
}
}
unsigned int SMS::totalMemoryRequests()
{
//TODO: recheck this? how about total in-flight requests instead?
unsigned int totalSize = 0;
for (auto &reqQueue : buffer)
{
totalSize += reqQueue.second.size();
}
return totalSize;
}
void SMS::batchFormation()
{
if (existReadyBatch())
{
SC_REPORT_FATAL("SMS", "Form ready batches when exist at least a ready batch");
}
else
{
auto totalNumThreads = Configuration::getInstance().NumberOfTracePlayers;
for (auto threadID = 1; threadID <= totalNumThreads; threadID++)
{
batchFormation(Thread(threadID));
}
}
}
void SMS::batchScheduler()
{
while (true)
{
srand(time(NULL));
bool isSJF = (rand() % 100) < SJFprobability;
if (!existReadyBatch())
{
// bypass low memory intensity thread
// bypass if system is lightly load
if (totalMemoryRequests() <= 16 && totalMemoryRequests() > 0) //TODO how about buffer empty?
{
bypassRequests();
}
else
{
batchFormation();
if (isSJF)
{
selectSJF()
}
else
{
selectRR();
}
}
}
else if (isSJF)
{
selectSJF()
}
else
{
selectRR();
}
}
}
void SMS::selectSJF()
{
// find shorstest thread
unsigned int minThread = 1
auto totalNumThreads = Configuration::getInstance().NumberOfTracePlayers;
for (auto threadID = 2; threadID <= totalNumThreads; threadID++)
{
if (memrequestcounter[Thread(threadID)] <= memrequestcounter[Thread(minThread)])
{
minThread = threadID;
}
}
// drain to bank buffers
std::deque<gp*> requestPtrs = readybatches[Thread(minThread)]->getTransactions();
for (auto intr = requestPtrs.begin(); intr != requestPtrs.end(); intr++)
{
Bank bank = DramExtension::getExtension(*intr).getBank();
bankbuffer.emplace(bank, *intr);
}
requestPtrs.clear();
// reform the drained ready batch
// batchFormation(Thread(minThread));
}
void SMS::selectRR()
{
static std::map<Thread, ReadyBatch*>::iterator next = readybatches.begin();
// drain to bank buffers
std::deque<gp*> requestPtrs = (*next).second->getTransactions();
for (auto intr = requestPtrs.begin(); intr != requestPtrs.end(); intr++)
{
Bank bank = DramExtension::getExtension(*intr).getBank();
bankbuffer.emplace(bank, *intr);
}
requestPtrs.clear();
// reform the drained ready batch
// batchFormation((*next).first);
// point to next pair
do
{
next++;
if (next == readybatches.end())
{
next = readybatches.begin();
}
} while ((*next).second->isEmpty());
}
bool SMS::existReadyBatch()
{
for (auto& thread_readybatch : readybatches)
{
if (!thread_readybatch.second->isEmpty())
{
return true;
}
}
return false;
}
void SMS::batchFormation(Thread thread)
{
if (!readybatches[thread]->isEmpty())
{
SC_REPORT_FATAL("SMS", "Ready batch formation for non empty ready batch");
}
else
{
while (!buffer[thread].empty() && readybatches[thread]->addTransaction(buffer[thread].front()))
{
buffer[thread].pop_front();
}
}
}
void SMS::bypassRequests()
{
for(auto& thread_requests : buffer)
{
for(auto request = thread_requests.second.begin(); request != thread_requests.second.end(); request++)
{
Bank bank = DramExtension::getExtension(*request).getBank();
bankbuffer[bank].emplace_back(request);
thread_requests.second.erase(request);
}
}
}