From 56fe13dbce04597b0b1274302f8f499b9cc11558 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Fri, 3 Sep 2021 14:25:26 +0200 Subject: [PATCH] Add flexible same-bank refresh management. --- .../library/src/controller/BankMachine.cpp | 15 ++- DRAMSys/library/src/controller/BankMachine.h | 7 +- .../powerdown/PowerDownManagerStaggered.cpp | 2 +- .../refresh/RefreshManagerPerBank.cpp | 4 +- .../refresh/RefreshManagerSameBank.cpp | 113 ++++++++++++------ .../refresh/RefreshManagerSameBank.h | 2 + .../controller/scheduler/SchedulerFrFcfs.cpp | 2 +- .../scheduler/SchedulerFrFcfsGrp.cpp | 2 +- 8 files changed, 94 insertions(+), 53 deletions(-) diff --git a/DRAMSys/library/src/controller/BankMachine.cpp b/DRAMSys/library/src/controller/BankMachine.cpp index 1b238d08..307b23f4 100644 --- a/DRAMSys/library/src/controller/BankMachine.cpp +++ b/DRAMSys/library/src/controller/BankMachine.cpp @@ -140,16 +140,21 @@ Row BankMachine::getOpenRow() const return openRow; } -BankMachine::State BankMachine::getState() const -{ - return state; -} - bool BankMachine::isIdle() const { return (currentPayload == nullptr); } +bool BankMachine::isActivated() const +{ + return state == State::Activated; +} + +bool BankMachine::isPrecharged() const +{ + return state == State::Precharged; +} + BankMachineOpen::BankMachineOpen(SchedulerIF *scheduler, CheckerIF *checker, Bank bank) : BankMachine(scheduler, checker, bank) {} diff --git a/DRAMSys/library/src/controller/BankMachine.h b/DRAMSys/library/src/controller/BankMachine.h index 5dbae1ca..898e8555 100644 --- a/DRAMSys/library/src/controller/BankMachine.h +++ b/DRAMSys/library/src/controller/BankMachine.h @@ -52,24 +52,23 @@ public: void updateState(Command); void block(); - enum class State {Precharged, Activated}; - Rank getRank() const; BankGroup getBankGroup() const; Bank getBank() const; Row getOpenRow() const; - State getState() const; bool isIdle() const; + bool isActivated() const; + bool isPrecharged() const; uint64_t getRefreshManagementCounter() const; protected: + enum class State {Precharged, Activated} state = State::Precharged; BankMachine(SchedulerIF *, CheckerIF *, Bank); const MemSpec* memSpec; tlm::tlm_generic_payload *currentPayload = nullptr; SchedulerIF *scheduler; CheckerIF *checker; Command nextCommand = Command::NOP; - State state = State::Precharged; Row openRow; sc_core::sc_time timeToSchedule = sc_core::sc_max_time(); Rank rank = Rank(0); diff --git a/DRAMSys/library/src/controller/powerdown/PowerDownManagerStaggered.cpp b/DRAMSys/library/src/controller/powerdown/PowerDownManagerStaggered.cpp index 665cec9e..b7a36bb1 100644 --- a/DRAMSys/library/src/controller/powerdown/PowerDownManagerStaggered.cpp +++ b/DRAMSys/library/src/controller/powerdown/PowerDownManagerStaggered.cpp @@ -99,7 +99,7 @@ sc_time PowerDownManagerStaggered::start() nextCommand = Command::PDEP; for (auto it : bankMachinesOnRank) { - if (it->getState() == BankMachine::State::Activated) + if (it->isActivated()) { nextCommand = Command::PDEA; break; diff --git a/DRAMSys/library/src/controller/refresh/RefreshManagerPerBank.cpp b/DRAMSys/library/src/controller/refresh/RefreshManagerPerBank.cpp index 5f335097..780fb845 100644 --- a/DRAMSys/library/src/controller/refresh/RefreshManagerPerBank.cpp +++ b/DRAMSys/library/src/controller/refresh/RefreshManagerPerBank.cpp @@ -117,7 +117,7 @@ sc_time RefreshManagerPerBank::start() } else { - if (currentBankMachine->getState() == BankMachine::State::Activated) + if (currentBankMachine->isActivated()) nextCommand = Command::PRE; else { @@ -158,7 +158,7 @@ sc_time RefreshManagerPerBank::start() } else { - if (currentBankMachine->getState() == BankMachine::State::Activated) + if (currentBankMachine->isActivated()) nextCommand = Command::PRE; else nextCommand = Command::REFB; diff --git a/DRAMSys/library/src/controller/refresh/RefreshManagerSameBank.cpp b/DRAMSys/library/src/controller/refresh/RefreshManagerSameBank.cpp index 21505a29..d8de04c4 100644 --- a/DRAMSys/library/src/controller/refresh/RefreshManagerSameBank.cpp +++ b/DRAMSys/library/src/controller/refresh/RefreshManagerSameBank.cpp @@ -73,6 +73,8 @@ RefreshManagerSameBank::RefreshManagerSameBank(std::vector &bankM maxPostponed = static_cast(config.refreshMaxPostponed * memSpec->banksPerGroup); maxPulledin = -static_cast(config.refreshMaxPulledin * memSpec->banksPerGroup); + + refreshManagement = config.refreshManagement; } CommandTuple::Type RefreshManagerSameBank::getNextCommand() @@ -102,7 +104,7 @@ sc_time RefreshManagerSameBank::start() if (state == State::Regular) { bool forcedRefresh = (flexibilityCounter == maxPostponed); - bool allBanksBusy = true; + bool allGroupsBusy = true; if (!skipSelection) { @@ -120,31 +122,31 @@ sc_time RefreshManagerSameBank::start() } if (!groupIsBusy) { - allBanksBusy = false; + allGroupsBusy = false; currentIterator = bankIt; break; } } } - if (allBanksBusy && !forcedRefresh) + if (allGroupsBusy && !forcedRefresh) { flexibilityCounter++; timeForNextTrigger += memSpec->getRefreshIntervalSB(); - return timeForNextTrigger; } else { nextCommand = Command::REFSB; for (auto it : *currentIterator) { - if (it->getState() == BankMachine::State::Activated) + if (it->isActivated()) { nextCommand = Command::PRESB; break; } } + // only check for forced refresh, also block for PRESB if (nextCommand == Command::REFSB && forcedRefresh) { for (auto it : *currentIterator) @@ -159,7 +161,7 @@ sc_time RefreshManagerSameBank::start() } else // if (state == RmState::Pulledin) { - bool allBanksBusy = true; + bool allGroupsBusy = true; currentIterator = remainingBankMachines.begin(); for (auto bankIt = remainingBankMachines.begin(); bankIt != remainingBankMachines.end(); bankIt++) @@ -175,24 +177,23 @@ sc_time RefreshManagerSameBank::start() } if (!groupIsBusy) { - allBanksBusy = false; + allGroupsBusy = false; currentIterator = bankIt; break; } } - if (allBanksBusy) + if (allGroupsBusy) { state = State::Regular; timeForNextTrigger += memSpec->getRefreshIntervalSB(); - return timeForNextTrigger; } else { nextCommand = Command::REFSB; for (auto it : *currentIterator) { - if (it->getState() == BankMachine::State::Activated) + if (it->isActivated()) { nextCommand = Command::PRESB; break; @@ -205,49 +206,83 @@ sc_time RefreshManagerSameBank::start() } } } - else + + if (refreshManagement) { - bool RFMRequired = false; - if (Configuration::getInstance().refreshManagement == true) + bool mmtReached = false; + std::vector>::iterator> imtCandidates; + + for (auto bankIt = allBankMachines.begin(); bankIt != allBankMachines.end(); bankIt++) { - for (auto bankIt = allBankMachines.begin(); bankIt != allBankMachines.end(); bankIt++) + for (auto groupIt: *bankIt) { - for (auto bm : *bankIt) + if (groupIt->getRefreshManagementCounter() >= memSpec->getRAAMMT()) { - uint64_t threshold = memSpec->getRAAIMT() * memSpec->getRAAMMT(); - if (bm->getRefreshManagementCounter() >= threshold) + mmtReached = true; + currentIterator = bankIt; + break; + } + else if (groupIt->getRefreshManagementCounter() >= memSpec->getRAAMMT()) + { + imtCandidates.emplace_back(currentIterator); + } + } + } + + if (mmtReached) + { + nextCommand = Command::RFMSB; + for (auto groupIt: *currentIterator) + { + groupIt->block(); + if (groupIt->isActivated()) + nextCommand = Command::PRESB; + } + timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, + &refreshPayloads[currentIterator->front()->getBank().ID() % memSpec->banksPerGroup]); + return timeToSchedule; + } + else if (!imtCandidates.empty()) + { + // search for IMT candidates and check if all banks idle + bool allGroupsBusy = true; + for (auto candidateIt: imtCandidates) + { + bool groupIsBusy = false; + for (auto groupIt: *candidateIt) + { + if (!groupIt->isIdle()) { - RFMRequired = true; - currentIterator = bankIt; + groupIsBusy = true; break; } } - } - } - - if (RFMRequired) - { - nextCommand = Command::RFMSB; - for (auto it : *currentIterator) - { - if (it->getState() == BankMachine::State::Activated) + if (!groupIsBusy) { - nextCommand = Command::PRESB; + allGroupsBusy = false; + currentIterator = candidateIt; break; } } - - for (auto it : *currentIterator) - it->block(); - - timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, &refreshPayloads[currentIterator->front()->getBank().ID() % memSpec->banksPerGroup]); - return timeToSchedule; - } - else - { - return timeForNextTrigger; + if (!allGroupsBusy) + { + nextCommand = Command::RFMSB; + for (auto it: *currentIterator) + { + if (it->isActivated()) + { + nextCommand = Command::PRESB; + break; + } + } + timeToSchedule = checker->timeToSatisfyConstraints(nextCommand, + &refreshPayloads[currentIterator->front()->getBank().ID() % memSpec->banksPerGroup]); + return timeToSchedule; + } } } + + return timeForNextTrigger; } void RefreshManagerSameBank::updateState(Command command) diff --git a/DRAMSys/library/src/controller/refresh/RefreshManagerSameBank.h b/DRAMSys/library/src/controller/refresh/RefreshManagerSameBank.h index 5d1921f3..dfe76064 100644 --- a/DRAMSys/library/src/controller/refresh/RefreshManagerSameBank.h +++ b/DRAMSys/library/src/controller/refresh/RefreshManagerSameBank.h @@ -74,6 +74,8 @@ private: bool sleeping = false; bool skipSelection = false; + + bool refreshManagement = false; }; #endif // REFRESHMANAGERSAMEBANK_H diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp index 273a1e99..23f6046e 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp @@ -88,7 +88,7 @@ tlm_generic_payload *SchedulerFrFcfs::getNextRequest(BankMachine *bankMachine) c unsigned bankID = bankMachine->getBank().ID(); if (!buffer[bankID].empty()) { - if (bankMachine->getState() == BankMachine::State::Activated) + if (bankMachine->isActivated()) { // Search for row hit Row openRow = bankMachine->getOpenRow(); diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.cpp b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.cpp index e09ebc98..16177905 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.cpp +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.cpp @@ -89,7 +89,7 @@ tlm_generic_payload *SchedulerFrFcfsGrp::getNextRequest(BankMachine *bankMachine unsigned bankID = bankMachine->getBank().ID(); if (!buffer[bankID].empty()) { - if (bankMachine->getState() == BankMachine::State::Activated) + if (bankMachine->isActivated()) { // Filter all row hits Row openRow = bankMachine->getOpenRow();