Fix bug in RR & SJF selection functions
# Explain what has been changed # Explain why this change is being made # Provide links to any relevant tickets, articles or other resources
This commit is contained in:
@@ -18,8 +18,7 @@ ReadyBatch::~ReadyBatch()
|
||||
|
||||
Row ReadyBatch::getRow()
|
||||
{
|
||||
gp*& firstPayload = readybatch.front();
|
||||
return DramExtension::getExtension(firstPayload).getRow();
|
||||
return DramExtension::getExtension(readybatch.front()).getRow();
|
||||
}
|
||||
|
||||
//sc_time ReadyBatch::getTimeOfOldestRequest()
|
||||
|
||||
@@ -6,16 +6,7 @@ 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
|
||||
inFlightMemRequestCounter[DramExtension::getExtension(payload).getThread()]++;
|
||||
}
|
||||
|
||||
std::pair<Command, gp*> SMS::getNextRequest(Bank bank)
|
||||
@@ -40,16 +31,35 @@ 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::batchScheduler()
|
||||
{
|
||||
sc_time memClk = Configuration::getInstance().memSpec.clk;
|
||||
std::default_random_engine generator;
|
||||
std::bernoulli_distribution distribution((double) SJFprobability / 100.0);
|
||||
bool isSJF;
|
||||
|
||||
wait(150, SC_NS); // Test Purpose
|
||||
|
||||
while (true)
|
||||
{
|
||||
wait(memClk); //TODO: Is this correct???
|
||||
|
||||
isSJF = distribution(generator);
|
||||
if (!existReadyBatch())
|
||||
{
|
||||
// pick & drain a ready batch
|
||||
if (batchFormation())
|
||||
{
|
||||
isSJF ? selectSJF() : selectRR();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// pick & drain a ready batch
|
||||
isSJF ? selectSJF() : selectRR();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool SMS::batchFormation()
|
||||
{
|
||||
@@ -70,115 +80,6 @@ bool SMS::batchFormation()
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
while (true)
|
||||
{
|
||||
wait(memClk);
|
||||
|
||||
isSJF = distribution(generator);
|
||||
if (!existReadyBatch())
|
||||
{
|
||||
// pick & drain a ready batch
|
||||
if (batchFormation())
|
||||
{
|
||||
isSJF ? selectSJF() : selectRR();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// pick & drain a ready batch
|
||||
isSJF ? selectSJF() : selectRR();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SMS::selectSJF()
|
||||
{
|
||||
// find shorstest thread
|
||||
unsigned int minThread = 1;
|
||||
unsigned int totalNumThreads = Configuration::getInstance().NumberOfTracePlayers;
|
||||
for (unsigned int threadID = 2; threadID <= totalNumThreads; threadID++)
|
||||
{
|
||||
if (inFlightMemRequestCounter[Thread(threadID)] <= inFlightMemRequestCounter[Thread(minThread)])
|
||||
{
|
||||
minThread = threadID;
|
||||
}
|
||||
}
|
||||
|
||||
// drain to bank buffers
|
||||
std::deque<gp*> requestPtrs = readybatches[Thread(minThread)]->getTransactions();
|
||||
if (!requestPtrs.empty())
|
||||
{
|
||||
for (auto intr = requestPtrs.begin(); intr != requestPtrs.end(); intr++)
|
||||
{
|
||||
Bank bank = DramExtension::getExtension(*intr).getBank();
|
||||
bankbuffer[bank].emplace_back(*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();
|
||||
if (!requestPtrs.empty())
|
||||
{
|
||||
for (auto intr = requestPtrs.begin(); intr != requestPtrs.end(); intr++)
|
||||
{
|
||||
Bank bank = DramExtension::getExtension(*intr).getBank();
|
||||
bankbuffer[bank].emplace_back(*intr);
|
||||
}
|
||||
requestPtrs.clear();
|
||||
}
|
||||
|
||||
// reform the drained ready batch
|
||||
// batchFormation((*next).first);
|
||||
|
||||
// point to next pair
|
||||
if (existReadyBatch())
|
||||
{
|
||||
do
|
||||
{
|
||||
next++;
|
||||
if (next == readybatches.end())
|
||||
{
|
||||
next = readybatches.begin();
|
||||
}
|
||||
} while ((*next).second->isEmpty());
|
||||
}
|
||||
else
|
||||
{
|
||||
// point to next empty ready batch, later call to batchScheduler() will call batchFormation()
|
||||
// this next empty ready batch will be refilled
|
||||
next++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool SMS::existReadyBatch()
|
||||
{
|
||||
for (auto& thread_readybatch : readybatches)
|
||||
{
|
||||
if (!thread_readybatch.second->isEmpty())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SMS::batchFormation(Thread thread)
|
||||
{
|
||||
if (!readybatches[thread]->isEmpty())
|
||||
@@ -196,33 +97,85 @@ bool SMS::batchFormation(Thread thread)
|
||||
}
|
||||
}
|
||||
|
||||
//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);
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//void SMS::bypassLowMemoryIntensity()
|
||||
//{
|
||||
// unsigned int totalNumThreads = Configuration::getInstance().NumberOfTracePlayers;
|
||||
// for (unsigned int threadID = 1; threadID <= totalNumThreads; threadID++)
|
||||
// {
|
||||
// if (memoryIntensity[Thread(threadID)] < 1 && memoryIntensity[Thread(threadID)] > 0)
|
||||
// {
|
||||
// for (auto request = buffer[Thread(threadID)].begin();
|
||||
// request != buffer[Thread(threadID)].end(); request++)
|
||||
// {
|
||||
// Bank bank = DramExtension::getExtension(*request).getBank();
|
||||
// bankbuffer[bank].emplace_back(*request);
|
||||
// buffer[Thread(threadID)].erase(request);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
void SMS::selectSJF()
|
||||
{
|
||||
// find shorstest thread
|
||||
std::vector<Thread> threadsWithNonEmptyReadybatches;
|
||||
for (auto& readybatch : readybatches)
|
||||
{
|
||||
if (!readybatch.second->isEmpty())
|
||||
{
|
||||
threadsWithNonEmptyReadybatches.push_back(readybatch.first);
|
||||
}
|
||||
}
|
||||
|
||||
if (!threadsWithNonEmptyReadybatches.empty())
|
||||
{
|
||||
Thread minThread = threadsWithNonEmptyReadybatches.front();
|
||||
for (auto& thread : threadsWithNonEmptyReadybatches)
|
||||
{
|
||||
if (inFlightMemRequestCounter[thread] <= inFlightMemRequestCounter[minThread])
|
||||
{
|
||||
minThread = thread;
|
||||
}
|
||||
}
|
||||
|
||||
// drain to bank buffers
|
||||
std::deque<gp*> &requestPtrs = readybatches[minThread]->getTransactions();
|
||||
for (auto payloadPtrIterator = requestPtrs.begin(); payloadPtrIterator != requestPtrs.end(); payloadPtrIterator++)
|
||||
{
|
||||
Bank bank = DramExtension::getExtension(*payloadPtrIterator).getBank();
|
||||
bankbuffer[bank].emplace_back(*payloadPtrIterator);
|
||||
}
|
||||
requestPtrs.clear();
|
||||
|
||||
// reform the drained ready batch
|
||||
// batchFormation(Thread(minThread));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SMS::selectRR()
|
||||
{
|
||||
static std::map<Thread, ReadyBatch*>::iterator next = readybatches.begin();
|
||||
|
||||
if (existReadyBatch())
|
||||
{
|
||||
while ((*next).second->isEmpty())
|
||||
{
|
||||
next++;
|
||||
if (next == readybatches.end())
|
||||
{
|
||||
next = readybatches.begin();
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
requestPtrs.clear();
|
||||
|
||||
// reform the drained ready batch
|
||||
// batchFormation((*next).first);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool SMS::existReadyBatch()
|
||||
{
|
||||
for (auto& thread_readybatch : readybatches)
|
||||
{
|
||||
if (!thread_readybatch.second->isEmpty())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -23,15 +23,14 @@ public:
|
||||
unsigned int totalNumThreads = Configuration::getInstance().NumberOfTracePlayers;
|
||||
for (unsigned int threadID = 1; threadID <= totalNumThreads; threadID++)
|
||||
{
|
||||
// memrequestcounter.emplace(Thread(threadID), 0);
|
||||
// memoryIntensity.emplace(Thread(threadID), 0);
|
||||
inFlightMemRequestCounter.emplace(Thread(threadID), 0);
|
||||
readybatches[Thread(threadID)] = new ReadyBatch();
|
||||
}
|
||||
SC_THREAD(batchScheduler);
|
||||
}
|
||||
SC_HAS_PROCESS(SMS);
|
||||
virtual ~SMS()
|
||||
|
||||
~SMS()
|
||||
{
|
||||
unsigned int totalNumThreads = Configuration::getInstance().NumberOfTracePlayers;
|
||||
for (unsigned int threadID = 1; threadID <= totalNumThreads; threadID++)
|
||||
@@ -39,27 +38,24 @@ public:
|
||||
delete readybatches[Thread(threadID)];
|
||||
}
|
||||
}
|
||||
|
||||
virtual void schedule(gp *payload) override;
|
||||
virtual std::pair<Command, gp*> getNextRequest(Bank bank) override;
|
||||
|
||||
void batchScheduler();
|
||||
|
||||
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;
|
||||
|
||||
// unsigned int totalMemoryRequests();
|
||||
bool batchFormation();
|
||||
void selectSJF();
|
||||
void selectRR();
|
||||
bool existReadyBatch();
|
||||
bool batchFormation(Thread thread);
|
||||
// void bypassRequests();
|
||||
// void bypassLowMemoryIntensity();
|
||||
};
|
||||
|
||||
#endif // SMS_H
|
||||
|
||||
Reference in New Issue
Block a user