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

@@ -41,3 +41,13 @@ bool ReadyBatch::addTransaction(gp* payload)
return true;
}
}
std::deque<gp*>& ReadyBatch::getTransactions()
{
return readybatch;
}
bool ReadyBatch::isEmpty()
{
return readybatch.empty();
}

View File

@@ -14,6 +14,9 @@ class ReadyBatch
public:
ReadyBatch();
bool addTransaction(gp* payload);
unsigned int getNumRequests();
std::deque<gp*>& getTransactions();
bool isEmpty();
private:
std::deque<gp*> readybatch;
unsigned int fifosize;
@@ -21,7 +24,6 @@ private:
Row getRow();
sc_time getTimeOfOldestRequest();
unsigned int getNumRequests();
};
#endif // READYBATCH_H

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);
}
}
}

View File

@@ -1,17 +1,31 @@
#ifndef SMS_H
#define SMS_H
#include <stdlib.h>
#include <time.h>
#include "sysc/utils/sc_report.h"
#include "IScheduler.h"
#include "../core/ControllerCore.h"
#include "../core/configuration/Configuration.h"
#include "../../common/dramExtension.h"
#define MIN_TOTAL_REQ 16
using namespace std;
class SMS: public sc_module, public IScheduler
{
public:
SMS(ControllerCore &controllerCore, unsigned int SJFprobability) : IScheduler(controllerCore), SJFprobability(SJFprobability){}
SMS(ControllerCore &controllerCore, unsigned int SJFprobability) : IScheduler(controllerCore), SJFprobability(SJFprobability)
{
// initialize memory request counter & memory request intensity for each thread
auto totalNumThreads = Configuration::getInstance().NumberOfTracePlayers;
for (auto threadID = 1; threadID <= totalNumThreads; threadID++)
{
memrequestcounter.emplace(Thread(threadID), 0);
memoryIntensity.emplace(Thread(threadID), 0);
}
}
virtual ~SMS(){}
virtual void schedule(gp *payload) override;
virtual std::pair<Command, gp*> getNextRequest(Bank bank) override;
@@ -19,8 +33,20 @@ public:
private:
std::map<Thread, std::deque<gp*>> buffer;
std::map<Bank, std::deque<gp*>> bankbuffer;
std::map<Thread, ReadyBatch*> readybatches;
std::map<Thread, unsigned int> memrequestcounter;
std::map<Thread, unsigned int> inFlightMemRequestCounter;
std::map<Thread, float> memoryIntensity;
unsigned int SJFprobability;
void batchScheduler();
unsigned int totalMemoryRequests();
void batchFormation();
void selectSJF();
void selectRR();
bool existReadyBatch();
void batchFormation(Thread thread);
void bypassRequests();
};
#endif // SMS_H