1st implementation SMS batch scheduler
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user