1st implementation SMS batch scheduler
This commit is contained in:
@@ -41,3 +41,13 @@ bool ReadyBatch::addTransaction(gp* payload)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
std::deque<gp*>& ReadyBatch::getTransactions()
|
||||
{
|
||||
return readybatch;
|
||||
}
|
||||
|
||||
bool ReadyBatch::isEmpty()
|
||||
{
|
||||
return readybatch.empty();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user