From 55d36d60c27eec3cf85e73043dc5eb89c893ac4a Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Sat, 29 Apr 2017 11:19:06 +0200 Subject: [PATCH] Fix SelectRR & batch scheduler 1. Form new batch for thread with empty ready batch 2. Return boolean indicate successful selectRR --- .../src/controller/scheduler/SMS.cpp | 101 +++++++++++------- .../simulator/src/controller/scheduler/SMS.h | 2 +- 2 files changed, 61 insertions(+), 42 deletions(-) diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index 9cacaef8..06d53552 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -40,31 +40,27 @@ 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; + std::map::iterator select = readybatches.begin(); wait(150, SC_NS); // Test Purpose while (true) { -// wait(memClk); //TODO: Is this correct??? - - isSJF = distribution(generator); - if (!existReadyBatch()) + if (distribution(generator)) { - // pick & drain a ready batch - if (batchFormation()) - { - isSJF ? selectSJF(memClk) : selectRR(memClk); - } - else + bool success = selectSJF(memClk); + if (!success) { wait(newRequest); } } else { - // pick & drain a ready batch - isSJF ? selectSJF(memClk) : selectRR(memClk); + bool success = selectRR(memClk, select); + if (!success) + { + wait(newRequest); + } } } } @@ -136,16 +132,16 @@ bool SMS::selectSJF(sc_time memClk) Thread thread = readybatch.first; while (!buffer[thread].empty() && readybatch.second->addTransaction(buffer[thread].front())) { - buffer[thread].pop_front(); + buffer[thread].pop_front(); } // marked as thread with non-empty ready batch - if (!readybatch.second->isEmpty()) { + if (!readybatch.second->isEmpty()) + { threadsWithNonEmptyReadybatches.push_back(readybatch.first); } } } - if (!threadsWithNonEmptyReadybatches.empty()) { // pick shortest-job thread among threads with non-empty ready batch @@ -162,7 +158,8 @@ bool SMS::selectSJF(sc_time memClk) // drain to bank buffers std::deque &requestPtrs = readybatches[minThread]->getTransactions(); - for (auto payloadPtrIterator = requestPtrs.begin(); payloadPtrIterator != requestPtrs.end(); payloadPtrIterator++) + for (auto payloadPtrIterator = requestPtrs.begin(); payloadPtrIterator != requestPtrs.end(); + payloadPtrIterator++) { Bank bank = DramExtension::getExtension(*payloadPtrIterator).getBank(); bankbuffer[bank].emplace_back(*payloadPtrIterator); @@ -185,40 +182,62 @@ bool SMS::selectSJF(sc_time memClk) } -void SMS::selectRR(sc_time memClk) +bool SMS::selectRR(sc_time memClk, std::map::iterator &select) { - static std::map::iterator next = readybatches.begin(); - - if (existReadyBatch()) + // pick a non-empty ready batch + std::map::iterator saved = select; + while ((*select).second->isEmpty()) { - while ((*next).second->isEmpty()) + // form ready batch for this thread + Thread thread = (*select).first; + while (!buffer[thread].empty() && (*select).second->addTransaction(buffer[thread].front())) { - next++; - if (next == readybatches.end()) + buffer[thread].pop_front(); + } + + if ((*select).second->isEmpty()) + { + // cannot form ready batch then move to next thread + select++; + if (select == readybatches.end()) { - next = readybatches.begin(); + select = readybatches.begin(); + } + + if (select == saved) + { + // the next thread is the original thread, that mean req buffer are totally empty + // non-existed ready batch to be picked up & drained + return false; } } + } + debugManager.printDebugMessage(name(), + "[RR] Select ready batch of thread " + to_string((*select).first.ID())); + + // drain to bank buffers + std::deque &requestPtrs = (*select).second->getTransactions(); + for (auto payloadPtrIterator = requestPtrs.begin(); payloadPtrIterator != requestPtrs.end(); + payloadPtrIterator++) + { + Bank bank = DramExtension::getExtension(*payloadPtrIterator).getBank(); + bankbuffer[bank].emplace_back(*payloadPtrIterator); debugManager.printDebugMessage(name(), - "[RR] Select ready batch of thread " + to_string((*next).first.ID())); + "[RR] Drained request in the ready batch of thread " + to_string((*select).first.ID()) + + " to bankbuffer " + to_string(bank.ID())); + wait(memClk); + } + requestPtrs.clear(); - // drain to bank buffers - std::deque &requestPtrs = (*next).second->getTransactions(); - for (auto payloadPtrIterator = requestPtrs.begin(); payloadPtrIterator != requestPtrs.end(); payloadPtrIterator++) - { - Bank bank = DramExtension::getExtension(*payloadPtrIterator).getBank(); - bankbuffer[bank].emplace_back(*payloadPtrIterator); - debugManager.printDebugMessage(name(), - "[RR] Drained request in the ready batch of thread " + to_string((*next).first.ID()) - + " to bankbuffer " + to_string(bank.ID())); - wait(memClk); - } - requestPtrs.clear(); - - // reform the drained ready batch - // batchFormation((*next).first); + // move the select iterator to the next one + select++; + if (select == readybatches.end()) + { + select = readybatches.begin(); } + // a ready batch has been picked up & drained + return true; } bool SMS::existReadyBatch() diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h index 590aa4ad..e9ad838a 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.h +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h @@ -57,7 +57,7 @@ private: bool batchFormation(); bool selectSJF(sc_time memClk); - void selectRR(sc_time memClk); + bool selectRR(sc_time memClk, std::map::iterator &next); bool existReadyBatch(); bool batchFormation(Thread thread);