diff --git a/dram/.settings/language.settings.xml b/dram/.settings/language.settings.xml index 127cd8ac..278289a3 100644 --- a/dram/.settings/language.settings.xml +++ b/dram/.settings/language.settings.xml @@ -4,7 +4,7 @@ - + diff --git a/dram/resources/configs/memconfigs/memconfig.xml b/dram/resources/configs/memconfigs/memconfig.xml index ba84ec9e..0e118b41 100644 --- a/dram/resources/configs/memconfigs/memconfig.xml +++ b/dram/resources/configs/memconfigs/memconfig.xml @@ -3,9 +3,9 @@ - + - + diff --git a/dram/resources/scripts/metrics.py b/dram/resources/scripts/metrics.py index f1081033..f771a292 100644 --- a/dram/resources/scripts/metrics.py +++ b/dram/resources/scripts/metrics.py @@ -35,7 +35,7 @@ def getTraceLength(connection): @metric def average_response_latency_in_ns(connection): cursor = connection.cursor() - cursor.execute("""SELECT avg(ranges.end-ranges.begin)/1000 FROM transactions INNER JOIN ranges + cursor.execute("""SELECT avg(transactions.DataStrobeEnd-ranges.begin)/1000 FROM transactions INNER JOIN ranges ON transactions.range = ranges.ID where TThread != 0""") result = cursor.fetchone() @@ -44,7 +44,7 @@ def average_response_latency_in_ns(connection): @threadMetric def average_response_latency_in_ns(connection, thread): cursor = connection.cursor() - query = """SELECT avg(ranges.end-ranges.begin)/1000 FROM transactions INNER JOIN ranges + query = """SELECT avg(transactions.DataStrobeEnd-ranges.begin)/1000 FROM transactions INNER JOIN ranges ON transactions.range = ranges.ID where TThread = :Thread """ cursor.execute(query, {"Thread": thread}) diff --git a/dram/src/common/dramExtension.cpp b/dram/src/common/dramExtension.cpp index 591ec8ab..3697c95f 100644 --- a/dram/src/common/dramExtension.cpp +++ b/dram/src/common/dramExtension.cpp @@ -29,6 +29,12 @@ bool operator !=(const Thread& lhs, const Thread& rhs) return !(lhs == rhs); } +bool operator <(const Thread& lhs, const Thread& rhs) +{ + return lhs.ID() < rhs.ID(); +} + + bool operator ==(const Channel& lhs, const Channel& rhs) { return lhs.ID() == rhs.ID(); @@ -88,3 +94,4 @@ bool operator !=(const Column& lhs, const Column& rhs) { return !(lhs == rhs); } + diff --git a/dram/src/common/dramExtension.h b/dram/src/common/dramExtension.h index 9bbf4b04..a8556607 100644 --- a/dram/src/common/dramExtension.h +++ b/dram/src/common/dramExtension.h @@ -78,6 +78,7 @@ private: bool operator==(const Thread &lhs, const Thread &rhs); bool operator!=(const Thread &lhs, const Thread &rhs); +bool operator<(const Thread &lhs, const Thread &rhs); bool operator==(const Channel &lhs, const Channel &rhs); bool operator!=(const Channel &lhs, const Channel &rhs); diff --git a/dram/src/scheduler/Fifo.cpp b/dram/src/scheduler/Fifo.cpp index 26c142f3..b89648f6 100644 --- a/dram/src/scheduler/Fifo.cpp +++ b/dram/src/scheduler/Fifo.cpp @@ -29,7 +29,8 @@ gp* Fifo::getTransactionForBank(Bank bank) void Fifo::popTransactionForBank(Bank bank, gp* payload) { - sc_assert(hasTransactionForBank(bank)); + sc_assert(DramExtension::getExtension(payload).getBank() == bank); + buffer[bank].pop_front(); } diff --git a/dram/src/scheduler/Fr_Fcfs.cpp b/dram/src/scheduler/Fr_Fcfs.cpp index 4bdfd740..e59bef5a 100644 --- a/dram/src/scheduler/Fr_Fcfs.cpp +++ b/dram/src/scheduler/Fr_Fcfs.cpp @@ -8,8 +8,8 @@ using namespace core; namespace scheduler { -FR_FCFS::FR_FCFS(core::ControllerCore& controller, bool refreshAware, bool adaptiveOpenPage) : - controllerBankstates(controller.state.bankStates), refreshAware(refreshAware), adaptiveOpenPage( +FR_FCFS::FR_FCFS(const core::BankStates& bankstates, bool useExternalStates, bool adaptiveOpenPage) : + externalBankstates(bankstates), useExternalStates(useExternalStates), adaptiveOpenPage( adaptiveOpenPage) { } @@ -23,16 +23,34 @@ bool FR_FCFS::hasTransactionForBank(Bank bank) return !buffer[bank].empty(); } + +bool FR_FCFS::isEmpty() +{ + for(unsigned int i = 0; i < Configuration::getInstance().NumberOfBanks;++i) + { + if(!buffer[Bank(i)].empty()) + return false; + } + return true; +} + void FR_FCFS::schedule(gp* payload) { buffer[DramExtension::getExtension(payload).getBank()].emplace_back(payload); } + +void FR_FCFS::schedule(std::vector payloads) +{ + for(gp* payload: payloads) + schedule(payload); +} + gp* FR_FCFS::getTransactionForBank(Bank bank) { sc_assert(hasTransactionForBank(bank)); - Row openRowOnBank = (refreshAware) ? controllerBankstates.getRowInRowBuffer(bank) : internalBankstates.getRowInRowBuffer(bank); + Row openRowOnBank = (useExternalStates) ? externalBankstates.getRowInRowBuffer(bank) : internalBankstates.getRowInRowBuffer(bank); auto rowHits = findRowHits(bank, openRowOnBank); gp* result = rowHits.empty() ? buffer[bank].front() : rowHits.front(); @@ -65,6 +83,15 @@ gp* FR_FCFS::getTransactionForBank(Bank bank) } } +gp* FR_FCFS::popOldest(Bank bank) +{ + assert(hasTransactionForBank(bank)); + + gp* result = buffer[bank].front(); + buffer[bank].pop_front(); + return result; +} + std::vector FR_FCFS::findRowHits(Bank bank, Row row) { vector found; @@ -78,11 +105,11 @@ std::vector FR_FCFS::findRowHits(Bank bank, Row row) void FR_FCFS::popTransactionForBank(Bank bank, gp* payload) { - sc_assert( - hasTransactionForBank(bank) && bank == DramExtension::getExtension(payload).getBank()); + sc_assert(DramExtension::getExtension(payload).getBank() == bank); + buffer[bank].remove(payload); - if (!refreshAware) + if (!useExternalStates) { internalBankstates.openRowInRowBuffer(bank, DramExtension::getExtension(payload).getRow()); } diff --git a/dram/src/scheduler/Fr_Fcfs.h b/dram/src/scheduler/Fr_Fcfs.h index f8473ee1..8e166b51 100644 --- a/dram/src/scheduler/Fr_Fcfs.h +++ b/dram/src/scheduler/Fr_Fcfs.h @@ -5,13 +5,14 @@ #include "../core/ControllerCore.h" #include #include +#include namespace scheduler { class FR_FCFS : public Scheduler { public: - FR_FCFS(core::ControllerCore& controller,bool refreshAware, bool adaptiveOpenPage); + FR_FCFS(const core::BankStates& bankstates, bool refreshAware, bool adaptiveOpenPage); virtual ~FR_FCFS(); virtual bool hasTransactionForBank(Bank bank) override; @@ -19,12 +20,17 @@ public: virtual gp* getTransactionForBank(Bank bank) override; virtual void popTransactionForBank(Bank bank, gp* payload) override; + //used by PAR_BS + void schedule (std::vector payloads); + gp* popOldest(Bank bank); + bool isEmpty(); + private: std::vector findRowHits(Bank bank, Row row); std::map> buffer; - const core::BankStates& controllerBankstates; + const core::BankStates& externalBankstates; core::BankStates internalBankstates; - bool refreshAware; + bool useExternalStates; bool adaptiveOpenPage; }; diff --git a/dram/src/scheduler/PARBS.cpp b/dram/src/scheduler/PARBS.cpp new file mode 100644 index 00000000..7e357870 --- /dev/null +++ b/dram/src/scheduler/PARBS.cpp @@ -0,0 +1,113 @@ +/* + * PARBS.cpp + * + * Created on: Apr 9, 2014 + * Author: robert + */ + +#include "PARBS.h" +#include "../core/configuration/Configuration.h" +#include "../common/dramExtension.h" +#include "map" +#include "ThreadLoad.h" +#include + +namespace scheduler { + +using namespace std; +using namespace core; + +PAR_BS::PAR_BS(const core::BankStates& bankstates, bool useExternalBankstates, unsigned int capsize) : + externalBankstates(bankstates), useExternalBankstates(useExternalBankstates), capsize(capsize) +{ + if (useExternalBankstates) + { + batch = new FR_FCFS(externalBankstates, true, false); + buffer = new FR_FCFS(externalBankstates, true, false); + } + else + { + batch = new FR_FCFS(internalBankstates, true, false); + buffer = new FR_FCFS(internalBankstates, true, false); + } +} + +PAR_BS::~PAR_BS() +{ + +} + +bool PAR_BS::hasTransactionForBank(Bank bank) +{ + return batch->hasTransactionForBank(bank) || buffer->hasTransactionForBank(bank); +} + +void PAR_BS::schedule(gp* payload) +{ + buffer->schedule(payload); +} + +gp* PAR_BS::getTransactionForBank(Bank bank) +{ + assert(hasTransactionForBank(bank)); + + if (batch->isEmpty()) + { + formBatch(); + sc_assert(!batch->isEmpty()); + } + + //prioritize batch first + if (batch->hasTransactionForBank(bank)) + { + return batch->getTransactionForBank(bank); + } + else + { + return buffer->getTransactionForBank(bank); + } +} + +void PAR_BS::popTransactionForBank(Bank bank, gp* payload) +{ + sc_assert(DramExtension::getExtension(payload).getBank() == bank); + buffer->popTransactionForBank(bank, payload); + batch->popTransactionForBank(bank, payload); + + if (!useExternalBankstates) + { + internalBankstates.openRowInRowBuffer(bank, DramExtension::getExtension(payload).getRow()); + } + +} + +void PAR_BS::formBatch() +{ + map loads; + + for (unsigned int b = 0; b < Configuration::getInstance().NumberOfBanks; ++b) + { + Bank bank(b); + for (unsigned int i = 0; i < capsize && buffer->hasTransactionForBank(bank); i++) + { + gp* payload = buffer->popOldest(bank); + loads[DramExtension::getExtension(payload).getThread()].addTransaction(payload); + } + } + + vector sortedLoads; + for (auto& threadLoadPair : loads) + { + sortedLoads.push_back(&threadLoadPair.second); + } + + sort(sortedLoads.begin(), sortedLoads.end(), LoadPointerComparer()); + + for (auto& load : sortedLoads) + { + batch->schedule(load->getTransactions()); + } + +} + +} /* namespace core */ diff --git a/dram/src/scheduler/PARBS.h b/dram/src/scheduler/PARBS.h new file mode 100644 index 00000000..19455285 --- /dev/null +++ b/dram/src/scheduler/PARBS.h @@ -0,0 +1,38 @@ +/* + * PARBS.h + * + * Created on: Apr 9, 2014 + * Author: robert + */ + +#ifndef PARBS_H_ +#define PARBS_H_ +#include "Scheduler.h" +#include "../core/ControllerCore.h" +#include "Fr_Fcfs.h" + +namespace scheduler { + +class PAR_BS : public Scheduler +{ +public: + PAR_BS(const core::BankStates& bankstates, bool useExternalBankstates, unsigned int capsize); + virtual ~PAR_BS(); + virtual bool hasTransactionForBank(Bank bank) override; + virtual void schedule(gp* payload) override; + virtual gp* getTransactionForBank(Bank bank) override; + virtual void popTransactionForBank(Bank bank, gp* payload) override; + +private: + void formBatch(); + bool useExternalBankstates; + const core::BankStates& externalBankstates; + core::BankStates internalBankstates; + FR_FCFS *batch; + FR_FCFS *buffer; + unsigned int capsize; +}; + +} /* scheduler core */ + +#endif /* PARBS_H_ */ diff --git a/dram/src/scheduler/ThreadLoad.cpp b/dram/src/scheduler/ThreadLoad.cpp new file mode 100644 index 00000000..fd551103 --- /dev/null +++ b/dram/src/scheduler/ThreadLoad.cpp @@ -0,0 +1,71 @@ +/* + * ThreadLoad.cpp + * + * Created on: Apr 9, 2014 + * Author: robert + */ + +#include "ThreadLoad.h" + +namespace scheduler { + +using namespace std; + +ThreadLoad::ThreadLoad() +{ + // TODO Auto-generated constructor stub + +} + +ThreadLoad::~ThreadLoad() +{ + // TODO Auto-generated destructor stub +} + +unsigned int ThreadLoad::getMaxBankLoad() const +{ + unsigned int maxLoad = 0; + for (auto& bankVectorPair : load) + { + if (bankVectorPair.second.size() > maxLoad) + maxLoad = bankVectorPair.second.size(); + } + return maxLoad; +} + +unsigned int ThreadLoad::getTotalLoad() const +{ + unsigned int totalLoad = 0; + for (auto& bankVectorPair : load) + { + totalLoad += bankVectorPair.second.size(); + } + return totalLoad; +} + +void ThreadLoad::addTransaction(gp* payload) +{ + load[DramExtension::getExtension(payload).getBank()].push_back(payload); +} + +bool operator<(const ThreadLoad& lhs, const ThreadLoad& rhs) +{ + if (lhs.getMaxBankLoad() < rhs.getMaxBankLoad()) + return true; + else if (lhs.getMaxBankLoad() == rhs.getMaxBankLoad()) + return lhs.getTotalLoad() < rhs.getTotalLoad(); + else + return false; +} + +vector ThreadLoad::getTransactions() +{ + vector result; + for (auto& bankVectorPair : load) + { + result.insert(result.end(), bankVectorPair.second.begin(), bankVectorPair.second.end()); + } + return result; +} + +} /* namespace scheduler */ diff --git a/dram/src/scheduler/ThreadLoad.h b/dram/src/scheduler/ThreadLoad.h new file mode 100644 index 00000000..9ccca269 --- /dev/null +++ b/dram/src/scheduler/ThreadLoad.h @@ -0,0 +1,44 @@ +/* + * ThreadLoad.h + * + * Created on: Apr 9, 2014 + * Author: robert + */ + +#ifndef THREADLOAD_H_ +#define THREADLOAD_H_ +#include +#include +#include "../common/dramExtension.h" + +namespace scheduler { + +typedef tlm::tlm_generic_payload gp; + +class ThreadLoad +{ +public: + ThreadLoad(); + virtual ~ThreadLoad(); + + unsigned int getMaxBankLoad() const; + unsigned int getTotalLoad() const; + + void addTransaction(gp* payload); + std::vector getTransactions(); + +private: + std::map> load; +}; + +bool operator< (const ThreadLoad &lhs, const ThreadLoad &rhs); + +struct LoadPointerComparer { + bool operator()(const ThreadLoad* l, const ThreadLoad* r) { + return *l < *r; + } +}; + +} /* namespace scheduler */ + +#endif /* THREADLOAD_H_ */ diff --git a/dram/src/simulation/Controller.h b/dram/src/simulation/Controller.h index fe4047b2..766bd5db 100644 --- a/dram/src/simulation/Controller.h +++ b/dram/src/simulation/Controller.h @@ -26,6 +26,7 @@ #include "../scheduler/Scheduler.h" #include "../scheduler/Fifo.h" #include "../scheduler/Fr_Fcfs.h" +#include "../scheduler/PARBS.h" using namespace std; using namespace tlm; @@ -61,10 +62,19 @@ public: void buildScheduler() { string selectedScheduler = Configuration::getInstance().Scheduler; + if (selectedScheduler == "FR_FCFS") - scheduler = new FR_FCFS(*controller, + { + scheduler = new FR_FCFS(controller->state.bankStates, Configuration::getInstance().RefreshAwareScheduling, Configuration::getInstance().AdaptiveOpenPagePolicy); + } + else if (selectedScheduler == "PAR_BS") + { + scheduler = new PAR_BS(controller->state.bankStates, + Configuration::getInstance().RefreshAwareScheduling, + Configuration::getInstance().Capsize); + } else if (selectedScheduler == "FIFO") scheduler = new Fifo(); else @@ -90,7 +100,7 @@ public: { case Command::Read: rec.recordPhase(payload, BEGIN_RD, command.getStart()); - dataStrobe = command.getIntervalOnDataStrobe(); + dataStrobe = command.getIntervalOnDataStrobe(); rec.updateDataStrobe(dataStrobe.start, dataStrobe.end, payload); rec.recordPhase(payload, END_RD, command.getEnd()); @@ -99,7 +109,7 @@ public: break; case Command::ReadA: rec.recordPhase(payload, BEGIN_RDA, command.getStart()); - dataStrobe = command.getIntervalOnDataStrobe(); + dataStrobe = command.getIntervalOnDataStrobe(); rec.updateDataStrobe(dataStrobe.start, dataStrobe.end, payload); rec.recordPhase(payload, END_RDA, command.getEnd()); @@ -108,7 +118,7 @@ public: break; case Command::Write: rec.recordPhase(payload, BEGIN_WR, command.getStart()); - dataStrobe = command.getIntervalOnDataStrobe(); + dataStrobe = command.getIntervalOnDataStrobe(); rec.updateDataStrobe(dataStrobe.start, dataStrobe.end, payload); rec.recordPhase(payload, END_WR, command.getEnd()); @@ -117,7 +127,7 @@ public: break; case Command::WriteA: rec.recordPhase(payload, BEGIN_WRA, command.getStart()); - dataStrobe = command.getIntervalOnDataStrobe(); + dataStrobe = command.getIntervalOnDataStrobe(); rec.updateDataStrobe(dataStrobe.start, dataStrobe.end, payload); rec.recordPhase(payload, END_WRA, command.getEnd()); diff --git a/dram/src/simulation/main.cpp b/dram/src/simulation/main.cpp deleted file mode 100644 index 26a75e68..00000000 --- a/dram/src/simulation/main.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/* - * main.cpp - * - * Created on: Mar 16, 2014 - * Author: robert - */ - -#include -#include -#include "SimulationManager.h" -#include "../core/configuration/Configuration.h" - -#include - -using namespace std; -using namespace simulation; - -string pathOfFile(string file) -{ - return file.substr(0, file.find_last_of('/')); -} - -void startTraceAnalyzer(string traceName) -{ - string p = getenv("trace"); - string run_tpr = p + " " + traceName; - system(run_tpr.c_str()); -} - -int sc_main(int argc, char **argv) -{ - sc_set_time_resolution(1, SC_PS); - - string resources = pathOfFile(argv[0]) + string("/../resources/"); - - string memconfig = "memconfig.xml"; - string memspec = "MICRON_4Gb_DDR4-1866_8bit_A.xml"; -// string memspec = "MatzesWideIO.xml"; - string stl1 = "chstone-sha_32.stl"; - stl1 = "empty.stl"; - unsigned int burstlength1 = 4; - string stl2 = "mediabench-h263decode_32.stl"; - // stl2 = "trace.stl"; - unsigned int burstlength2 = 4; - string traceName = "tpr.tdb"; - - SimulationManager simulationManager("sim",memconfig,memspec,stl1,burstlength1, stl2,burstlength2, traceName, resources,false); - simulationManager.startSimulation(); - startTraceAnalyzer(traceName); - return 0; -} -