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:
Thanh C. Tran
2017-03-22 12:44:33 +01:00
parent ba39c9443b
commit 3521cafa81
3 changed files with 117 additions and 169 deletions

View File

@@ -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()

View File

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

View File

@@ -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