From 6f0e2a00e19435520c47962f1c15fc005ac652c7 Mon Sep 17 00:00:00 2001 From: Johannes Feldmann Date: Wed, 8 Feb 2017 17:00:31 +0100 Subject: [PATCH 01/59] Added several files with test software for ECC Codes. --- DRAMSys/simulator/src/error/ECC/Bit.cpp | 25 ++++ DRAMSys/simulator/src/error/ECC/Bit.h | 66 ++++++++++ DRAMSys/simulator/src/error/ECC/ECC.cpp | 91 +++++++++++++ DRAMSys/simulator/src/error/ECC/ECC.h | 21 +++ DRAMSys/simulator/src/error/ECC/ECC_Test.cpp | 128 +++++++++++++++++++ DRAMSys/simulator/src/error/ECC/Word.cpp | 117 +++++++++++++++++ DRAMSys/simulator/src/error/ECC/Word.h | 60 +++++++++ 7 files changed, 508 insertions(+) create mode 100644 DRAMSys/simulator/src/error/ECC/Bit.cpp create mode 100644 DRAMSys/simulator/src/error/ECC/Bit.h create mode 100644 DRAMSys/simulator/src/error/ECC/ECC.cpp create mode 100644 DRAMSys/simulator/src/error/ECC/ECC.h create mode 100644 DRAMSys/simulator/src/error/ECC/ECC_Test.cpp create mode 100644 DRAMSys/simulator/src/error/ECC/Word.cpp create mode 100644 DRAMSys/simulator/src/error/ECC/Word.h diff --git a/DRAMSys/simulator/src/error/ECC/Bit.cpp b/DRAMSys/simulator/src/error/ECC/Bit.cpp new file mode 100644 index 00000000..b5faee9a --- /dev/null +++ b/DRAMSys/simulator/src/error/ECC/Bit.cpp @@ -0,0 +1,25 @@ +#include "stdafx.h" +#include "Bit.h" + + +CBit::CBit(VALUE nVal) +{ + m_nValue = nVal; +} + + +CBit::~CBit() +{ +} + +void CBit::Print() +{ + if (m_nValue == ZERO) + { + printf("0"); + } + else + { + printf("1"); + } +} diff --git a/DRAMSys/simulator/src/error/ECC/Bit.h b/DRAMSys/simulator/src/error/ECC/Bit.h new file mode 100644 index 00000000..74aec5da --- /dev/null +++ b/DRAMSys/simulator/src/error/ECC/Bit.h @@ -0,0 +1,66 @@ +#pragma once +class CBit +{ +public: + enum VALUE + { + ZERO = 0, + ONE = 1 + }; + +protected: + VALUE m_nValue; + +public: + CBit(VALUE nVal = ZERO); + virtual ~CBit(); + + inline void Set() { m_nValue = ONE; }; + inline void Clear() { m_nValue = ZERO; }; + + void Print(); + + CBit& operator=(DWORD d) + { + if (d == 0 ) + { + m_nValue = ZERO; + } + else + { + m_nValue = ONE; + } + return *this; + } + + friend CBit operator^(CBit l, const CBit& r) + { + if (l.m_nValue == r.m_nValue) + { + return CBit(ZERO); + } + else + { + return CBit(ONE); + } + } + + CBit& operator^=(const CBit& r) + { + if (m_nValue == r.m_nValue) + { + m_nValue = ZERO; + } + else + { + m_nValue = ONE; + } + return *this; + } + + inline bool operator==(const CBit::VALUE& r) + { + return m_nValue == r; + } +}; + diff --git a/DRAMSys/simulator/src/error/ECC/ECC.cpp b/DRAMSys/simulator/src/error/ECC/ECC.cpp new file mode 100644 index 00000000..bbd230ba --- /dev/null +++ b/DRAMSys/simulator/src/error/ECC/ECC.cpp @@ -0,0 +1,91 @@ +#include "stdafx.h" + +#include "ECC.h" + +unsigned ECC::GetNumParityBits(unsigned nDataBits) +{ + unsigned nParityBits = 0; + + // n = 2^k - k - 1 + while (nDataBits > ((1 << nParityBits) - nParityBits - 1)) + { + ++nParityBits; + } + + return nParityBits+1; // +1 for SEC-DED +} + +void ECC::ExtendWord(CWord & v) +{ + unsigned end = v.GetLength() + ECC::GetNumParityBits(v.GetLength()); + + unsigned i = 1; + while (i < end) + { + v.Insert(i-1, CBit()); + i <<= 1; + } + + v.Append(CBit()); +} + +void ECC::CalculateCheckbits(CWord & v, CWord & p) +{ + // Hamming-Code Prüfbits füllen + unsigned i = 1, l = 0; + while (i < v.GetLength()) + { + for (unsigned j = (i - 1); j < v.GetLength(); j += (i << 1)) + { + for (unsigned k = 0; k < (i); k++) + { + p[l] ^= v[j + k]; + } + } + l++; + i <<= 1; + } +} + +void ECC::InsertCheckbits(CWord& v, CWord p) +{ + // Prüfbits einfügen + unsigned i = 1, j = 0; + while (i <= v.GetLength()) + { + v[i - 1] = p[j++]; + i <<= 1; + } + +} + +void ECC::ExtractCheckbits(CWord v, CWord & p) +{ + // Prüfbits extrahieren + unsigned i = 1, j = 0; + while(i <= v.GetLength()) + { + p[j++] = v[i - 1]; + i <<= 1; + } +} + +void ECC::CalculateParityBit(CWord v, CBit & p) +{ + // Paritybit + p = CBit::ZERO; + for (unsigned i = 0; i < v.GetLength(); i++) + { + p ^= v[i]; + } +} + +void ECC::InsertParityBit(CWord& v, CBit p) +{ + v[v.GetLength() - 1] = p; +} + +void ECC::ExtractParityBit(CWord v, CBit & p) +{ + p = v[v.GetLength() - 1]; +} diff --git a/DRAMSys/simulator/src/error/ECC/ECC.h b/DRAMSys/simulator/src/error/ECC/ECC.h new file mode 100644 index 00000000..8379999a --- /dev/null +++ b/DRAMSys/simulator/src/error/ECC/ECC.h @@ -0,0 +1,21 @@ +#pragma once + +#include "Word.h" +#include "Bit.h" + +namespace ECC +{ + + unsigned GetNumParityBits(unsigned nDataBits); + + // Erweitert das Wort um zusätzliche Bits für die Berechnung des Hamming-Codes + void ExtendWord(CWord &v); + + void CalculateCheckbits(CWord &v, CWord & p); + void InsertCheckbits(CWord& v, CWord p); + void ExtractCheckbits(CWord v, CWord& p); + + void CalculateParityBit(CWord v, CBit& p); + void InsertParityBit(CWord& v, CBit p); + void ExtractParityBit(CWord v, CBit& p); +} diff --git a/DRAMSys/simulator/src/error/ECC/ECC_Test.cpp b/DRAMSys/simulator/src/error/ECC/ECC_Test.cpp new file mode 100644 index 00000000..dcbd884e --- /dev/null +++ b/DRAMSys/simulator/src/error/ECC/ECC_Test.cpp @@ -0,0 +1,128 @@ +// ECC_Test.cpp : Definiert den Einstiegspunkt für die Konsolenanwendung. +// + +#include "stdafx.h" +#include +#include "ECC.h" + +int main() +{ + // Random number init + srand(time(NULL)); + + // Erstellen + unsigned size = 4; + CWord p(ECC::GetNumParityBits(size)), v(size); + + // Daten eingeben + for (unsigned a = 0; a < 16; a++) + { + v = a; + v.Rotate(); + + ECC::ExtendWord(v); + printf("%d:\t", a); + + p = 0; + ECC::CalculateCheckbits(v, p); + ECC::InsertCheckbits(v, p); + ECC::CalculateParityBit(v, p[3]); + ECC::InsertParityBit(v, p[3]); + + v.Print(); + + v.Resize(size); + } + + printf("\r\n"); + + for (unsigned x = 0; x < 100; x++) + { + //Get random number + unsigned a = rand() % 16; + + v.Resize(size); + v = a; + v.Rotate(); + + ECC::ExtendWord(v); + + p = 0; + ECC::CalculateCheckbits(v, p); + ECC::InsertCheckbits(v, p); + ECC::CalculateParityBit(v, p[3]); + ECC::InsertParityBit(v, p[3]); + v.Print(); + + // Insert error + unsigned pos = rand() % 8; + v[pos] ^= CBit(CBit::ONE); + + printf("Data: %d, Error at pos %d: ", a, pos + 1); + v[pos].Print(); + printf("\r\n"); + v.Print(); + + p = 0; + ECC::CalculateCheckbits(v, p); + ECC::CalculateParityBit(v, p[3]); + + printf("%d:\t", a); + + p.Print(); + + // Interpreting Data + + unsigned syndrome = 0; + for (unsigned i = 0; i < p.GetLength() - 1; i++) + { + if (p[i] == CBit::ONE) + syndrome += (1 << i); + } + + if (p[3] == CBit::ZERO) + { + // Parity even + + if (syndrome) + { + // Double error + printf("Double error detected.\r\n"); + break; + } + else + { + // No Error + printf("No error detected.\r\n"); + break; + } + } + else + { + // Parity odd + + if (syndrome) + { + // Bit error + printf("Error detected in Bit %d.\r\n", syndrome); + if (syndrome == pos + 1) + continue; + else + break; + } + else + { + // Overall parity Error + printf("Overall parity error detected.\r\n"); + if (pos == 7 || pos == 3 || pos == 1 || pos == 0) + continue; + else + break; + } + } + } + system("pause"); + + return 0; +} + diff --git a/DRAMSys/simulator/src/error/ECC/Word.cpp b/DRAMSys/simulator/src/error/ECC/Word.cpp new file mode 100644 index 00000000..a94bdad7 --- /dev/null +++ b/DRAMSys/simulator/src/error/ECC/Word.cpp @@ -0,0 +1,117 @@ +#include "stdafx.h" +#include "Word.h" + + +CWord::CWord(unsigned nBitLength) + : m_nBitLength(nBitLength) +{ + m_word.resize(nBitLength); +} + + +CWord::~CWord() +{ +} + +CBit * CWord::GetAt(unsigned nBitPos) +{ + if (nBitPos < m_nBitLength) + { + return &m_word.at(nBitPos); + } + + return nullptr; +} + +void CWord::Set(DWORD data) +{ + deque::iterator it; + if (m_nBitLength < sizeof(data)) + { + it = m_word.begin(); + for (unsigned i = 0; i < m_nBitLength; i++) + { + (*it++) = data & 1; + data >>= 1; + } + } + else + { + for (it = m_word.begin(); it != m_word.end(); it++) + { + (*it) = data & 1; + data >>= 1; + } + } +} + +void CWord::Rotate() +{ + deque buffer = m_word; + for (unsigned i = 0; i < m_nBitLength; i++) + { + m_word.at(m_nBitLength -i -1) = buffer.at(i); + } +} + +bool CWord::Insert(unsigned npos, CBit b) +{ + if (npos >= m_nBitLength) + return false; + + deque::iterator it = m_word.begin() + npos; + m_word.insert(it, b); + + m_nBitLength++; + + return true; +} + +bool CWord::Delete(unsigned npos) +{ + if (npos >= m_nBitLength) + return false; + + deque::iterator it = m_word.begin() + npos; + m_word.erase(it); + + m_nBitLength++; + + return true; +} + +void CWord::Append(CBit b) +{ + m_word.push_back(b); + + m_nBitLength++; +} + +void CWord::Resize(unsigned nsize) +{ + m_word.resize(nsize); + m_nBitLength = nsize; +} + +bool CWord::PartShiftRight(unsigned nPos, unsigned nShift) +{ + if(nPos >= m_nBitLength) + return false; + + /*for (unsigned i = 0; i < nShift; i++) + { + m_word.insert() + }*/ + + return true; +} + +void CWord::Print() +{ + deque::iterator it; + for (it = m_word.begin(); it != m_word.end(); it++) + { + (*it).Print(); + } + printf("\r\n"); +} diff --git a/DRAMSys/simulator/src/error/ECC/Word.h b/DRAMSys/simulator/src/error/ECC/Word.h new file mode 100644 index 00000000..e3ae7c66 --- /dev/null +++ b/DRAMSys/simulator/src/error/ECC/Word.h @@ -0,0 +1,60 @@ +#pragma once + +#include +#include "Bit.h" + +using std::deque; + + +class CWord +{ +protected: + + unsigned m_nBitLength; + deque m_word; + + +public: + CWord(unsigned nBitLength); + virtual ~CWord(); + + CBit* GetAt(unsigned nBitPos); + + void Set(DWORD data); + void Rotate(); + + bool Insert(unsigned npos, CBit b); + bool Delete(unsigned npos); + + void Append(CBit b); + + void Resize(unsigned nsize); + + bool PartShiftRight(unsigned nPos, unsigned nShift); + + inline unsigned GetLength() const { return m_nBitLength; }; + + void Print(); + + CWord& operator=(DWORD d) + { + Set(d); + return *this; + } + + CBit& operator[](unsigned nPos) + { + return m_word.at(nPos); + } + + friend CWord operator >> (CWord l, const unsigned& r) + { + for (unsigned i = 0; i < r; i++) + { + l.m_word.pop_front(); + l.m_word.push_back(CBit(CBit::VALUE::ZERO)); + } + return l; + } +}; + From 4ed7ff420b85fc9ac60b937ec9e7bf025a610faa Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Thu, 23 Feb 2017 16:22:44 +0100 Subject: [PATCH 02/59] Initial setup for SMS implementation # Explain what has been changed # Explain why this change is being made # Provide links to any relevant tickets, articles or other resources --- .../resources/configs/mcconfigs/sms.xml | 15 ++++++++++++ .../resources/simulations/sim-batch.xml | 6 ++--- DRAMSys/simulator/simulator.pro | 6 +++-- .../simulator/src/controller/Controller.cpp | 4 ++++ DRAMSys/simulator/src/controller/Controller.h | 1 + .../core/configuration/Configuration.cpp | 6 +++++ .../core/configuration/Configuration.h | 1 + .../src/controller/scheduler/SMS.cpp | 13 ++++++++++ .../simulator/src/controller/scheduler/SMS.h | 24 +++++++++++++++++++ 9 files changed, 71 insertions(+), 5 deletions(-) create mode 100644 DRAMSys/simulator/resources/configs/mcconfigs/sms.xml create mode 100644 DRAMSys/simulator/src/controller/scheduler/SMS.cpp create mode 100644 DRAMSys/simulator/src/controller/scheduler/SMS.h diff --git a/DRAMSys/simulator/resources/configs/mcconfigs/sms.xml b/DRAMSys/simulator/resources/configs/mcconfigs/sms.xml new file mode 100644 index 00000000..f975678a --- /dev/null +++ b/DRAMSys/simulator/resources/configs/mcconfigs/sms.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/DRAMSys/simulator/resources/simulations/sim-batch.xml b/DRAMSys/simulator/resources/simulations/sim-batch.xml index 0752914c..dcc783d9 100644 --- a/DRAMSys/simulator/resources/simulations/sim-batch.xml +++ b/DRAMSys/simulator/resources/simulations/sim-batch.xml @@ -2,7 +2,7 @@ - + @@ -39,11 +39,11 @@ - + - + chstone-adpcm_32.stl diff --git a/DRAMSys/simulator/simulator.pro b/DRAMSys/simulator/simulator.pro index 593718da..20ddcef4 100644 --- a/DRAMSys/simulator/simulator.pro +++ b/DRAMSys/simulator/simulator.pro @@ -107,7 +107,8 @@ SOURCES += \ src/controller/Controller.cpp \ src/simulation/TracePlayer.cpp \ src/simulation/StlPlayer.cpp \ - src/controller/core/powerdown/PowerDownManagerTimeoutBankwise.cpp + src/controller/core/powerdown/PowerDownManagerTimeoutBankwise.cpp \ + src/controller/scheduler/SMS.cpp HEADERS += \ src/common/third_party/tinyxml2/tinyxml2.h \ @@ -169,7 +170,8 @@ HEADERS += \ src/controller/core/configuration/ConfigurationLoader.h \ src/error/errormodel.h \ src/simulation/ExampleInitiator.h \ - src/controller/core/powerdown/PowerDownManagerTimeoutBankwise.h + src/controller/core/powerdown/PowerDownManagerTimeoutBankwise.h \ + src/controller/scheduler/SMS.h thermalsim = $$(THERMALSIM) isEmpty(thermalsim) { diff --git a/DRAMSys/simulator/src/controller/Controller.cpp b/DRAMSys/simulator/src/controller/Controller.cpp index 65847603..b16f981b 100644 --- a/DRAMSys/simulator/src/controller/Controller.cpp +++ b/DRAMSys/simulator/src/controller/Controller.cpp @@ -53,6 +53,10 @@ void Controller::buildScheduler() { scheduler = new FR_FCFS(*controllerCore); } + else if (selectedScheduler == "SMS") + { + scheduler = new SMS(*controllerCore, Configuration::getInstance().SJFProbability); + } //else if (selectedScheduler == "PAR_BS") //{ // scheduler = new PAR_BS(*controllerCore,Configuration::getInstance().RefreshAwareScheduling, diff --git a/DRAMSys/simulator/src/controller/Controller.h b/DRAMSys/simulator/src/controller/Controller.h index a07a8b74..a1286d1f 100644 --- a/DRAMSys/simulator/src/controller/Controller.h +++ b/DRAMSys/simulator/src/controller/Controller.h @@ -67,6 +67,7 @@ #include "scheduler/Fifo.h" #include "scheduler/FifoStrict.h" #include "scheduler/Fr_Fcfs.h" +#include "scheduler/SMS.h" #include "scheduler/IScheduler.h" using namespace std; diff --git a/DRAMSys/simulator/src/controller/core/configuration/Configuration.cpp b/DRAMSys/simulator/src/controller/core/configuration/Configuration.cpp index 594a746b..910e0029 100644 --- a/DRAMSys/simulator/src/controller/core/configuration/Configuration.cpp +++ b/DRAMSys/simulator/src/controller/core/configuration/Configuration.cpp @@ -121,6 +121,12 @@ void Configuration::setParameter(std::string name, std::string value) MaxNrOfTransactions = string2int(value); else if(name == "Scheduler") Scheduler = value; + else if(name == "SJFProbability") + if (string2int(value) > 100 || string2int(value) < 0) { + SC_REPORT_FATAL("Configuration", ("Invalid value for parameter " + name + ". This parameter must be between 0 and 100.").c_str()); + } else { + SJFProbability = string2int(value); + } else if(name == "Capsize") Capsize = string2int(value); else if(name == "PowerDownTimeout") diff --git a/DRAMSys/simulator/src/controller/core/configuration/Configuration.h b/DRAMSys/simulator/src/controller/core/configuration/Configuration.h index 53437269..929d65f1 100644 --- a/DRAMSys/simulator/src/controller/core/configuration/Configuration.h +++ b/DRAMSys/simulator/src/controller/core/configuration/Configuration.h @@ -66,6 +66,7 @@ struct Configuration bool OpenPagePolicy = true; unsigned int MaxNrOfTransactions = 8; std::string Scheduler; + unsigned int SJFProbability; unsigned int Capsize = 5; sc_time getPowerDownTimeout(){return powerDownTimeoutInClk*memSpec.clk;} EPowerDownMode PowerDownMode = EPowerDownMode::Staggered; diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp new file mode 100644 index 00000000..a5eef6dc --- /dev/null +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -0,0 +1,13 @@ +#include "SMS.h" + +using namespace std; + +void SMS::schedule (gp *payload) +{ + buffer[DramExtension::getExtension(payload).getThread()].emplace_back(payload); +} + +std::pair SMS::getNextRequest(Bank bank) +{ + return pair(Command::NOP, NULL); +} diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h new file mode 100644 index 00000000..c2c7dfa3 --- /dev/null +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h @@ -0,0 +1,24 @@ +#ifndef SMS_H +#define SMS_H + +#include "IScheduler.h" +#include "../core/ControllerCore.h" +#include "../core/configuration/Configuration.h" +#include "../../common/dramExtension.h" + +using namespace std; + +class SMS: public sc_module, public IScheduler +{ +public: + SMS(ControllerCore &controllerCore, unsigned int SJFprobability) : IScheduler(controllerCore), SJFprobability(SJFprobability){} + virtual ~SMS(){} + virtual void schedule(gp *payload) override; + virtual std::pair getNextRequest(Bank bank) override; + +private: + std::map> buffer; + unsigned int SJFprobability; +}; + +#endif // SMS_H From 2cfa7114af2fb3dc6a3fad2d3010b2fd7821d098 Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Thu, 23 Feb 2017 21:14:30 +0100 Subject: [PATCH 03/59] Implement getNextRequest # Explain what has been changed # Explain why this change is being made # Provide links to any relevant tickets, articles or other resources --- .../src/controller/scheduler/SMS.cpp | 22 ++++++++++++++++--- .../simulator/src/controller/scheduler/SMS.h | 2 ++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index a5eef6dc..a3ae0867 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -2,12 +2,28 @@ using namespace std; -void SMS::schedule (gp *payload) +void SMS::schedule(gp *payload) { - buffer[DramExtension::getExtension(payload).getThread()].emplace_back(payload); + buffer[DramExtension::getExtension(payload).getThread()].emplace_back(payload); } std::pair SMS::getNextRequest(Bank bank) { - return pair(Command::NOP, NULL); + if (bankbuffer[bank].empty()) + { + return pair(Command::NOP, NULL); + } + else + { + gp* payload = bankbuffer[bank].front(); + Command command = IScheduler::getNextCommand(*payload); + if (command == Command::Read || command == Command::ReadA || command == Command::Write + || command == Command::WriteA) + { + bankbuffer[bank].pop_front(); + } + + return pair(command, payload); + } + } diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h index c2c7dfa3..d6fde08a 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.h +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h @@ -18,6 +18,8 @@ public: private: std::map> buffer; + std::map> bankbuffer; + unsigned int SJFprobability; }; From 42b1c96afdb76fe28f281853e6b627d7f698be9a Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Thu, 23 Feb 2017 21:48:29 +0100 Subject: [PATCH 04/59] First prototype of ReadyBatch class # Explain what has been changed # Explain why this change is being made # Provide links to any relevant tickets, articles or other resources --- .../resources/configs/mcconfigs/sms.xml | 2 ++ DRAMSys/simulator/simulator.pro | 6 +++-- .../core/configuration/Configuration.cpp | 4 +++ .../core/configuration/Configuration.h | 2 ++ .../src/controller/scheduler/ReadyBatch.cpp | 1 + .../src/controller/scheduler/ReadyBatch.h | 25 +++++++++++++++++++ 6 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp create mode 100644 DRAMSys/simulator/src/controller/scheduler/ReadyBatch.h diff --git a/DRAMSys/simulator/resources/configs/mcconfigs/sms.xml b/DRAMSys/simulator/resources/configs/mcconfigs/sms.xml index f975678a..bee3151e 100644 --- a/DRAMSys/simulator/resources/configs/mcconfigs/sms.xml +++ b/DRAMSys/simulator/resources/configs/mcconfigs/sms.xml @@ -4,6 +4,8 @@ + + diff --git a/DRAMSys/simulator/simulator.pro b/DRAMSys/simulator/simulator.pro index 20ddcef4..4d98bf05 100644 --- a/DRAMSys/simulator/simulator.pro +++ b/DRAMSys/simulator/simulator.pro @@ -108,7 +108,8 @@ SOURCES += \ src/simulation/TracePlayer.cpp \ src/simulation/StlPlayer.cpp \ src/controller/core/powerdown/PowerDownManagerTimeoutBankwise.cpp \ - src/controller/scheduler/SMS.cpp + src/controller/scheduler/SMS.cpp \ + src/controller/scheduler/ReadyBatch.cpp HEADERS += \ src/common/third_party/tinyxml2/tinyxml2.h \ @@ -171,7 +172,8 @@ HEADERS += \ src/error/errormodel.h \ src/simulation/ExampleInitiator.h \ src/controller/core/powerdown/PowerDownManagerTimeoutBankwise.h \ - src/controller/scheduler/SMS.h + src/controller/scheduler/SMS.h \ + src/controller/scheduler/ReadyBatch.h thermalsim = $$(THERMALSIM) isEmpty(thermalsim) { diff --git a/DRAMSys/simulator/src/controller/core/configuration/Configuration.cpp b/DRAMSys/simulator/src/controller/core/configuration/Configuration.cpp index 910e0029..f3698179 100644 --- a/DRAMSys/simulator/src/controller/core/configuration/Configuration.cpp +++ b/DRAMSys/simulator/src/controller/core/configuration/Configuration.cpp @@ -127,6 +127,10 @@ void Configuration::setParameter(std::string name, std::string value) } else { SJFProbability = string2int(value); } + else if (name == "ReadyBatchSize") + ReadyBatchSize = string2int(value); + else if (name == "ReadyBatchThresholdAge") + ReadyBatchThresholdAge = string2int(value); else if(name == "Capsize") Capsize = string2int(value); else if(name == "PowerDownTimeout") diff --git a/DRAMSys/simulator/src/controller/core/configuration/Configuration.h b/DRAMSys/simulator/src/controller/core/configuration/Configuration.h index 929d65f1..6ca503a7 100644 --- a/DRAMSys/simulator/src/controller/core/configuration/Configuration.h +++ b/DRAMSys/simulator/src/controller/core/configuration/Configuration.h @@ -67,6 +67,8 @@ struct Configuration unsigned int MaxNrOfTransactions = 8; std::string Scheduler; unsigned int SJFProbability; + unsigned int ReadyBatchSize; + unsigned int ReadyBatchThresholdAge; unsigned int Capsize = 5; sc_time getPowerDownTimeout(){return powerDownTimeoutInClk*memSpec.clk;} EPowerDownMode PowerDownMode = EPowerDownMode::Staggered; diff --git a/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp new file mode 100644 index 00000000..a55c4c40 --- /dev/null +++ b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp @@ -0,0 +1 @@ +#include "ReadyBatch.h" diff --git a/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.h b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.h new file mode 100644 index 00000000..91fac215 --- /dev/null +++ b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.h @@ -0,0 +1,25 @@ +#ifndef READYBATCH_H +#define READYBATCH_H + +#include "tlm.h" +#include "../../common/dramExtension.h" + +typedef tlm::tlm_generic_payload gp; + +using namespace std; + +class ReadyBatch +{ +public: + ReadyBatch(unsigned int fifosize) : fifosize(fifosize){} + bool addTransaction(gp* payload); +private: + std::deque readybatch; + unsigned int fifosize; + + Row getRow(); + sc_time getTimeOfOldestRequest(); + unsigned int getNumRequests(); +}; + +#endif // READYBATCH_H From 413916f4027bcf3f7c6f9fdab1fdf9e858d3a92f Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Thu, 23 Feb 2017 22:35:09 +0100 Subject: [PATCH 05/59] Implement ReadyBatch class # Explain what has been changed # Explain why this change is being made # Provide links to any relevant tickets, articles or other resources --- .../src/controller/scheduler/ReadyBatch.cpp | 42 +++++++++++++++++++ .../src/controller/scheduler/ReadyBatch.h | 4 +- 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp index a55c4c40..af218173 100644 --- a/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp @@ -1 +1,43 @@ #include "ReadyBatch.h" + +ReadyBatch::ReadyBatch() +{ + fifosize = Configuration::getInstance().ReadyBatchSize; + thresholdAge(Configuration::getInstance().ReadyBatchThresholdAge, SC_NS); +} + +unsigned int ReadyBatch::getNumRequests() +{ + return readybatch.size(); +} + +Row ReadyBatch::getRow() +{ + return DramExtension::getExtension(readybatch.front()).getRow(); +} + +sc_time ReadyBatch::getTimeOfOldestRequest() +{ + sc_time oldestTime = sc_time_stamp(); + for (auto reqPayload = readybatch.begin(); reqPayload != readybatch.end(); reqPayload++) + { + sc_time requestTimeOfGeneration = GenerationExtension::getExtension(*reqPayload).TimeOfGeneration(); + if (requestTimeOfGeneration < oldestTime) + { + oldestTime = requestTimeOfGeneration; + } + } + return oldestTime; +} + +bool ReadyBatch::addTransaction(gp* payload) +{ + sc_time currentAge = sc_time_stamp() - getTimeOfOldestRequest(); + Row newRow = DramExtension::getExtension(payload).getRow(); + if (getNumRequests == fifosize || currentAge >= thresholdAge || newRow != getRow()) { + return false; + } else { + readybatch.emplace_back(payload); + return true; + } +} diff --git a/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.h b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.h index 91fac215..ff9e8e80 100644 --- a/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.h +++ b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.h @@ -3,6 +3,7 @@ #include "tlm.h" #include "../../common/dramExtension.h" +#include "../core/configuration/Configuration.h" typedef tlm::tlm_generic_payload gp; @@ -11,11 +12,12 @@ using namespace std; class ReadyBatch { public: - ReadyBatch(unsigned int fifosize) : fifosize(fifosize){} + ReadyBatch(); bool addTransaction(gp* payload); private: std::deque readybatch; unsigned int fifosize; + sc_time thresholdAge; Row getRow(); sc_time getTimeOfOldestRequest(); From 10f9f2caff06cd5d77f260b6e99051bc599c6a53 Mon Sep 17 00:00:00 2001 From: Johannes Feldmann Date: Mon, 27 Feb 2017 07:39:53 +0100 Subject: [PATCH 06/59] If StoreMode is Store or ErrorModel, then reads don't need data anymore. --- DRAMSys/simulator/src/simulation/StlPlayer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DRAMSys/simulator/src/simulation/StlPlayer.cpp b/DRAMSys/simulator/src/simulation/StlPlayer.cpp index 2ed2dd5f..2b805500 100644 --- a/DRAMSys/simulator/src/simulation/StlPlayer.cpp +++ b/DRAMSys/simulator/src/simulation/StlPlayer.cpp @@ -113,7 +113,7 @@ void StlPlayer::nextPayload() unsigned long long addr = std::stoull(address.c_str(), 0, 16); // Get the data if necessary. - if (Configuration::getInstance().StoreMode != StorageMode::NoStorage) { + if (Configuration::getInstance().StoreMode != StorageMode::NoStorage && cmd != TLM_READ_COMMAND) { // The input trace file must provide the data to be stored into the memory. iss >> dataStr; if (dataStr.empty()) From af20dcb64708fb3414339e8598966bda837c0c7e Mon Sep 17 00:00:00 2001 From: Johannes Feldmann Date: Mon, 27 Feb 2017 08:57:34 +0100 Subject: [PATCH 07/59] ECC Controller as dummy created. --- DRAMSys/simulator/simulator.pro | 3 +- DRAMSys/simulator/src/error/controllerECC.h | 40 +++++++++++++++++++ .../simulator/src/simulation/Simulation.cpp | 8 +++- DRAMSys/simulator/src/simulation/Simulation.h | 4 +- 4 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 DRAMSys/simulator/src/error/controllerECC.h diff --git a/DRAMSys/simulator/simulator.pro b/DRAMSys/simulator/simulator.pro index 593718da..3577b06b 100644 --- a/DRAMSys/simulator/simulator.pro +++ b/DRAMSys/simulator/simulator.pro @@ -169,7 +169,8 @@ HEADERS += \ src/controller/core/configuration/ConfigurationLoader.h \ src/error/errormodel.h \ src/simulation/ExampleInitiator.h \ - src/controller/core/powerdown/PowerDownManagerTimeoutBankwise.h + src/controller/core/powerdown/PowerDownManagerTimeoutBankwise.h \ + src/error/controllerECC.h thermalsim = $$(THERMALSIM) isEmpty(thermalsim) { diff --git a/DRAMSys/simulator/src/error/controllerECC.h b/DRAMSys/simulator/src/error/controllerECC.h new file mode 100644 index 00000000..28c93547 --- /dev/null +++ b/DRAMSys/simulator/src/error/controllerECC.h @@ -0,0 +1,40 @@ +#ifndef CONTROLLERECC_H +#define CONTROLLERECC_H + +#include + +using namespace std; +using namespace tlm; + +struct ControllerECC: sc_module +{ + tlm_utils::multi_passthrough_target_socket t_socket; + tlm_utils::multi_passthrough_initiator_socket i_socket; + + SC_CTOR(ControllerECC) + : t_socket("t_socket") + , i_socket("i_socket") + { + t_socket.register_nb_transport_fw (this, &ControllerECC::nb_transport_fw); + i_socket.register_nb_transport_bw (this, &ControllerECC::nb_transport_bw); + } + + // Forward interface + + virtual tlm::tlm_sync_enum nb_transport_fw( int id, tlm::tlm_generic_payload& trans, + tlm::tlm_phase& phase, sc_time& delay ) + { + return i_socket[id]->nb_transport_fw( trans, phase, delay ); + } + + + // Backward interface + + virtual tlm::tlm_sync_enum nb_transport_bw( int id, tlm::tlm_generic_payload& trans, + tlm::tlm_phase& phase, sc_time& delay ) + { + return t_socket[id]->nb_transport_bw( trans, phase, delay ); + } +}; + +#endif // CONTROLLERECC_H diff --git a/DRAMSys/simulator/src/simulation/Simulation.cpp b/DRAMSys/simulator/src/simulation/Simulation.cpp index eae30c9a..c478e0bf 100644 --- a/DRAMSys/simulator/src/simulation/Simulation.cpp +++ b/DRAMSys/simulator/src/simulation/Simulation.cpp @@ -117,6 +117,10 @@ void Simulation::instantiateModules(const string &traceName, const string &pathT // Create and properly initialize TLM recorders. They need to be ready before creating some modules. setupTlmRecorders(traceName, pathToResources, devices); + // Create ECC Controller + ecc = new ControllerECC("ecc"); + + // Create Arbiter arbiter = new Arbiter("arbiter"); arbiter->setTlmRecorders(tlmRecorders); @@ -142,7 +146,9 @@ void Simulation::instantiateModules(const string &traceName, const string &pathT void Simulation::bindSockets() { - tSocket.bind(arbiter->tSocket); + tSocket.bind(ecc->t_socket); + ecc->i_socket(arbiter->tSocket); + //tSocket.bind(arbiter->tSocket); if(Configuration::getInstance().CheckTLM2Protocol) { for (size_t i = 0; i < Configuration::getInstance().NumberOfMemChannels; i++) { diff --git a/DRAMSys/simulator/src/simulation/Simulation.h b/DRAMSys/simulator/src/simulation/Simulation.h index 45890b47..18304cbe 100644 --- a/DRAMSys/simulator/src/simulation/Simulation.h +++ b/DRAMSys/simulator/src/simulation/Simulation.h @@ -49,7 +49,7 @@ #include "../controller/Controller.h" #include "../common/third_party/tinyxml2/tinyxml2.h" #include "../common/tlm2_base_protocol_checker.h" - +#include "../error/controllerECC.h" struct DramSetup { @@ -96,6 +96,8 @@ private: //TLM 2.0 Protocol Checkers std::vector*> controllersTlmCheckers; + // All transactions pass first through the ECC Controller + ControllerECC *ecc; // All transactions pass through the same arbiter Arbiter *arbiter; // Each DRAM unit has a controller From a0daa34bf14a79c3a6d6caa4b3c068e55a4f2126 Mon Sep 17 00:00:00 2001 From: Johannes Feldmann Date: Mon, 27 Feb 2017 10:46:48 +0100 Subject: [PATCH 08/59] ECC implemented. Error trace created which produces many errors. --- .../resources/configs/mcconfigs/fifo.xml | 2 +- .../resources/configs/memspecs/WideIO.xml | 2 +- .../resources/simulations/sim-batch.xml | 8 +-- DRAMSys/simulator/src/error/controllerECC.h | 70 +++++++++++++------ .../src/simulation/SimulationManager.cpp | 3 +- 5 files changed, 57 insertions(+), 28 deletions(-) diff --git a/DRAMSys/simulator/resources/configs/mcconfigs/fifo.xml b/DRAMSys/simulator/resources/configs/mcconfigs/fifo.xml index 2048948f..b3810f64 100644 --- a/DRAMSys/simulator/resources/configs/mcconfigs/fifo.xml +++ b/DRAMSys/simulator/resources/configs/mcconfigs/fifo.xml @@ -10,5 +10,5 @@ - + diff --git a/DRAMSys/simulator/resources/configs/memspecs/WideIO.xml b/DRAMSys/simulator/resources/configs/memspecs/WideIO.xml index fbe252d6..3ab07172 100644 --- a/DRAMSys/simulator/resources/configs/memspecs/WideIO.xml +++ b/DRAMSys/simulator/resources/configs/memspecs/WideIO.xml @@ -24,7 +24,7 @@ - + diff --git a/DRAMSys/simulator/resources/simulations/sim-batch.xml b/DRAMSys/simulator/resources/simulations/sim-batch.xml index 0752914c..8e28fdb9 100644 --- a/DRAMSys/simulator/resources/simulations/sim-batch.xml +++ b/DRAMSys/simulator/resources/simulations/sim-batch.xml @@ -1,8 +1,8 @@ - - + + @@ -39,12 +39,12 @@ - + - chstone-adpcm_32.stl + test.stl diff --git a/DRAMSys/simulator/src/error/controllerECC.h b/DRAMSys/simulator/src/error/controllerECC.h index 28c93547..b9dd772e 100644 --- a/DRAMSys/simulator/src/error/controllerECC.h +++ b/DRAMSys/simulator/src/error/controllerECC.h @@ -3,38 +3,66 @@ #include +#include "../common/xmlAddressdecoder.h" +#include "../common/DebugManager.h" + using namespace std; using namespace tlm; struct ControllerECC: sc_module { - tlm_utils::multi_passthrough_target_socket t_socket; - tlm_utils::multi_passthrough_initiator_socket i_socket; +private: + map m_mBuffer; - SC_CTOR(ControllerECC) - : t_socket("t_socket") - , i_socket("i_socket") - { - t_socket.register_nb_transport_fw (this, &ControllerECC::nb_transport_fw); - i_socket.register_nb_transport_bw (this, &ControllerECC::nb_transport_bw); - } +public: + tlm_utils::multi_passthrough_target_socket t_socket; + tlm_utils::multi_passthrough_initiator_socket i_socket; - // Forward interface + SC_CTOR(ControllerECC) + : t_socket("t_socket") + , i_socket("i_socket") + { + t_socket.register_nb_transport_fw(this, &ControllerECC::nb_transport_fw); + i_socket.register_nb_transport_bw(this, &ControllerECC::nb_transport_bw); + } - virtual tlm::tlm_sync_enum nb_transport_fw( int id, tlm::tlm_generic_payload& trans, - tlm::tlm_phase& phase, sc_time& delay ) - { - return i_socket[id]->nb_transport_fw( trans, phase, delay ); - } + // Forward interface + virtual tlm::tlm_sync_enum nb_transport_fw( int id, tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_time& delay ) + { + if(trans.get_command() == TLM_WRITE_COMMAND) + { + // Save all Bytes + for(unsigned i = 0; i < trans.get_data_length(); i++) + { + m_mBuffer[trans.get_address() + i] = *(trans.get_data_ptr() + i); + } + } + return i_socket[id]->nb_transport_fw( trans, phase, delay ); + } - // Backward interface + // Backward interface + virtual tlm::tlm_sync_enum nb_transport_bw( int id, tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_time& delay ) + { + if(trans.get_command() == TLM_WRITE_COMMAND) + { + // Compare all Bytes + for(unsigned i = 0; i < trans.get_data_length(); i++) + { + if(m_mBuffer[trans.get_address() + i] != *(trans.get_data_ptr() + i)) + { + std::stringstream msg; + msg << "Error Detected: Address: 0x" << hex << trans.get_address() + i + << "\n\t\tData Read: 0x" << hex << (int)*(trans.get_data_ptr() + i) + << "\n\t\tData original: 0x" << hex << (int)m_mBuffer[trans.get_address() + i]; - virtual tlm::tlm_sync_enum nb_transport_bw( int id, tlm::tlm_generic_payload& trans, - tlm::tlm_phase& phase, sc_time& delay ) - { - return t_socket[id]->nb_transport_bw( trans, phase, delay ); - } + DebugManager::getInstance().printDebugMessage(name(), msg.str()); + } + } + } + + return t_socket[id]->nb_transport_bw( trans, phase, delay ); + } }; #endif // CONTROLLERECC_H diff --git a/DRAMSys/simulator/src/simulation/SimulationManager.cpp b/DRAMSys/simulator/src/simulation/SimulationManager.cpp index a3494667..f9760533 100644 --- a/DRAMSys/simulator/src/simulation/SimulationManager.cpp +++ b/DRAMSys/simulator/src/simulation/SimulationManager.cpp @@ -92,7 +92,7 @@ void SimulationManager::runSimulations() for (auto& batch : simulationBatches) { boost::filesystem::path dir(exportPath); - boost::filesystem::create_directories(dir); + boost::filesystem::create_directory(dir); for (auto& dramSetup : batch.dramSetups) { @@ -238,6 +238,7 @@ void SimulationManager::runSimulation(string traceName) sc_set_stop_mode(SC_STOP_FINISH_DELTA); sc_start(); + double elapsed_secs = double(clock() - simStartTime) / CLOCKS_PER_SEC; report("\nSimulation took " + to_string(elapsed_secs) + " seconds\n"); delete simulation; From df9368b1fd35cd83df0cd1a7cdea0fa59ead0a75 Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Wed, 1 Mar 2017 17:22:01 +0100 Subject: [PATCH 09/59] 1st implementation SMS batch scheduler --- .../src/controller/scheduler/ReadyBatch.cpp | 10 ++ .../src/controller/scheduler/ReadyBatch.h | 4 +- .../src/controller/scheduler/SMS.cpp | 170 ++++++++++++++++++ .../simulator/src/controller/scheduler/SMS.h | 30 +++- 4 files changed, 211 insertions(+), 3 deletions(-) diff --git a/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp index af218173..84af0d69 100644 --- a/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp @@ -41,3 +41,13 @@ bool ReadyBatch::addTransaction(gp* payload) return true; } } + +std::deque& ReadyBatch::getTransactions() +{ + return readybatch; +} + +bool ReadyBatch::isEmpty() +{ + return readybatch.empty(); +} diff --git a/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.h b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.h index ff9e8e80..5e2e8f49 100644 --- a/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.h +++ b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.h @@ -14,6 +14,9 @@ class ReadyBatch public: ReadyBatch(); bool addTransaction(gp* payload); + unsigned int getNumRequests(); + std::deque& getTransactions(); + bool isEmpty(); private: std::deque readybatch; unsigned int fifosize; @@ -21,7 +24,6 @@ private: Row getRow(); sc_time getTimeOfOldestRequest(); - unsigned int getNumRequests(); }; #endif // READYBATCH_H diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index a3ae0867..252300b1 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -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 SMS::getNextRequest(Bank bank) @@ -20,6 +30,7 @@ std::pair 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 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 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::iterator next = readybatches.begin(); + + // drain to bank buffers + std::deque 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); + } + } +} diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h index d6fde08a..9f871776 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.h +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h @@ -1,17 +1,31 @@ #ifndef SMS_H #define SMS_H +#include +#include +#include "sysc/utils/sc_report.h" #include "IScheduler.h" #include "../core/ControllerCore.h" #include "../core/configuration/Configuration.h" #include "../../common/dramExtension.h" +#define MIN_TOTAL_REQ 16 + using namespace std; class SMS: public sc_module, public IScheduler { public: - SMS(ControllerCore &controllerCore, unsigned int SJFprobability) : IScheduler(controllerCore), SJFprobability(SJFprobability){} + SMS(ControllerCore &controllerCore, unsigned int SJFprobability) : IScheduler(controllerCore), SJFprobability(SJFprobability) + { + // initialize memory request counter & memory request intensity for each thread + auto totalNumThreads = Configuration::getInstance().NumberOfTracePlayers; + for (auto threadID = 1; threadID <= totalNumThreads; threadID++) + { + memrequestcounter.emplace(Thread(threadID), 0); + memoryIntensity.emplace(Thread(threadID), 0); + } + } virtual ~SMS(){} virtual void schedule(gp *payload) override; virtual std::pair getNextRequest(Bank bank) override; @@ -19,8 +33,20 @@ public: private: std::map> buffer; std::map> bankbuffer; - + std::map readybatches; + std::map memrequestcounter; + std::map inFlightMemRequestCounter; + std::map memoryIntensity; unsigned int SJFprobability; + + void batchScheduler(); + unsigned int totalMemoryRequests(); + void batchFormation(); + void selectSJF(); + void selectRR(); + bool existReadyBatch(); + void batchFormation(Thread thread); + void bypassRequests(); }; #endif // SMS_H From a11276c87658b7df45352d3a88eaa22c51ffadf7 Mon Sep 17 00:00:00 2001 From: Johannes Feldmann Date: Thu, 2 Mar 2017 20:18:36 +0100 Subject: [PATCH 10/59] ECC Controller umgebaut. Testumgebung angepasst. Weak cells manuell gesetzt. --- DRAMSys/simulator/library.pro | 3 +- .../resources/configs/mcconfigs/fifo_ecc.xml | 20 ++++++ .../configs/memspecs/wideio_less_refresh.xml | 61 +++++++++++++++++++ .../configs/simulator/wideio_ecc.xml | 15 +++++ DRAMSys/simulator/resources/resources.pri | 7 +++ .../resources/simulations/wideio-ecc.xml | 22 +++++++ .../core/configuration/Configuration.cpp | 2 + .../core/configuration/Configuration.h | 1 + DRAMSys/simulator/src/error/controllerECC.h | 59 ++++++++++-------- DRAMSys/simulator/src/error/errormodel.cpp | 20 ++++++ DRAMSys/simulator/src/simulation/DRAMSys.cpp | 57 +++++++++++------ DRAMSys/simulator/src/simulation/main.cpp | 2 +- 12 files changed, 221 insertions(+), 48 deletions(-) create mode 100644 DRAMSys/simulator/resources/configs/mcconfigs/fifo_ecc.xml create mode 100644 DRAMSys/simulator/resources/configs/memspecs/wideio_less_refresh.xml create mode 100644 DRAMSys/simulator/resources/configs/simulator/wideio_ecc.xml create mode 100644 DRAMSys/simulator/resources/simulations/wideio-ecc.xml diff --git a/DRAMSys/simulator/library.pro b/DRAMSys/simulator/library.pro index 0a930c9a..5a25d3ff 100644 --- a/DRAMSys/simulator/library.pro +++ b/DRAMSys/simulator/library.pro @@ -163,7 +163,8 @@ HEADERS += \ src/controller/core/powerdown/PowerDownManagerTimeoutBankwise.h \ src/simulation/TraceSetup.h \ src/simulation/DRAMSys.h \ - src/simulation/Setup.h + src/simulation/Setup.h \ + src/error/controllerECC.h thermalsim = $$(THERMALSIM) isEmpty(thermalsim) { diff --git a/DRAMSys/simulator/resources/configs/mcconfigs/fifo_ecc.xml b/DRAMSys/simulator/resources/configs/mcconfigs/fifo_ecc.xml new file mode 100644 index 00000000..d6acf112 --- /dev/null +++ b/DRAMSys/simulator/resources/configs/mcconfigs/fifo_ecc.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + diff --git a/DRAMSys/simulator/resources/configs/memspecs/wideio_less_refresh.xml b/DRAMSys/simulator/resources/configs/memspecs/wideio_less_refresh.xml new file mode 100644 index 00000000..f8aa3190 --- /dev/null +++ b/DRAMSys/simulator/resources/configs/memspecs/wideio_less_refresh.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DRAMSys/simulator/resources/configs/simulator/wideio_ecc.xml b/DRAMSys/simulator/resources/configs/simulator/wideio_ecc.xml new file mode 100644 index 00000000..4b8ad3d1 --- /dev/null +++ b/DRAMSys/simulator/resources/configs/simulator/wideio_ecc.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/DRAMSys/simulator/resources/resources.pri b/DRAMSys/simulator/resources/resources.pri index fc1d85c7..37b75724 100644 --- a/DRAMSys/simulator/resources/resources.pri +++ b/DRAMSys/simulator/resources/resources.pri @@ -134,3 +134,10 @@ OTHER_FILES += resources/configs/thermalsim/mem.flp OTHER_FILES += resources/configs/thermalsim/powerInfo.xml OTHER_FILES += resources/configs/thermalsim/stack.stk OTHER_FILES += resources/configs/thermalsim/config.xml + +DISTFILES += \ + $$PWD/configs/simulator/wideio_ecc.xml \ + $$PWD/configs/mcconfigs/fifo_ecc.xml \ + $$PWD/simulations/wideio-ecc.xml \ + $$PWD/traces/test_ecc.stl \ + $$PWD/configs/memspecs/wideio_less_refresh.xml diff --git a/DRAMSys/simulator/resources/simulations/wideio-ecc.xml b/DRAMSys/simulator/resources/simulations/wideio-ecc.xml new file mode 100644 index 00000000..ead21319 --- /dev/null +++ b/DRAMSys/simulator/resources/simulations/wideio-ecc.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + test_ecc.stl + + diff --git a/DRAMSys/simulator/src/controller/core/configuration/Configuration.cpp b/DRAMSys/simulator/src/controller/core/configuration/Configuration.cpp index 1a7feaa4..85f0a250 100644 --- a/DRAMSys/simulator/src/controller/core/configuration/Configuration.cpp +++ b/DRAMSys/simulator/src/controller/core/configuration/Configuration.cpp @@ -187,6 +187,8 @@ void Configuration::setParameter(std::string name, std::string value) NumberOfDevicesOnDIMM = string2int(value); else if(name == "CheckTLM2Protocol") CheckTLM2Protocol = string2bool(value); + else if(name == "EnableControllerECC") + EnableControllerECC = string2bool(value); // Specification for ErrorChipSeed, ErrorCSVFile path and StoreMode else if(name == "ErrorChipSeed") ErrorChipSeed = string2int(value); diff --git a/DRAMSys/simulator/src/controller/core/configuration/Configuration.h b/DRAMSys/simulator/src/controller/core/configuration/Configuration.h index 40c24b8a..bff51af5 100644 --- a/DRAMSys/simulator/src/controller/core/configuration/Configuration.h +++ b/DRAMSys/simulator/src/controller/core/configuration/Configuration.h @@ -81,6 +81,7 @@ struct Configuration bool SimulationProgressBar = false; unsigned int NumberOfDevicesOnDIMM = 1; bool CheckTLM2Protocol = false; + bool EnableControllerECC = false; // MemSpec (from DRAM-Power XML) MemSpec memSpec; diff --git a/DRAMSys/simulator/src/error/controllerECC.h b/DRAMSys/simulator/src/error/controllerECC.h index b9dd772e..0a33c1c1 100644 --- a/DRAMSys/simulator/src/error/controllerECC.h +++ b/DRAMSys/simulator/src/error/controllerECC.h @@ -12,7 +12,7 @@ using namespace tlm; struct ControllerECC: sc_module { private: - map m_mBuffer; + map> m_mBuffer; public: tlm_utils::multi_passthrough_target_socket t_socket; @@ -29,38 +29,45 @@ public: // Forward interface virtual tlm::tlm_sync_enum nb_transport_fw( int id, tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_time& delay ) { - if(trans.get_command() == TLM_WRITE_COMMAND) - { - // Save all Bytes - for(unsigned i = 0; i < trans.get_data_length(); i++) - { - m_mBuffer[trans.get_address() + i] = *(trans.get_data_ptr() + i); - } - } - return i_socket[id]->nb_transport_fw( trans, phase, delay ); + if(trans.get_command() == TLM_WRITE_COMMAND) + { + // Allocate memory if necessary + if(m_mBuffer[trans.get_address()].size() != trans.get_data_length()) + m_mBuffer[trans.get_address()].resize(trans.get_data_length()); + + // Copy data + memcpy(m_mBuffer[trans.get_address()].data(), trans.get_data_ptr(), trans.get_data_length()); + } + return i_socket[id]->nb_transport_fw( trans, phase, delay ); } // Backward interface virtual tlm::tlm_sync_enum nb_transport_bw( int id, tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_time& delay ) { - if(trans.get_command() == TLM_WRITE_COMMAND) - { - // Compare all Bytes - for(unsigned i = 0; i < trans.get_data_length(); i++) - { - if(m_mBuffer[trans.get_address() + i] != *(trans.get_data_ptr() + i)) - { - std::stringstream msg; - msg << "Error Detected: Address: 0x" << hex << trans.get_address() + i - << "\n\t\tData Read: 0x" << hex << (int)*(trans.get_data_ptr() + i) - << "\n\t\tData original: 0x" << hex << (int)m_mBuffer[trans.get_address() + i]; - - DebugManager::getInstance().printDebugMessage(name(), msg.str()); - } - } - } + if(trans.get_command() == TLM_READ_COMMAND && phase == 3) + { + if(m_mBuffer[trans.get_address()].size() == trans.get_data_length()) + { + // Data can be compared, they got the same size + int error = memcmp(m_mBuffer[trans.get_address()].data(), trans.get_data_ptr(), trans.get_data_length()); + if(error) + { + // Data not equal + cout << "\nError Detected: Address: 0x" << hex << trans.get_address(); + for(unsigned n = 0; n < trans.get_data_length(); n++) + { + if(m_mBuffer[trans.get_address()].data()[n] != trans.get_data_ptr()[n]) + { + cout << "\n\t\tError Byte " << dec << n << " Orig: 0x" << hex << (int)m_mBuffer[trans.get_address()].data()[n] + << " Read: 0x" << hex << (int)trans.get_data_ptr()[n]; + } + } + cout << endl; + } + } + } return t_socket[id]->nb_transport_bw( trans, phase, delay ); } }; diff --git a/DRAMSys/simulator/src/error/errormodel.cpp b/DRAMSys/simulator/src/error/errormodel.cpp index 4e397377..91eb789b 100644 --- a/DRAMSys/simulator/src/error/errormodel.cpp +++ b/DRAMSys/simulator/src/error/errormodel.cpp @@ -105,6 +105,26 @@ void errorModel::init() //weakCells[0].row = 0; //weakCells[0].dependent = true; + weakCells[0].bit = 0; + weakCells[0].col = 0; + weakCells[0].row = 0; + weakCells[0].dependent = false; + + weakCells[0].bit = 5; + weakCells[0].col = 0; + weakCells[0].row = 0; + weakCells[0].dependent = false; + + weakCells[0].bit = 12; + weakCells[0].col = 0; + weakCells[0].row = 0; + weakCells[0].dependent = false; + + weakCells[0].bit = 22; + weakCells[0].col = 0; + weakCells[0].row = 0; + weakCells[0].dependent = false; + markBitFlips(); } diff --git a/DRAMSys/simulator/src/simulation/DRAMSys.cpp b/DRAMSys/simulator/src/simulation/DRAMSys.cpp index 41b80d42..0cb5bbc5 100644 --- a/DRAMSys/simulator/src/simulation/DRAMSys.cpp +++ b/DRAMSys/simulator/src/simulation/DRAMSys.cpp @@ -58,6 +58,9 @@ DRAMSys::DRAMSys(sc_module_name __attribute__((unused)) name, string simulationToRun, string pathToResources) : tSocket("DRAMSys_tSocket") { + // Initialize ecc pointer + ecc = 0; + logo(); // Read Configuration Setup: @@ -185,6 +188,10 @@ void DRAMSys::instantiateModules(const string &traceName, // They need to be ready before creating some modules. setupTlmRecorders(traceName, pathToResources); + // Initialize ECC Controller is enabled + if(Configuration::getInstance().EnableControllerECC) + ecc = new ControllerECC("ControllerECC"); + arbiter = new Arbiter("arbiter"); arbiter->setTlmRecorders(tlmRecorders); @@ -214,35 +221,45 @@ void DRAMSys::instantiateModules(const string &traceName, void DRAMSys::bindSockets() { - tSocket.bind(arbiter->tSocket); + // If ECC Controller enabled, put it between Trace and arbiter + if(Configuration::getInstance().EnableControllerECC) + { + tSocket.bind(ecc->t_socket); + ecc->i_socket.bind(arbiter->tSocket); + } + else + { + tSocket.bind(arbiter->tSocket); + } - if(Configuration::getInstance().CheckTLM2Protocol) + if(Configuration::getInstance().CheckTLM2Protocol) + { + for (size_t i = 0; + i < Configuration::getInstance().NumberOfMemChannels; + i++) { - for (size_t i = 0; - i < Configuration::getInstance().NumberOfMemChannels; - i++) - { - arbiter->iSocket.bind(controllersTlmCheckers[i]->target_socket); - controllersTlmCheckers[i]->initiator_socket.bind( - controllers[i]->tSocket); - controllers[i]->iSocket.bind(drams[i]->tSocket); - } + arbiter->iSocket.bind(controllersTlmCheckers[i]->target_socket); + controllersTlmCheckers[i]->initiator_socket.bind( + controllers[i]->tSocket); + controllers[i]->iSocket.bind(drams[i]->tSocket); } - else + } + else + { + for (size_t i = 0; + i < Configuration::getInstance().NumberOfMemChannels; + i++) { - for (size_t i = 0; - i < Configuration::getInstance().NumberOfMemChannels; - i++) - { - arbiter->iSocket.bind(controllers[i]->tSocket); - controllers[i]->iSocket.bind(drams[i]->tSocket); - } + arbiter->iSocket.bind(controllers[i]->tSocket); + controllers[i]->iSocket.bind(drams[i]->tSocket); } + } } DRAMSys::~DRAMSys() { - + if(ecc) + delete ecc; delete arbiter; for (auto controller : controllers) diff --git a/DRAMSys/simulator/src/simulation/main.cpp b/DRAMSys/simulator/src/simulation/main.cpp index 18e00f77..18b474e9 100644 --- a/DRAMSys/simulator/src/simulation/main.cpp +++ b/DRAMSys/simulator/src/simulation/main.cpp @@ -72,7 +72,7 @@ int sc_main(int argc, char **argv) } else { - SimulationXML = resources + "simulations/ddr3-example.xml"; + SimulationXML = resources + "simulations/wideio-ecc.xml"; } std::vector players; From 725d7e9d19fa88e66519924626503f260bd05e06 Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Fri, 3 Mar 2017 03:20:37 +0100 Subject: [PATCH 11/59] Fix compile errors & warnings # Explain what has been changed # Explain why this change is being made # Provide links to any relevant tickets, articles or other resources --- .../analyzer/businessObjects/phases/phase.h | 14 ++++++------- DRAMSys/analyzer/businessObjects/timespan.h | 3 ++- .../src/common/tlm2_base_protocol_checker.h | 6 +++--- DRAMSys/simulator/src/controller/Controller.h | 2 +- .../src/controller/scheduler/ReadyBatch.cpp | 4 ++-- .../src/controller/scheduler/SMS.cpp | 20 +++++++++---------- .../simulator/src/controller/scheduler/SMS.h | 5 +++-- 7 files changed, 28 insertions(+), 26 deletions(-) diff --git a/DRAMSys/analyzer/businessObjects/phases/phase.h b/DRAMSys/analyzer/businessObjects/phases/phase.h index 62c5ea27..ef8d187a 100644 --- a/DRAMSys/analyzer/businessObjects/phases/phase.h +++ b/DRAMSys/analyzer/businessObjects/phases/phase.h @@ -180,7 +180,7 @@ public: using AUTO_REFRESH::AUTO_REFRESH; protected: virtual QString Name() const override {return "REFA";} - virtual bool isBankwise() const {return false;} + virtual bool isBankwise() const override {return false;} }; class REFB : public AUTO_REFRESH @@ -201,7 +201,7 @@ protected: virtual std::vector getTimesOnCommandBus() const {return {span.Begin()};} virtual QColor getColor(const TraceDrawingProperties &drawingProperties) const override {Q_UNUSED(drawingProperties) return getPhaseColor();} virtual QColor getPhaseColor() const override {return ColorGenerator::getColor(10);} - virtual bool isBankwise() const {return false;} + virtual bool isBankwise() const override {return false;} }; class PDNAB : public Phase @@ -222,7 +222,7 @@ public: using PDNAB::PDNAB; protected: virtual QString Name() const override {return "PDNA";} - virtual bool isBankwise() const {return false;} + virtual bool isBankwise() const override {return false;} }; class PDNPB : public Phase @@ -243,7 +243,7 @@ public: using PDNPB::PDNPB; protected: virtual QString Name() const override {return "PDNP";} - virtual bool isBankwise() const {return false;} + virtual bool isBankwise() const override {return false;} }; class SREFB : public Phase @@ -251,8 +251,8 @@ class SREFB : public Phase public: using Phase::Phase; protected: - virtual QString Name() const {return "SREFB";} - virtual Qt::BrushStyle getBrushStyle() const {return Qt::Dense1Pattern;} + virtual QString Name() const override {return "SREFB";} + virtual Qt::BrushStyle getBrushStyle() const override {return Qt::Dense1Pattern;} virtual QColor getColor(const TraceDrawingProperties &drawingProperties) const override {Q_UNUSED(drawingProperties) return getPhaseColor();} virtual QColor getPhaseColor() const override {return QColor(Qt::black);} virtual Phase::PhaseSymbol getPhaseSymbol() const override {return PhaseSymbol::Rect;} @@ -264,7 +264,7 @@ public: using SREFB::SREFB; protected: virtual QString Name() const override {return "SREF";} - virtual bool isBankwise() const {return false;} + virtual bool isBankwise() const override {return false;} }; diff --git a/DRAMSys/analyzer/businessObjects/timespan.h b/DRAMSys/analyzer/businessObjects/timespan.h index c54f99b0..dcc32839 100644 --- a/DRAMSys/analyzer/businessObjects/timespan.h +++ b/DRAMSys/analyzer/businessObjects/timespan.h @@ -38,6 +38,7 @@ #ifndef TIMESPAN_H #define TIMESPAN_H #include +#include #include "tracetime.h" class Timespan @@ -47,7 +48,7 @@ class Timespan public: Timespan(traceTime begin = 0, traceTime end = 0) : begin(begin), end(end){} - traceTime timeCovered() const{return abs(End()-Begin());} + traceTime timeCovered() const{return std::abs(End()-Begin());} traceTime Begin() const{return begin;} void setBegin(traceTime time){begin = time;} traceTime End() const{return end;} diff --git a/DRAMSys/simulator/src/common/tlm2_base_protocol_checker.h b/DRAMSys/simulator/src/common/tlm2_base_protocol_checker.h index eb0833a1..99b5ce10 100755 --- a/DRAMSys/simulator/src/common/tlm2_base_protocol_checker.h +++ b/DRAMSys/simulator/src/common/tlm2_base_protocol_checker.h @@ -343,7 +343,7 @@ void tlm2_base_protocol_checker:: BOILERPLATE b_transport_pre_checks( - tlm::tlm_generic_payload& trans, sc_core::sc_time& delay) + tlm::tlm_generic_payload& trans, sc_core::sc_time& /*delay*/) { ++ m_map[&trans].b_call; @@ -372,7 +372,7 @@ b_transport_pre_checks( BOILERPLATE b_transport_post_checks( - tlm::tlm_generic_payload& trans, sc_core::sc_time& delay) + tlm::tlm_generic_payload& trans, sc_core::sc_time& /*delay*/) { check_response_path(trans, "b_transport"); check_trans_not_modified(trans, "b_transport"); @@ -914,7 +914,7 @@ get_direct_mem_ptr_pre_checks( BOILERPLATE -get_direct_mem_ptr_post_checks( tlm::tlm_generic_payload& trans, tlm::tlm_dmi& dmi_data ) +get_direct_mem_ptr_post_checks( tlm::tlm_generic_payload& trans, tlm::tlm_dmi& /*dmi_data*/ ) { tlm::tlm_generic_payload* init = m_map[&trans].gp; diff --git a/DRAMSys/simulator/src/controller/Controller.h b/DRAMSys/simulator/src/controller/Controller.h index a1286d1f..77de4bf3 100644 --- a/DRAMSys/simulator/src/controller/Controller.h +++ b/DRAMSys/simulator/src/controller/Controller.h @@ -110,7 +110,7 @@ private: void buildScheduler(); void payloadEntersSystem(tlm_generic_payload& payload); void payloadLeavesSystem(tlm_generic_payload& payload); - void scheduleNextFromScheduler(Bank bank); + void scheduleNextFromScheduler(Bank bank) override; // --- FRONTEND ------ tlm_sync_enum nb_transport_fw(tlm_generic_payload& payload, tlm_phase& phase, sc_time& fwDelay); diff --git a/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp index 84af0d69..2200a6f4 100644 --- a/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp @@ -3,7 +3,7 @@ ReadyBatch::ReadyBatch() { fifosize = Configuration::getInstance().ReadyBatchSize; - thresholdAge(Configuration::getInstance().ReadyBatchThresholdAge, SC_NS); + thresholdAge = sc_time(Configuration::getInstance().ReadyBatchThresholdAge, SC_NS); } unsigned int ReadyBatch::getNumRequests() @@ -34,7 +34,7 @@ bool ReadyBatch::addTransaction(gp* payload) { sc_time currentAge = sc_time_stamp() - getTimeOfOldestRequest(); Row newRow = DramExtension::getExtension(payload).getRow(); - if (getNumRequests == fifosize || currentAge >= thresholdAge || newRow != getRow()) { + if (getNumRequests() == fifosize || currentAge >= thresholdAge || newRow != getRow()) { return false; } else { readybatch.emplace_back(payload); diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index 252300b1..7e9fd5b5 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -58,8 +58,8 @@ void SMS::batchFormation() } else { - auto totalNumThreads = Configuration::getInstance().NumberOfTracePlayers; - for (auto threadID = 1; threadID <= totalNumThreads; threadID++) + unsigned int totalNumThreads = Configuration::getInstance().NumberOfTracePlayers; + for (unsigned int threadID = 1; threadID <= totalNumThreads; threadID++) { batchFormation(Thread(threadID)); } @@ -86,7 +86,7 @@ void SMS::batchScheduler() batchFormation(); if (isSJF) { - selectSJF() + selectSJF(); } else { @@ -96,7 +96,7 @@ void SMS::batchScheduler() } else if (isSJF) { - selectSJF() + selectSJF(); } else { @@ -108,9 +108,9 @@ void SMS::batchScheduler() void SMS::selectSJF() { // find shorstest thread - unsigned int minThread = 1 - auto totalNumThreads = Configuration::getInstance().NumberOfTracePlayers; - for (auto threadID = 2; threadID <= totalNumThreads; threadID++) + unsigned int minThread = 1; + unsigned int totalNumThreads = Configuration::getInstance().NumberOfTracePlayers; + for (unsigned int threadID = 2; threadID <= totalNumThreads; threadID++) { if (memrequestcounter[Thread(threadID)] <= memrequestcounter[Thread(minThread)]) { @@ -123,7 +123,7 @@ void SMS::selectSJF() for (auto intr = requestPtrs.begin(); intr != requestPtrs.end(); intr++) { Bank bank = DramExtension::getExtension(*intr).getBank(); - bankbuffer.emplace(bank, *intr); + bankbuffer[bank].emplace_back(*intr); } requestPtrs.clear(); @@ -140,7 +140,7 @@ void SMS::selectRR() for (auto intr = requestPtrs.begin(); intr != requestPtrs.end(); intr++) { Bank bank = DramExtension::getExtension(*intr).getBank(); - bankbuffer.emplace(bank, *intr); + bankbuffer[bank].emplace_back(*intr); } requestPtrs.clear(); @@ -192,7 +192,7 @@ void SMS::bypassRequests() for(auto request = thread_requests.second.begin(); request != thread_requests.second.end(); request++) { Bank bank = DramExtension::getExtension(*request).getBank(); - bankbuffer[bank].emplace_back(request); + bankbuffer[bank].emplace_back(*request); thread_requests.second.erase(request); } } diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h index 9f871776..6b7853a6 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.h +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h @@ -5,6 +5,7 @@ #include #include "sysc/utils/sc_report.h" #include "IScheduler.h" +#include "ReadyBatch.h" #include "../core/ControllerCore.h" #include "../core/configuration/Configuration.h" #include "../../common/dramExtension.h" @@ -19,8 +20,8 @@ public: SMS(ControllerCore &controllerCore, unsigned int SJFprobability) : IScheduler(controllerCore), SJFprobability(SJFprobability) { // initialize memory request counter & memory request intensity for each thread - auto totalNumThreads = Configuration::getInstance().NumberOfTracePlayers; - for (auto threadID = 1; threadID <= totalNumThreads; threadID++) + unsigned int totalNumThreads = Configuration::getInstance().NumberOfTracePlayers; + for (unsigned int threadID = 1; threadID <= totalNumThreads; threadID++) { memrequestcounter.emplace(Thread(threadID), 0); memoryIntensity.emplace(Thread(threadID), 0); From 73eb716deb50dd2789d97b871791657e5a3e55db Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Fri, 3 Mar 2017 03:32:18 +0100 Subject: [PATCH 12/59] Implement batch scheduler as a SYSTEMC process # Explain what has been changed # Explain why this change is being made # Provide links to any relevant tickets, articles or other resources --- DRAMSys/simulator/src/controller/scheduler/SMS.cpp | 3 +++ DRAMSys/simulator/src/controller/scheduler/SMS.h | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index 7e9fd5b5..4e8a86fb 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -68,8 +68,11 @@ void SMS::batchFormation() void SMS::batchScheduler() { + sc_time memClk = Configuration::getInstance().memSpec.clk; while (true) { + wait(memClk); + srand(time(NULL)); bool isSJF = (rand() % 100) < SJFprobability; if (!existReadyBatch()) diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h index 6b7853a6..bb60f447 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.h +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h @@ -26,10 +26,13 @@ public: memrequestcounter.emplace(Thread(threadID), 0); memoryIntensity.emplace(Thread(threadID), 0); } + SC_THREAD(batchScheduler); } + SC_HAS_PROCESS(SMS); virtual ~SMS(){} virtual void schedule(gp *payload) override; virtual std::pair getNextRequest(Bank bank) override; + void batchScheduler(); private: std::map> buffer; @@ -40,7 +43,6 @@ private: std::map memoryIntensity; unsigned int SJFprobability; - void batchScheduler(); unsigned int totalMemoryRequests(); void batchFormation(); void selectSJF(); From ee006952de61c95ec1114ef8ae2b115ee089c991 Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Wed, 8 Mar 2017 00:11:47 +0100 Subject: [PATCH 13/59] Safeguard against empty buffer & bypass low memory intensity request # Explain what has been changed # Explain why this change is being made # Provide links to any relevant tickets, articles or other resources --- .../src/controller/scheduler/SMS.cpp | 111 ++++++++++++------ .../simulator/src/controller/scheduler/SMS.h | 5 +- 2 files changed, 77 insertions(+), 39 deletions(-) diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index 4e8a86fb..4790edb7 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -50,19 +50,22 @@ unsigned int SMS::totalMemoryRequests() return totalSize; } -void SMS::batchFormation() +bool SMS::batchFormation() { if (existReadyBatch()) { + return false; SC_REPORT_FATAL("SMS", "Form ready batches when exist at least a ready batch"); } else { + bool isBatchForm = false; unsigned int totalNumThreads = Configuration::getInstance().NumberOfTracePlayers; for (unsigned int threadID = 1; threadID <= totalNumThreads; threadID++) { - batchFormation(Thread(threadID)); + isBatchForm = isBatchForm || batchFormation(Thread(threadID)); } + return isBatchForm; } } @@ -77,33 +80,31 @@ void SMS::batchScheduler() 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? + if (totalMemoryRequests() == 0) { + continue; + } + else if (totalMemoryRequests() <= 16 && totalMemoryRequests() > 0) + { + // bypass if system is lightly load bypassRequests(); } - else + else if (totalMemoryRequests() > 16) { - batchFormation(); - if (isSJF) + // bypass low memory intensity thread + bypassLowMemoryIntensity(); + + // pick & drain a ready batch + if (batchFormation()) { - selectSJF(); - } - else - { - selectRR(); + isSJF ? selectSJF() : selectRR(); } } } - else if (isSJF) - { - selectSJF(); - } else { - selectRR(); + // pick & drain a ready batch + isSJF ? selectSJF() : selectRR(); } } } @@ -115,7 +116,7 @@ void SMS::selectSJF() unsigned int totalNumThreads = Configuration::getInstance().NumberOfTracePlayers; for (unsigned int threadID = 2; threadID <= totalNumThreads; threadID++) { - if (memrequestcounter[Thread(threadID)] <= memrequestcounter[Thread(minThread)]) + if (inFlightMemRequestCounter[Thread(threadID)] <= inFlightMemRequestCounter[Thread(minThread)]) { minThread = threadID; } @@ -123,12 +124,15 @@ void SMS::selectSJF() // drain to bank buffers std::deque requestPtrs = readybatches[Thread(minThread)]->getTransactions(); - for (auto intr = requestPtrs.begin(); intr != requestPtrs.end(); intr++) + if (!requestPtrs.empty()) { - Bank bank = DramExtension::getExtension(*intr).getBank(); - bankbuffer[bank].emplace_back(*intr); + for (auto intr = requestPtrs.begin(); intr != requestPtrs.end(); intr++) + { + Bank bank = DramExtension::getExtension(*intr).getBank(); + bankbuffer[bank].emplace_back(*intr); + } + requestPtrs.clear(); } - requestPtrs.clear(); // reform the drained ready batch // batchFormation(Thread(minThread)); @@ -140,25 +144,38 @@ void SMS::selectRR() // drain to bank buffers std::deque requestPtrs = (*next).second->getTransactions(); - for (auto intr = requestPtrs.begin(); intr != requestPtrs.end(); intr++) + if (!requestPtrs.empty()) { - Bank bank = DramExtension::getExtension(*intr).getBank(); - bankbuffer[bank].emplace_back(*intr); + for (auto intr = requestPtrs.begin(); intr != requestPtrs.end(); intr++) + { + Bank bank = DramExtension::getExtension(*intr).getBank(); + bankbuffer[bank].emplace_back(*intr); + } + requestPtrs.clear(); } - requestPtrs.clear(); // reform the drained ready batch // batchFormation((*next).first); // point to next pair - do + if (existReadyBatch()) { - next++; - if (next == readybatches.end()) + do { - next = readybatches.begin(); - } - } while ((*next).second->isEmpty()); + 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() @@ -173,10 +190,11 @@ bool SMS::existReadyBatch() return false; } -void SMS::batchFormation(Thread thread) +bool SMS::batchFormation(Thread thread) { if (!readybatches[thread]->isEmpty()) { + return false; SC_REPORT_FATAL("SMS", "Ready batch formation for non empty ready batch"); } else @@ -185,14 +203,15 @@ void SMS::batchFormation(Thread thread) { buffer[thread].pop_front(); } + return !readybatches[thread]->isEmpty(); } } void SMS::bypassRequests() { - for(auto& thread_requests : buffer) + for (auto& thread_requests : buffer) { - for(auto request = thread_requests.second.begin(); request != thread_requests.second.end(); request++) + for (auto request = thread_requests.second.begin(); request != thread_requests.second.end(); request++) { Bank bank = DramExtension::getExtension(*request).getBank(); bankbuffer[bank].emplace_back(*request); @@ -200,3 +219,21 @@ void SMS::bypassRequests() } } } + +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); + } + } + } +} diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h index bb60f447..7989bd08 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.h +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h @@ -44,12 +44,13 @@ private: unsigned int SJFprobability; unsigned int totalMemoryRequests(); - void batchFormation(); + bool batchFormation(); void selectSJF(); void selectRR(); bool existReadyBatch(); - void batchFormation(Thread thread); + bool batchFormation(Thread thread); void bypassRequests(); + void bypassLowMemoryIntensity(); }; #endif // SMS_H From 37435b6285bdfc76bd90bd60e8487fc2e9698318 Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Wed, 8 Mar 2017 00:19:36 +0100 Subject: [PATCH 14/59] Initialize in-flight memory request counters # Explain what has been changed # Explain why this change is being made # Provide links to any relevant tickets, articles or other resources --- DRAMSys/simulator/src/controller/scheduler/SMS.h | 1 + 1 file changed, 1 insertion(+) diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h index 7989bd08..00fe6877 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.h +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h @@ -25,6 +25,7 @@ public: { memrequestcounter.emplace(Thread(threadID), 0); memoryIntensity.emplace(Thread(threadID), 0); + inFlightMemRequestCounter.emplace(Thread(threadID), 0); } SC_THREAD(batchScheduler); } From a0227b2a6005f15cf12fbb9406c7c8a3b1b0458b Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Wed, 8 Mar 2017 23:50:19 +0100 Subject: [PATCH 15/59] Remove unnecessary functions, keep it simple for testing # Explain what has been changed # Explain why this change is being made # Provide links to any relevant tickets, articles or other resources --- .../src/controller/scheduler/ReadyBatch.cpp | 38 +++--- .../src/controller/scheduler/ReadyBatch.h | 4 +- .../src/controller/scheduler/SMS.cpp | 109 ++++++++---------- .../simulator/src/controller/scheduler/SMS.h | 14 +-- 4 files changed, 75 insertions(+), 90 deletions(-) diff --git a/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp index 2200a6f4..91aa48db 100644 --- a/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp @@ -6,35 +6,35 @@ ReadyBatch::ReadyBatch() thresholdAge = sc_time(Configuration::getInstance().ReadyBatchThresholdAge, SC_NS); } -unsigned int ReadyBatch::getNumRequests() -{ - return readybatch.size(); -} +//unsigned int ReadyBatch::getNumRequests() +//{ +// return readybatch.size(); +//} Row ReadyBatch::getRow() { return DramExtension::getExtension(readybatch.front()).getRow(); } -sc_time ReadyBatch::getTimeOfOldestRequest() -{ - sc_time oldestTime = sc_time_stamp(); - for (auto reqPayload = readybatch.begin(); reqPayload != readybatch.end(); reqPayload++) - { - sc_time requestTimeOfGeneration = GenerationExtension::getExtension(*reqPayload).TimeOfGeneration(); - if (requestTimeOfGeneration < oldestTime) - { - oldestTime = requestTimeOfGeneration; - } - } - return oldestTime; -} +//sc_time ReadyBatch::getTimeOfOldestRequest() +//{ +// sc_time oldestTime = sc_time_stamp(); +// for (auto reqPayload = readybatch.begin(); reqPayload != readybatch.end(); reqPayload++) +// { +// sc_time requestTimeOfGeneration = GenerationExtension::getExtension(*reqPayload).TimeOfGeneration(); +// if (requestTimeOfGeneration < oldestTime) +// { +// oldestTime = requestTimeOfGeneration; +// } +// } +// return oldestTime; +//} bool ReadyBatch::addTransaction(gp* payload) { - sc_time currentAge = sc_time_stamp() - getTimeOfOldestRequest(); +// sc_time currentAge = sc_time_stamp() - getTimeOfOldestRequest(); Row newRow = DramExtension::getExtension(payload).getRow(); - if (getNumRequests() == fifosize || currentAge >= thresholdAge || newRow != getRow()) { + if (/*getNumRequests() == fifosize || currentAge >= thresholdAge || */newRow != getRow()) { return false; } else { readybatch.emplace_back(payload); diff --git a/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.h b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.h index 5e2e8f49..c35640a5 100644 --- a/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.h +++ b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.h @@ -14,7 +14,7 @@ class ReadyBatch public: ReadyBatch(); bool addTransaction(gp* payload); - unsigned int getNumRequests(); +// unsigned int getNumRequests(); std::deque& getTransactions(); bool isEmpty(); private: @@ -23,7 +23,7 @@ private: sc_time thresholdAge; Row getRow(); - sc_time getTimeOfOldestRequest(); +// sc_time getTimeOfOldestRequest(); }; #endif // READYBATCH_H diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index 4790edb7..147cea6e 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -8,13 +8,13 @@ void SMS::schedule(gp *payload) Thread thread = DramExtension::getExtension(payload).getThread(); // update memory request counter - memrequestcounter[thread]++; +// 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 +// 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 SMS::getNextRequest(Bank bank) @@ -39,16 +39,16 @@ std::pair 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; -} +//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; +//} bool SMS::batchFormation() { @@ -80,25 +80,10 @@ void SMS::batchScheduler() bool isSJF = (rand() % 100) < SJFprobability; if (!existReadyBatch()) { - if (totalMemoryRequests() == 0) + // pick & drain a ready batch + if (batchFormation()) { - continue; - } - else if (totalMemoryRequests() <= 16 && totalMemoryRequests() > 0) - { - // bypass if system is lightly load - bypassRequests(); - } - else if (totalMemoryRequests() > 16) - { - // bypass low memory intensity thread - bypassLowMemoryIntensity(); - - // pick & drain a ready batch - if (batchFormation()) - { - isSJF ? selectSJF() : selectRR(); - } + isSJF ? selectSJF() : selectRR(); } } else @@ -207,33 +192,33 @@ 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::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); +// } +// } +// } +//} diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h index 00fe6877..71f7aa96 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.h +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h @@ -23,8 +23,8 @@ 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); +// memrequestcounter.emplace(Thread(threadID), 0); +// memoryIntensity.emplace(Thread(threadID), 0); inFlightMemRequestCounter.emplace(Thread(threadID), 0); } SC_THREAD(batchScheduler); @@ -39,19 +39,19 @@ private: std::map> buffer; std::map> bankbuffer; std::map readybatches; - std::map memrequestcounter; +// std::map memrequestcounter; std::map inFlightMemRequestCounter; - std::map memoryIntensity; +// std::map memoryIntensity; unsigned int SJFprobability; - unsigned int totalMemoryRequests(); +// unsigned int totalMemoryRequests(); bool batchFormation(); void selectSJF(); void selectRR(); bool existReadyBatch(); bool batchFormation(Thread thread); - void bypassRequests(); - void bypassLowMemoryIntensity(); +// void bypassRequests(); +// void bypassLowMemoryIntensity(); }; #endif // SMS_H From 904ee688be8f5b1c5674e6acc205f2ae18482df2 Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Mon, 13 Mar 2017 17:33:49 +0100 Subject: [PATCH 16/59] Add test traces # Explain what has been changed # Explain why this change is being made # Provide links to any relevant tickets, articles or other resources --- DRAMSys/simulator/resources/simulations/sim-batch.xml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/DRAMSys/simulator/resources/simulations/sim-batch.xml b/DRAMSys/simulator/resources/simulations/sim-batch.xml index dcc783d9..fbd47695 100644 --- a/DRAMSys/simulator/resources/simulations/sim-batch.xml +++ b/DRAMSys/simulator/resources/simulations/sim-batch.xml @@ -6,7 +6,7 @@ - + @@ -44,7 +44,10 @@ - chstone-adpcm_32.stl + t1.stl + t2.stl + t3.stl + t4.stl From 7626b8b6b5a410aff0ff80325bc1dcc24f6ace07 Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Mon, 13 Mar 2017 17:34:13 +0100 Subject: [PATCH 17/59] Fix bugs # Explain what has been changed # Explain why this change is being made # Provide links to any relevant tickets, articles or other resources --- DRAMSys/simulator/src/controller/Controller.cpp | 2 +- .../src/controller/scheduler/ReadyBatch.cpp | 11 +++++++++-- .../simulator/src/controller/scheduler/ReadyBatch.h | 1 + DRAMSys/simulator/src/controller/scheduler/SMS.h | 12 ++++++++++-- 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/DRAMSys/simulator/src/controller/Controller.cpp b/DRAMSys/simulator/src/controller/Controller.cpp index b16f981b..56e27215 100644 --- a/DRAMSys/simulator/src/controller/Controller.cpp +++ b/DRAMSys/simulator/src/controller/Controller.cpp @@ -55,7 +55,7 @@ void Controller::buildScheduler() } else if (selectedScheduler == "SMS") { - scheduler = new SMS(*controllerCore, Configuration::getInstance().SJFProbability); + scheduler = new SMS("SMS", *controllerCore, Configuration::getInstance().SJFProbability); } //else if (selectedScheduler == "PAR_BS") //{ diff --git a/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp index 91aa48db..af2a624b 100644 --- a/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp @@ -6,6 +6,11 @@ ReadyBatch::ReadyBatch() thresholdAge = sc_time(Configuration::getInstance().ReadyBatchThresholdAge, SC_NS); } +ReadyBatch::~ReadyBatch() +{ + +} + //unsigned int ReadyBatch::getNumRequests() //{ // return readybatch.size(); @@ -13,7 +18,8 @@ ReadyBatch::ReadyBatch() Row ReadyBatch::getRow() { - return DramExtension::getExtension(readybatch.front()).getRow(); + gp*& firstPayload = readybatch.front(); + return DramExtension::getExtension(firstPayload).getRow(); } //sc_time ReadyBatch::getTimeOfOldestRequest() @@ -34,7 +40,8 @@ bool ReadyBatch::addTransaction(gp* payload) { // sc_time currentAge = sc_time_stamp() - getTimeOfOldestRequest(); Row newRow = DramExtension::getExtension(payload).getRow(); - if (/*getNumRequests() == fifosize || currentAge >= thresholdAge || */newRow != getRow()) { + Row oldRow = readybatch.empty()? newRow : getRow(); + if (/*getNumRequests() == fifosize || currentAge >= thresholdAge || */newRow != oldRow) { return false; } else { readybatch.emplace_back(payload); diff --git a/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.h b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.h index c35640a5..1b0f304c 100644 --- a/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.h +++ b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.h @@ -17,6 +17,7 @@ public: // unsigned int getNumRequests(); std::deque& getTransactions(); bool isEmpty(); + ~ReadyBatch(); private: std::deque readybatch; unsigned int fifosize; diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h index 71f7aa96..527b350c 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.h +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h @@ -17,7 +17,7 @@ using namespace std; class SMS: public sc_module, public IScheduler { public: - SMS(ControllerCore &controllerCore, unsigned int SJFprobability) : IScheduler(controllerCore), SJFprobability(SJFprobability) + SMS(sc_module_name /*_name*/, ControllerCore &controllerCore, unsigned int SJFprobability) : IScheduler(controllerCore), SJFprobability(SJFprobability) { // initialize memory request counter & memory request intensity for each thread unsigned int totalNumThreads = Configuration::getInstance().NumberOfTracePlayers; @@ -26,11 +26,19 @@ public: // 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(){} + virtual ~SMS() + { + unsigned int totalNumThreads = Configuration::getInstance().NumberOfTracePlayers; + for (unsigned int threadID = 1; threadID <= totalNumThreads; threadID++) + { + delete readybatches[Thread(threadID)]; + } + } virtual void schedule(gp *payload) override; virtual std::pair getNextRequest(Bank bank) override; void batchScheduler(); From 0830dc4d53e12c8c0d7d2ed651b42a54a120646f Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Tue, 14 Mar 2017 02:20:52 +0100 Subject: [PATCH 18/59] Change random generator to Bernoulli distribution # Explain what has been changed # Explain why this change is being made # Provide links to any relevant tickets, articles or other resources --- DRAMSys/simulator/src/controller/scheduler/SMS.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index 147cea6e..533498ef 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -1,4 +1,5 @@ #include "SMS.h" +#include using namespace std; @@ -72,12 +73,15 @@ 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); - srand(time(NULL)); - bool isSJF = (rand() % 100) < SJFprobability; + isSJF = distribution(generator); if (!existReadyBatch()) { // pick & drain a ready batch From ba39c9443bc584ac4f90c66cf0bf1e9a00760e3e Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Wed, 22 Mar 2017 12:43:36 +0100 Subject: [PATCH 19/59] Update test cases & simulation configurations # Explain what has been changed # Explain why this change is being made # Provide links to any relevant tickets, articles or other resources --- DRAMSys/simulator/resources/configs/mcconfigs/sms.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DRAMSys/simulator/resources/configs/mcconfigs/sms.xml b/DRAMSys/simulator/resources/configs/mcconfigs/sms.xml index bee3151e..19490a2c 100644 --- a/DRAMSys/simulator/resources/configs/mcconfigs/sms.xml +++ b/DRAMSys/simulator/resources/configs/mcconfigs/sms.xml @@ -1,9 +1,9 @@ - + - + From 3521cafa814ca0da85e61fe4fe5dc34998227c7d Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Wed, 22 Mar 2017 12:44:33 +0100 Subject: [PATCH 20/59] 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 --- .../src/controller/scheduler/ReadyBatch.cpp | 3 +- .../src/controller/scheduler/SMS.cpp | 271 ++++++++---------- .../simulator/src/controller/scheduler/SMS.h | 12 +- 3 files changed, 117 insertions(+), 169 deletions(-) diff --git a/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp index af2a624b..55118d15 100644 --- a/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/ReadyBatch.cpp @@ -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() diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index 533498ef..b7da758e 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -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 SMS::getNextRequest(Bank bank) @@ -40,16 +31,35 @@ std::pair 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 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::iterator next = readybatches.begin(); - - // drain to bank buffers - std::deque 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 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 &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::iterator next = readybatches.begin(); + + if (existReadyBatch()) + { + while ((*next).second->isEmpty()) + { + next++; + if (next == readybatches.end()) + { + next = readybatches.begin(); + } + } + + // 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); + } + 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; +} + + + diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h index 527b350c..9d2979f4 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.h +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h @@ -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 getNextRequest(Bank bank) override; + void batchScheduler(); private: std::map> buffer; std::map> bankbuffer; std::map readybatches; -// std::map memrequestcounter; std::map inFlightMemRequestCounter; -// std::map 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 From 8c7e3549aa2a5577499cb250c5934a5b4ecf7b5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89der=20F=2E=20Zulian?= Date: Fri, 10 Mar 2017 15:40:04 +0100 Subject: [PATCH 21/59] Fix for disable refresh --- .../simulator/src/controller/core/ControllerCore.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/DRAMSys/simulator/src/controller/core/ControllerCore.cpp b/DRAMSys/simulator/src/controller/core/ControllerCore.cpp index d8650e70..45b3bd47 100644 --- a/DRAMSys/simulator/src/controller/core/ControllerCore.cpp +++ b/DRAMSys/simulator/src/controller/core/ControllerCore.cpp @@ -160,11 +160,16 @@ void ControllerCore::scheduleRequest(Command command, tlm::tlm_generic_payload & sc_time start = clkAlign(sc_time_stamp()); state->cleanUp(start); ScheduledCommand scheduledCommand = schedule(command, start, payload); - if(!((command == Command::Precharge || command == Command::Activate) - && refreshManager->hasCollision(scheduledCommand))) - { + if (config.ControllerCoreDisableRefresh == true) { state->change(scheduledCommand); controller.send(scheduledCommand, payload); + } else { + if(!((command == Command::Precharge || command == Command::Activate) + && refreshManager->hasCollision(scheduledCommand))) + { + state->change(scheduledCommand); + controller.send(scheduledCommand, payload); + } } } From 83e6a1884ce303fb502232680b2828989fec3378 Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Wed, 22 Mar 2017 15:54:33 +0100 Subject: [PATCH 22/59] Revert simulation config file and create a separate simulation file for SMS # Explain what has been changed # Explain why this change is being made # Provide links to any relevant tickets, articles or other resources --- .../resources/simulations/sim-batch.xml | 13 ++--- .../resources/simulations/sms-example.xml | 55 +++++++++++++++++++ 2 files changed, 60 insertions(+), 8 deletions(-) create mode 100644 DRAMSys/simulator/resources/simulations/sms-example.xml diff --git a/DRAMSys/simulator/resources/simulations/sim-batch.xml b/DRAMSys/simulator/resources/simulations/sim-batch.xml index fbd47695..0752914c 100644 --- a/DRAMSys/simulator/resources/simulations/sim-batch.xml +++ b/DRAMSys/simulator/resources/simulations/sim-batch.xml @@ -2,11 +2,11 @@ - + - + @@ -39,15 +39,12 @@ - + - - t1.stl - t2.stl - t3.stl - t4.stl + + chstone-adpcm_32.stl diff --git a/DRAMSys/simulator/resources/simulations/sms-example.xml b/DRAMSys/simulator/resources/simulations/sms-example.xml new file mode 100644 index 00000000..fbd47695 --- /dev/null +++ b/DRAMSys/simulator/resources/simulations/sms-example.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + t1.stl + t2.stl + t3.stl + t4.stl + + + + + From 20e6d4e6157e5dfc3c7bdde62620075dcb186d19 Mon Sep 17 00:00:00 2001 From: Johannes Feldmann Date: Fri, 31 Mar 2017 16:09:36 +0200 Subject: [PATCH 23/59] ECC Controller erstellt ECC Daten. Noch Fehler bei der Weiterverarbeitung im Simulationsmodell. --- DRAMSys/simulator/library.pro | 10 +++- DRAMSys/simulator/src/error/ECC/Bit.cpp | 8 ++- DRAMSys/simulator/src/error/ECC/Bit.h | 9 ++- DRAMSys/simulator/src/error/ECC/ECC.cpp | 10 ++-- DRAMSys/simulator/src/error/ECC/Word.cpp | 41 ++++++++++++- DRAMSys/simulator/src/error/ECC/Word.h | 7 ++- DRAMSys/simulator/src/error/controllerECC.h | 66 ++++++++++++++++++--- DRAMSys/simulator/src/simulation/Dram.h | 3 + 8 files changed, 131 insertions(+), 23 deletions(-) diff --git a/DRAMSys/simulator/library.pro b/DRAMSys/simulator/library.pro index 5a25d3ff..50e6afa0 100644 --- a/DRAMSys/simulator/library.pro +++ b/DRAMSys/simulator/library.pro @@ -100,7 +100,10 @@ SOURCES += \ src/controller/core/powerdown/PowerDownManagerTimeoutBankwise.cpp \ src/simulation/TraceSetup.cpp \ src/simulation/DRAMSys.cpp \ - src/simulation/Setup.cpp + src/simulation/Setup.cpp \ + src/error/ECC/Bit.cpp \ + src/error/ECC/ECC.cpp \ + src/error/ECC/Word.cpp HEADERS += \ src/common/third_party/tinyxml2/tinyxml2.h \ @@ -164,7 +167,10 @@ HEADERS += \ src/simulation/TraceSetup.h \ src/simulation/DRAMSys.h \ src/simulation/Setup.h \ - src/error/controllerECC.h + src/error/controllerECC.h \ + src/error/ECC/Bit.h \ + src/error/ECC/ECC.h \ + src/error/ECC/Word.h thermalsim = $$(THERMALSIM) isEmpty(thermalsim) { diff --git a/DRAMSys/simulator/src/error/ECC/Bit.cpp b/DRAMSys/simulator/src/error/ECC/Bit.cpp index b5faee9a..55f28ebf 100644 --- a/DRAMSys/simulator/src/error/ECC/Bit.cpp +++ b/DRAMSys/simulator/src/error/ECC/Bit.cpp @@ -1,6 +1,8 @@ -#include "stdafx.h" #include "Bit.h" +#include + +using std::cout; CBit::CBit(VALUE nVal) { @@ -16,10 +18,10 @@ void CBit::Print() { if (m_nValue == ZERO) { - printf("0"); + cout <<"0"; } else { - printf("1"); + cout << "1"; } } diff --git a/DRAMSys/simulator/src/error/ECC/Bit.h b/DRAMSys/simulator/src/error/ECC/Bit.h index 74aec5da..bfdda476 100644 --- a/DRAMSys/simulator/src/error/ECC/Bit.h +++ b/DRAMSys/simulator/src/error/ECC/Bit.h @@ -17,10 +17,17 @@ public: inline void Set() { m_nValue = ONE; }; inline void Clear() { m_nValue = ZERO; }; + inline unsigned Get() + { + if(m_nValue == ONE) + return 1; + else + return 0; + }; void Print(); - CBit& operator=(DWORD d) + CBit& operator=(unsigned d) { if (d == 0 ) { diff --git a/DRAMSys/simulator/src/error/ECC/ECC.cpp b/DRAMSys/simulator/src/error/ECC/ECC.cpp index bbd230ba..a041496e 100644 --- a/DRAMSys/simulator/src/error/ECC/ECC.cpp +++ b/DRAMSys/simulator/src/error/ECC/ECC.cpp @@ -1,5 +1,3 @@ -#include "stdafx.h" - #include "ECC.h" unsigned ECC::GetNumParityBits(unsigned nDataBits) @@ -31,7 +29,7 @@ void ECC::ExtendWord(CWord & v) void ECC::CalculateCheckbits(CWord & v, CWord & p) { - // Hamming-Code Prüfbits füllen + // Hamming-Code Prüfbits füllen unsigned i = 1, l = 0; while (i < v.GetLength()) { @@ -39,6 +37,8 @@ void ECC::CalculateCheckbits(CWord & v, CWord & p) { for (unsigned k = 0; k < (i); k++) { + if(j + k >= v.GetLength()) + break; p[l] ^= v[j + k]; } } @@ -49,7 +49,7 @@ void ECC::CalculateCheckbits(CWord & v, CWord & p) void ECC::InsertCheckbits(CWord& v, CWord p) { - // Prüfbits einfügen + // Prüfbits einfügen unsigned i = 1, j = 0; while (i <= v.GetLength()) { @@ -61,7 +61,7 @@ void ECC::InsertCheckbits(CWord& v, CWord p) void ECC::ExtractCheckbits(CWord v, CWord & p) { - // Prüfbits extrahieren + // Prüfbits extrahieren unsigned i = 1, j = 0; while(i <= v.GetLength()) { diff --git a/DRAMSys/simulator/src/error/ECC/Word.cpp b/DRAMSys/simulator/src/error/ECC/Word.cpp index a94bdad7..f260d76c 100644 --- a/DRAMSys/simulator/src/error/ECC/Word.cpp +++ b/DRAMSys/simulator/src/error/ECC/Word.cpp @@ -1,6 +1,8 @@ -#include "stdafx.h" #include "Word.h" +#include + +using std::cout; CWord::CWord(unsigned nBitLength) : m_nBitLength(nBitLength) @@ -23,7 +25,7 @@ CBit * CWord::GetAt(unsigned nBitPos) return nullptr; } -void CWord::Set(DWORD data) +void CWord::Set(unsigned data) { deque::iterator it; if (m_nBitLength < sizeof(data)) @@ -45,6 +47,29 @@ void CWord::Set(DWORD data) } } +void CWord::Set(unsigned char* data, unsigned lengthInBits) +{ + deque::iterator it; + if (m_nBitLength < lengthInBits) + { + it = m_word.begin(); + for (unsigned pos = 0; pos < m_nBitLength; pos++) + { + (*it) = data[pos>>3] & (1 << (7-(pos&7))); + it++; + } + } + else + { + unsigned pos = 0; + for (it = m_word.begin(); it != m_word.end(); it++) + { + (*it) = data[pos>>3] & (1 << (7-(pos&7))); + ++pos; + } + } +} + void CWord::Rotate() { deque buffer = m_word; @@ -113,5 +138,15 @@ void CWord::Print() { (*it).Print(); } - printf("\r\n"); + cout << "\r\n"; +} + +void CWord::Copy(unsigned char* ptr) +{ + unsigned pos = 0; + for(auto it = m_word.begin(); it != m_word.end(); it++) + { + ptr[pos>>3] |= (*it).Get() << (7-(pos&7)); + ++pos; + } } diff --git a/DRAMSys/simulator/src/error/ECC/Word.h b/DRAMSys/simulator/src/error/ECC/Word.h index e3ae7c66..f21432cb 100644 --- a/DRAMSys/simulator/src/error/ECC/Word.h +++ b/DRAMSys/simulator/src/error/ECC/Word.h @@ -20,12 +20,15 @@ public: CBit* GetAt(unsigned nBitPos); - void Set(DWORD data); + void Set(unsigned data); + void Set(unsigned char* data, unsigned lengthInBits); void Rotate(); bool Insert(unsigned npos, CBit b); bool Delete(unsigned npos); + void Copy(unsigned char* ptr); + void Append(CBit b); void Resize(unsigned nsize); @@ -36,7 +39,7 @@ public: void Print(); - CWord& operator=(DWORD d) + CWord& operator=(unsigned d) { Set(d); return *this; diff --git a/DRAMSys/simulator/src/error/controllerECC.h b/DRAMSys/simulator/src/error/controllerECC.h index 0a33c1c1..94a2ce6e 100644 --- a/DRAMSys/simulator/src/error/controllerECC.h +++ b/DRAMSys/simulator/src/error/controllerECC.h @@ -3,6 +3,8 @@ #include +#include "ECC/ECC.h" + #include "../common/xmlAddressdecoder.h" #include "../common/DebugManager.h" @@ -29,14 +31,64 @@ public: // Forward interface virtual tlm::tlm_sync_enum nb_transport_fw( int id, tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_time& delay ) { - if(trans.get_command() == TLM_WRITE_COMMAND) - { - // Allocate memory if necessary - if(m_mBuffer[trans.get_address()].size() != trans.get_data_length()) - m_mBuffer[trans.get_address()].resize(trans.get_data_length()); + if(trans.get_command() == TLM_WRITE_COMMAND) + { + // Get data and length + unsigned nDataLength = trans.get_data_length(); + unsigned char* pData = trans.get_data_ptr(); - // Copy data - memcpy(m_mBuffer[trans.get_address()].data(), trans.get_data_ptr(), trans.get_data_length()); + // Calculate how many 64 bit blocks are there + unsigned nBlocks = nDataLength>>3; + + // Create new data array for data with ECC + unsigned char* pDataECC = new unsigned char[nBlocks*9]; + memset(pDataECC, 0x0, nBlocks*9*sizeof(unsigned char)); + + // Create ECC data for every block + for(unsigned i = 0; i < nBlocks; i++) + { + // Create all variables needed for calulation + CWord dataword(64); + CWord checkbits(8); + + // Fill in current data block + dataword.Set(&pData[i<<3], 64); + dataword.Print(); + // Extend data word + ECC::ExtendWord(dataword); + + // Calculate Checkbits + ECC::CalculateCheckbits(dataword, checkbits); + ECC::InsertCheckbits(dataword, checkbits); + + // Calculate Parity + ECC::CalculateParityBit(dataword, checkbits[7]); + + // Copy old data + memcpy(&pDataECC[i*9], &pData[i<<3], 8); + + dataword.Print(); + checkbits.Print(); + + // Save new data + checkbits.Copy(&pDataECC[i*9+8]); + } + + // Change transport data length + trans.set_data_length(nBlocks*9); + + // delete old data + delete[] trans.get_data_ptr(); + + // Set new data + trans.set_data_ptr(pDataECC); + + // Allocate memory if necessary + //if(m_mBuffer[trans.get_address()].size() != trans.get_data_length()) + // m_mBuffer[trans.get_address()].resize(trans.get_data_length()); + + // Copy data + //memcpy(m_mBuffer[trans.get_address()].data(), trans.get_data_ptr(), trans.get_data_length()); } return i_socket[id]->nb_transport_fw( trans, phase, delay ); } diff --git a/DRAMSys/simulator/src/simulation/Dram.h b/DRAMSys/simulator/src/simulation/Dram.h index 3710a8ae..1e8079be 100644 --- a/DRAMSys/simulator/src/simulation/Dram.h +++ b/DRAMSys/simulator/src/simulation/Dram.h @@ -92,6 +92,9 @@ struct Dram : sc_module SC_CTOR(Dram) : tSocket("socket") { + if(Configuration::getInstance().EnableControllerECC) + bytesPerBurst += bytesPerBurst>>3; + std::uint64_t memorySize = Configuration::getInstance().getSimMemSizeInBytes(); // allocate and model storage of one DRAM channel using memory map memory = (unsigned char *)mmap(NULL, memorySize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON | MAP_NORESERVE, -1, 0); From d974851c0eae4494d89cf75883609946105666fc Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Mon, 3 Apr 2017 22:14:44 +0200 Subject: [PATCH 24/59] Small fix --- DRAMSys/simulator/src/controller/scheduler/SMS.cpp | 4 +++- DRAMSys/simulator/src/simulation/main.cpp | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index b7da758e..af4af7be 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -71,10 +71,12 @@ bool SMS::batchFormation() else { bool isBatchForm = false; + bool isBatchFormForThread = false; unsigned int totalNumThreads = Configuration::getInstance().NumberOfTracePlayers; for (unsigned int threadID = 1; threadID <= totalNumThreads; threadID++) { - isBatchForm = isBatchForm || batchFormation(Thread(threadID)); + isBatchFormForThread = batchFormation(Thread(threadID)); + isBatchForm = isBatchForm || isBatchFormForThread; } return isBatchForm; } diff --git a/DRAMSys/simulator/src/simulation/main.cpp b/DRAMSys/simulator/src/simulation/main.cpp index 207d99db..87a8d27a 100644 --- a/DRAMSys/simulator/src/simulation/main.cpp +++ b/DRAMSys/simulator/src/simulation/main.cpp @@ -83,7 +83,7 @@ int sc_main(int argc, char **argv) if(argc > 1) simulationToRun = argv[1]; else - simulationToRun = resources + "simulations/sim-batch.xml"; + simulationToRun = resources + "simulations/sms-example.xml"; cout << "Simulation file is " << simulationToRun << endl; SimulationManager manager(resources); From b0b1d0efd2c5a8f3e781683f6840c85abb8ff03b Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Tue, 11 Apr 2017 22:55:33 +0200 Subject: [PATCH 25/59] Include necessary files for SMS simulation in Qt resource config file --- DRAMSys/simulator/resources/resources.pri | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/DRAMSys/simulator/resources/resources.pri b/DRAMSys/simulator/resources/resources.pri index 1d6ffe46..412c88be 100644 --- a/DRAMSys/simulator/resources/resources.pri +++ b/DRAMSys/simulator/resources/resources.pri @@ -5,6 +5,7 @@ OTHER_FILES += resources/simulations/sim-batch.xml OTHER_FILES += resources/simulations/ddr3-example.xml OTHER_FILES += resources/simulations/ddr3-single-device.xml +OTHER_FILES += resources/simulations/sms-example.xml # scripts OTHER_FILES += resources/scripts/address_scrambler.pl @@ -52,6 +53,10 @@ OTHER_FILES += resources/traces/mediabench-adpcmdecode_32.stl OTHER_FILES += resources/traces/ddr3_example.stl OTHER_FILES += resources/traces/ddr3_single_dev_example.stl OTHER_FILES += resources/traces/ddr3_SAMSUNG_M471B5674QH0_DIMM_example.stl +OTHER_FILES += resources/traces/t1.stl +OTHER_FILES += resources/traces/t2.stl +OTHER_FILES += resources/traces/t3.stl +OTHER_FILES += resources/traces/t4.stl # mcconfigs OTHER_FILES += resources/configs/mcconfigs/fifoStrict.xml @@ -63,6 +68,7 @@ OTHER_FILES += resources/configs/mcconfigs/_old/par_bs.xml OTHER_FILES += resources/configs/mcconfigs/_old/fr_fcfs_bankwise.xml OTHER_FILES += resources/configs/mcconfigs/fr_fcfs.xml OTHER_FILES += resources/configs/mcconfigs/par_bs.xml +OTHER_FILES += resources/configs/mcconfigs/sms.xml # memspecs OTHER_FILES += resources/configs/memspecs/memspec.dtd From 11d428c1d5b18331ecbbfe048cd9fe3351b01caf Mon Sep 17 00:00:00 2001 From: Johannes Feldmann Date: Thu, 13 Apr 2017 18:59:56 +0200 Subject: [PATCH 26/59] ECC implementierung fertig gestellt. --- ...CRON_1Gb_DDR3-1600_8bit_G_less_refresh.xml | 55 ++++++ .../resources/configs/simulator/ddr3_ecc.xml | 22 +++ DRAMSys/simulator/resources/resources.pri | 5 +- .../resources/simulations/ddr3-ecc.xml | 22 +++ DRAMSys/simulator/src/error/ECC/ECC.cpp | 14 +- DRAMSys/simulator/src/error/controllerECC.h | 165 ++++++++++++++---- DRAMSys/simulator/src/error/errormodel.cpp | 7 +- DRAMSys/simulator/src/simulation/main.cpp | 2 +- 8 files changed, 252 insertions(+), 40 deletions(-) create mode 100644 DRAMSys/simulator/resources/configs/memspecs/MICRON_1Gb_DDR3-1600_8bit_G_less_refresh.xml create mode 100644 DRAMSys/simulator/resources/configs/simulator/ddr3_ecc.xml create mode 100644 DRAMSys/simulator/resources/simulations/ddr3-ecc.xml diff --git a/DRAMSys/simulator/resources/configs/memspecs/MICRON_1Gb_DDR3-1600_8bit_G_less_refresh.xml b/DRAMSys/simulator/resources/configs/memspecs/MICRON_1Gb_DDR3-1600_8bit_G_less_refresh.xml new file mode 100644 index 00000000..7a94a932 --- /dev/null +++ b/DRAMSys/simulator/resources/configs/memspecs/MICRON_1Gb_DDR3-1600_8bit_G_less_refresh.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DRAMSys/simulator/resources/configs/simulator/ddr3_ecc.xml b/DRAMSys/simulator/resources/configs/simulator/ddr3_ecc.xml new file mode 100644 index 00000000..f1f7bcf8 --- /dev/null +++ b/DRAMSys/simulator/resources/configs/simulator/ddr3_ecc.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + diff --git a/DRAMSys/simulator/resources/resources.pri b/DRAMSys/simulator/resources/resources.pri index 37b75724..3d02ddb8 100644 --- a/DRAMSys/simulator/resources/resources.pri +++ b/DRAMSys/simulator/resources/resources.pri @@ -140,4 +140,7 @@ DISTFILES += \ $$PWD/configs/mcconfigs/fifo_ecc.xml \ $$PWD/simulations/wideio-ecc.xml \ $$PWD/traces/test_ecc.stl \ - $$PWD/configs/memspecs/wideio_less_refresh.xml + $$PWD/configs/memspecs/wideio_less_refresh.xml \ + $$PWD/simulations/ddr3-ecc.xml \ + $$PWD/configs/simulator/ddr3_ecc.xml \ + $$PWD/configs/memspecs/MICRON_1Gb_DDR3-1600_8bit_G_less_refresh.xml diff --git a/DRAMSys/simulator/resources/simulations/ddr3-ecc.xml b/DRAMSys/simulator/resources/simulations/ddr3-ecc.xml new file mode 100644 index 00000000..5760612c --- /dev/null +++ b/DRAMSys/simulator/resources/simulations/ddr3-ecc.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + test_ecc.stl + + diff --git a/DRAMSys/simulator/src/error/ECC/ECC.cpp b/DRAMSys/simulator/src/error/ECC/ECC.cpp index a041496e..b8e15743 100644 --- a/DRAMSys/simulator/src/error/ECC/ECC.cpp +++ b/DRAMSys/simulator/src/error/ECC/ECC.cpp @@ -31,13 +31,17 @@ void ECC::CalculateCheckbits(CWord & v, CWord & p) { // Hamming-Code Prüfbits füllen unsigned i = 1, l = 0; - while (i < v.GetLength()) + + // Last bit is the parity bit - don't use this in the algorithm for hamming code + unsigned len = v.GetLength()-1; + + while (i < len) { - for (unsigned j = (i - 1); j < v.GetLength(); j += (i << 1)) + for (unsigned j = (i - 1); j < len; j += (i << 1)) { for (unsigned k = 0; k < (i); k++) { - if(j + k >= v.GetLength()) + if(j + k >= len) break; p[l] ^= v[j + k]; } @@ -51,7 +55,7 @@ void ECC::InsertCheckbits(CWord& v, CWord p) { // Prüfbits einfügen unsigned i = 1, j = 0; - while (i <= v.GetLength()) + while (i <= v.GetLength()-1) { v[i - 1] = p[j++]; i <<= 1; @@ -63,7 +67,7 @@ void ECC::ExtractCheckbits(CWord v, CWord & p) { // Prüfbits extrahieren unsigned i = 1, j = 0; - while(i <= v.GetLength()) + while(i <= v.GetLength()-1) { p[j++] = v[i - 1]; i <<= 1; diff --git a/DRAMSys/simulator/src/error/controllerECC.h b/DRAMSys/simulator/src/error/controllerECC.h index 94a2ce6e..509e1036 100644 --- a/DRAMSys/simulator/src/error/controllerECC.h +++ b/DRAMSys/simulator/src/error/controllerECC.h @@ -31,7 +31,7 @@ public: // Forward interface virtual tlm::tlm_sync_enum nb_transport_fw( int id, tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_time& delay ) { - if(trans.get_command() == TLM_WRITE_COMMAND) + if(trans.get_command() == TLM_WRITE_COMMAND && trans.get_response_status() == TLM_INCOMPLETE_RESPONSE) { // Get data and length unsigned nDataLength = trans.get_data_length(); @@ -53,10 +53,12 @@ public: // Fill in current data block dataword.Set(&pData[i<<3], 64); - dataword.Print(); + // Extend data word ECC::ExtendWord(dataword); + checkbits = 0; + // Calculate Checkbits ECC::CalculateCheckbits(dataword, checkbits); ECC::InsertCheckbits(dataword, checkbits); @@ -67,13 +69,21 @@ public: // Copy old data memcpy(&pDataECC[i*9], &pData[i<<3], 8); - dataword.Print(); - checkbits.Print(); - // Save new data checkbits.Copy(&pDataECC[i*9+8]); } + // Print all +// for(unsigned i = 0; i < nBlocks; i++) +// { +// for(unsigned j = 0; j < 9; j++) +// { +// cout << setw(2) << setfill('0') << hex << uppercase << (int)pDataECC[i*9+j]; +// } +// cout << endl; +// } +// cout << endl; + // Change transport data length trans.set_data_length(nBlocks*9); @@ -82,14 +92,24 @@ public: // Set new data trans.set_data_ptr(pDataECC); - - // Allocate memory if necessary - //if(m_mBuffer[trans.get_address()].size() != trans.get_data_length()) - // m_mBuffer[trans.get_address()].resize(trans.get_data_length()); - - // Copy data - //memcpy(m_mBuffer[trans.get_address()].data(), trans.get_data_ptr(), trans.get_data_length()); } + else if(trans.get_response_status() == TLM_INCOMPLETE_RESPONSE) + { + // 64 -> 72 + + // Get data length + unsigned nDataLength = trans.get_data_length(); + + // delete old data + delete[] trans.get_data_ptr(); + + // Set new data + nDataLength += nDataLength>>3; + trans.set_data_ptr(new unsigned char [nDataLength]); + + // Change transport data length + trans.set_data_length(nDataLength); + } return i_socket[id]->nb_transport_fw( trans, phase, delay ); } @@ -99,27 +119,108 @@ public: { if(trans.get_command() == TLM_READ_COMMAND && phase == 3) { - if(m_mBuffer[trans.get_address()].size() == trans.get_data_length()) - { - // Data can be compared, they got the same size - int error = memcmp(m_mBuffer[trans.get_address()].data(), trans.get_data_ptr(), trans.get_data_length()); - if(error) - { - // Data not equal - cout << "\nError Detected: Address: 0x" << hex << trans.get_address(); + // Get data and length + unsigned nDataLength = trans.get_data_length(); + unsigned char* pData = trans.get_data_ptr(); - for(unsigned n = 0; n < trans.get_data_length(); n++) - { - if(m_mBuffer[trans.get_address()].data()[n] != trans.get_data_ptr()[n]) - { - cout << "\n\t\tError Byte " << dec << n << " Orig: 0x" << hex << (int)m_mBuffer[trans.get_address()].data()[n] - << " Read: 0x" << hex << (int)trans.get_data_ptr()[n]; - } - } - cout << endl; - } - } - } + // Calculate how many 72 bit blocks are there + unsigned nBlocks = nDataLength/9; + + // Print all +// for(unsigned i = 0; i < nBlocks; i++) +// { +// for(unsigned j = 0; j < 9; j++) +// { +// cout << setw(2) << setfill('0') << hex << uppercase << (int)pData[i*9+j]; +// } +// cout << endl; +// } +// cout << endl; + + // Verify ECC data for every block + for(unsigned i = 0; i < nBlocks; i++) + { + // Create all variables needed for calulation + CWord dataword(64); + CWord checkbits(8); + + // Fill in current data block + dataword.Set(&pData[i*9], 64); + checkbits.Set(&pData[i*9+8], 8); + + // Extend data word + ECC::ExtendWord(dataword); + + // Insert old checkbits + ECC::InsertCheckbits(dataword, checkbits); + ECC::InsertParityBit(dataword, checkbits[7]); + + checkbits = 0; + + // Calculate Checkbits + ECC::CalculateCheckbits(dataword, checkbits); + + // Calculate Parity + ECC::CalculateParityBit(dataword, checkbits[7]); + + // Translate Checkbits + bool bParity = checkbits[7] == CBit::ONE; + + unsigned char c = 0; + checkbits.Rotate(); + checkbits.Copy(&c); + c &= 0x7F; + + // Parity Error? + if(bParity) + { + // Parity Error + + if(c == 0) + { + // Only Parity Bit broken - continue + cout << "Parity Bit error" << endl; + continue; + } + else + { + // Data or Hamming Code Bit broken + cout << "Single Error Detected" << endl; + continue; + } + } + else + { + // No Parity Error + + if(c == 0) + { + // No error at all - continue + continue; + } + else + { + // Double error detected + cout << "Double Error Detected (Block " << i << ")." << endl; + continue; + } + } + } + // Change transport data length + trans.set_data_length(nBlocks<<3); + + // New Data + unsigned char* pDataECC = new unsigned char[nBlocks<<3]; + + // Copy data + memcpy(pDataECC, pData, nBlocks<<3); + + // delete old data + delete[] trans.get_data_ptr(); + + // Set new data + trans.set_data_ptr(pDataECC); + } return t_socket[id]->nb_transport_bw( trans, phase, delay ); } }; diff --git a/DRAMSys/simulator/src/error/errormodel.cpp b/DRAMSys/simulator/src/error/errormodel.cpp index 91eb789b..5ff3693f 100644 --- a/DRAMSys/simulator/src/error/errormodel.cpp +++ b/DRAMSys/simulator/src/error/errormodel.cpp @@ -49,7 +49,12 @@ void errorModel::init() burstLenght = Configuration::getInstance().memSpec.BurstLength; numberOfColumns = Configuration::getInstance().memSpec.NumberOfColumns; bytesPerColumn = xmlAddressDecoder::getInstance().amount["bytes"]; - numberOfRows = Configuration::getInstance().memSpec.NumberOfRows; + if(Configuration::getInstance().EnableControllerECC) + { + bytesPerColumn += bytesPerColumn>>3; + } + + numberOfRows = Configuration::getInstance().memSpec.NumberOfRows; numberOfBitErrorEvents = 0; diff --git a/DRAMSys/simulator/src/simulation/main.cpp b/DRAMSys/simulator/src/simulation/main.cpp index 18b474e9..0bb75469 100644 --- a/DRAMSys/simulator/src/simulation/main.cpp +++ b/DRAMSys/simulator/src/simulation/main.cpp @@ -72,7 +72,7 @@ int sc_main(int argc, char **argv) } else { - SimulationXML = resources + "simulations/wideio-ecc.xml"; + SimulationXML = resources + "simulations/ddr3-ecc.xml"; } std::vector players; From e99b07fb4f6852080dd12edd3bbc013471617c9e Mon Sep 17 00:00:00 2001 From: Johannes Feldmann Date: Mon, 17 Apr 2017 15:48:31 +0200 Subject: [PATCH 27/59] Revert change in wideio.xml --- DRAMSys/simulator/resources/configs/memspecs/wideio.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DRAMSys/simulator/resources/configs/memspecs/wideio.xml b/DRAMSys/simulator/resources/configs/memspecs/wideio.xml index 3ab07172..fbe252d6 100644 --- a/DRAMSys/simulator/resources/configs/memspecs/wideio.xml +++ b/DRAMSys/simulator/resources/configs/memspecs/wideio.xml @@ -24,7 +24,7 @@ - + From c09f0cac0a5d005271311ff3693c8e772c9b85bb Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Mon, 24 Apr 2017 00:29:19 +0200 Subject: [PATCH 28/59] Change trace file names for SMS --- DRAMSys/simulator/resources/resources.pri | 8 ++++---- DRAMSys/simulator/resources/simulations/sms-example.xml | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/DRAMSys/simulator/resources/resources.pri b/DRAMSys/simulator/resources/resources.pri index 412c88be..23f0e606 100644 --- a/DRAMSys/simulator/resources/resources.pri +++ b/DRAMSys/simulator/resources/resources.pri @@ -53,10 +53,10 @@ OTHER_FILES += resources/traces/mediabench-adpcmdecode_32.stl OTHER_FILES += resources/traces/ddr3_example.stl OTHER_FILES += resources/traces/ddr3_single_dev_example.stl OTHER_FILES += resources/traces/ddr3_SAMSUNG_M471B5674QH0_DIMM_example.stl -OTHER_FILES += resources/traces/t1.stl -OTHER_FILES += resources/traces/t2.stl -OTHER_FILES += resources/traces/t3.stl -OTHER_FILES += resources/traces/t4.stl +OTHER_FILES += resources/traces/sms_t1.stl +OTHER_FILES += resources/traces/sms_t2.stl +OTHER_FILES += resources/traces/sms_t3.stl +OTHER_FILES += resources/traces/sms_t4.stl # mcconfigs OTHER_FILES += resources/configs/mcconfigs/fifoStrict.xml diff --git a/DRAMSys/simulator/resources/simulations/sms-example.xml b/DRAMSys/simulator/resources/simulations/sms-example.xml index fbd47695..16383801 100644 --- a/DRAMSys/simulator/resources/simulations/sms-example.xml +++ b/DRAMSys/simulator/resources/simulations/sms-example.xml @@ -44,10 +44,10 @@ - t1.stl - t2.stl - t3.stl - t4.stl + sms_t1.stl + sms_t2.stl + sms_t3.stl + sms_t4.stl From 8a2d4331ec04de7be0eccc3dd8dfefc9df14b058 Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Fri, 28 Apr 2017 15:03:40 +0200 Subject: [PATCH 29/59] Add debugger & fix the drain step to drain each request in each clock cycle --- .../src/controller/scheduler/SMS.cpp | 46 +++++++++++++++---- .../simulator/src/controller/scheduler/SMS.h | 11 +++-- 2 files changed, 46 insertions(+), 11 deletions(-) diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index af4af7be..51b1b2ec 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -7,12 +7,15 @@ void SMS::schedule(gp *payload) { buffer[DramExtension::getExtension(payload).getThread()].emplace_back(payload); inFlightMemRequestCounter[DramExtension::getExtension(payload).getThread()]++; + newRequest.notify(SC_ZERO_TIME); } std::pair SMS::getNextRequest(Bank bank) { if (bankbuffer[bank].empty()) { + debugManager.printDebugMessage(name(), + "Get next request on bank " + to_string(bank.ID()) + " : EMPTY buffer"); return pair(Command::NOP, NULL); } else @@ -26,6 +29,7 @@ std::pair SMS::getNextRequest(Bank bank) bankbuffer[bank].pop_front(); } + debugManager.printDebugMessage(name(), "Get next request on bank " + to_string(bank.ID())); return pair(command, payload); } @@ -42,7 +46,7 @@ void SMS::batchScheduler() while (true) { - wait(memClk); //TODO: Is this correct??? +// wait(memClk); //TODO: Is this correct??? isSJF = distribution(generator); if (!existReadyBatch()) @@ -50,13 +54,17 @@ void SMS::batchScheduler() // pick & drain a ready batch if (batchFormation()) { - isSJF ? selectSJF() : selectRR(); + isSJF ? selectSJF(memClk) : selectRR(memClk); + } + else + { + wait(newRequest); } } else { // pick & drain a ready batch - isSJF ? selectSJF() : selectRR(); + isSJF ? selectSJF(memClk) : selectRR(memClk); } } } @@ -95,11 +103,23 @@ bool SMS::batchFormation(Thread thread) { buffer[thread].pop_front(); } - return !readybatches[thread]->isEmpty(); + + if (readybatches[thread]->isEmpty()) + { + debugManager.printDebugMessage(name(), + "EMPTY buffer, Ready batch for thread: " + to_string(thread.ID()) + " NOT formed"); + return false; + } + else + { + debugManager.printDebugMessage(name(), + "Form ready batch for thread: " + to_string(thread.ID())); + return true; + } } } -void SMS::selectSJF() +void SMS::selectSJF(sc_time memClk) { // find shorstest thread std::vector threadsWithNonEmptyReadybatches; @@ -121,6 +141,8 @@ void SMS::selectSJF() minThread = thread; } } + debugManager.printDebugMessage(name(), + "[SJF] Select ready batch of thread " + to_string(minThread.ID())); // drain to bank buffers std::deque &requestPtrs = readybatches[minThread]->getTransactions(); @@ -128,6 +150,10 @@ void SMS::selectSJF() { Bank bank = DramExtension::getExtension(*payloadPtrIterator).getBank(); bankbuffer[bank].emplace_back(*payloadPtrIterator); + debugManager.printDebugMessage(name(), + "[SJF] Drain request in the ready batch of thread " + to_string(minThread.ID()) + + " to bankbuffer " + to_string(bank.ID())); + wait(memClk); } requestPtrs.clear(); @@ -137,7 +163,7 @@ void SMS::selectSJF() } -void SMS::selectRR() +void SMS::selectRR(sc_time memClk) { static std::map::iterator next = readybatches.begin(); @@ -151,6 +177,8 @@ void SMS::selectRR() next = readybatches.begin(); } } + debugManager.printDebugMessage(name(), + "[RR] Select ready batch of thread " + to_string((*next).first.ID())); // drain to bank buffers std::deque &requestPtrs = (*next).second->getTransactions(); @@ -158,6 +186,10 @@ void SMS::selectRR() { 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(); @@ -179,5 +211,3 @@ bool SMS::existReadyBatch() return false; } - - diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h index 9d2979f4..a1b7ac70 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.h +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h @@ -9,6 +9,7 @@ #include "../core/ControllerCore.h" #include "../core/configuration/Configuration.h" #include "../../common/dramExtension.h" +#include "../../common/DebugManager.h" #define MIN_TOTAL_REQ 16 @@ -17,7 +18,7 @@ using namespace std; class SMS: public sc_module, public IScheduler { public: - SMS(sc_module_name /*_name*/, ControllerCore &controllerCore, unsigned int SJFprobability) : IScheduler(controllerCore), SJFprobability(SJFprobability) + SMS(sc_module_name /*_name*/, ControllerCore &controllerCore, unsigned int SJFprobability) : IScheduler(controllerCore), SJFprobability(SJFprobability), debugManager(DebugManager::getInstance()) { // initialize memory request counter & memory request intensity for each thread unsigned int totalNumThreads = Configuration::getInstance().NumberOfTracePlayers; @@ -51,11 +52,15 @@ private: std::map inFlightMemRequestCounter; unsigned int SJFprobability; + DebugManager& debugManager; + sc_event newRequest; + bool batchFormation(); - void selectSJF(); - void selectRR(); + void selectSJF(sc_time memClk); + void selectRR(sc_time memClk); bool existReadyBatch(); bool batchFormation(Thread thread); + }; #endif // SMS_H From 64ed3107b56cc7280b3848a619c9468db82838c7 Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Sat, 29 Apr 2017 00:26:27 +0200 Subject: [PATCH 30/59] Fix SelectSJF 1. Form new ready batch when searching for SJF 2. Add return value to indicate whether successful selectSJF --- .../src/controller/scheduler/SMS.cpp | 30 ++++++++++++++++--- .../simulator/src/controller/scheduler/SMS.h | 2 +- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index 51b1b2ec..9cacaef8 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -119,20 +119,36 @@ bool SMS::batchFormation(Thread thread) } } -void SMS::selectSJF(sc_time memClk) +bool SMS::selectSJF(sc_time memClk) { - // find shorstest thread + // find threads with non-empty ready batch std::vector threadsWithNonEmptyReadybatches; for (auto& readybatch : readybatches) { if (!readybatch.second->isEmpty()) { + // marked as thread with non-empty ready batch threadsWithNonEmptyReadybatches.push_back(readybatch.first); } + else + { + // form ready batch for this thread + Thread thread = readybatch.first; + while (!buffer[thread].empty() && readybatch.second->addTransaction(buffer[thread].front())) + { + buffer[thread].pop_front(); + } + // marked as thread with non-empty ready batch + if (!readybatch.second->isEmpty()) { + threadsWithNonEmptyReadybatches.push_back(readybatch.first); + } + } } + if (!threadsWithNonEmptyReadybatches.empty()) { + // pick shortest-job thread among threads with non-empty ready batch Thread minThread = threadsWithNonEmptyReadybatches.front(); for (auto& thread : threadsWithNonEmptyReadybatches) { @@ -157,8 +173,14 @@ void SMS::selectSJF(sc_time memClk) } requestPtrs.clear(); - // reform the drained ready batch - // batchFormation(Thread(minThread)); + // a ready batch has been picked up & drained + return true; + } + else + { + // non-existed ready batch to be picked up & drained + // this mean the request buffers are totally empty + return false; } } diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h index a1b7ac70..590aa4ad 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.h +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h @@ -56,7 +56,7 @@ private: sc_event newRequest; bool batchFormation(); - void selectSJF(sc_time memClk); + bool selectSJF(sc_time memClk); void selectRR(sc_time memClk); bool existReadyBatch(); bool batchFormation(Thread thread); From 55d36d60c27eec3cf85e73043dc5eb89c893ac4a Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Sat, 29 Apr 2017 11:19:06 +0200 Subject: [PATCH 31/59] 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); From a48fd2bfe6179c95f34383ed76a291b994a5d966 Mon Sep 17 00:00:00 2001 From: Johannes Feldmann Date: Tue, 2 May 2017 17:12:13 +0200 Subject: [PATCH 32/59] DISTFILES from resources.pri changed to the standard way. --- DRAMSys/simulator/resources/resources.pri | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/DRAMSys/simulator/resources/resources.pri b/DRAMSys/simulator/resources/resources.pri index 37b75724..7d191a53 100644 --- a/DRAMSys/simulator/resources/resources.pri +++ b/DRAMSys/simulator/resources/resources.pri @@ -5,13 +5,14 @@ OTHER_FILES += resources/simulations/ddr3-example.xml OTHER_FILES += resources/simulations/ddr3-single-device.xml OTHER_FILES += resources/simulations/wideio-example.xml - +OTHER_FILES += resources/simulations/wideio-ecc.xml # Simulator Files OTHER_FILES += resources/configs/simulator/wideio.xml OTHER_FILES += resources/configs/simulator/ddr3.xml OTHER_FILES += resources/configs/simulator/ddr3-single-device.xml OTHER_FILES += resources/configs/simulator/wideio_thermal.xml +OTHER_FILES += resources/configs/simulator/wideio_ecc.xml # Scripts @@ -60,12 +61,14 @@ OTHER_FILES += resources/traces/mediabench-adpcmdecode_32.stl OTHER_FILES += resources/traces/ddr3_example.stl OTHER_FILES += resources/traces/ddr3_single_dev_example.stl OTHER_FILES += resources/traces/ddr3_SAMSUNG_M471B5674QH0_DIMM_example.stl +OTHER_FILES += resources/traces/test_ecc.stl # Memory Controller Configs OTHER_FILES += resources/configs/mcconfigs/fifoStrict.xml OTHER_FILES += resources/configs/mcconfigs/fifo.xml OTHER_FILES += resources/configs/mcconfigs/fr_fcfs.xml OTHER_FILES += resources/configs/mcconfigs/par_bs.xml +OTHER_FILES += resources/configs/mcconfigs/fifo_ecc.xml # Memspecs OTHER_FILES += resources/configs/memspecs/memspec.dtd @@ -108,6 +111,7 @@ OTHER_FILES += resources/configs/memspecs/MICRON_4Gb_LPDDR3-1600_32bit_A.xml OTHER_FILES += resources/configs/memspecs/SAMSUNG_K4B1G1646E_1Gb_DDR3-1600_16bit.xml OTHER_FILES += resources/configs/memspecs/SAMSUNG_K4B4G1646Q_4Gb_DDR3-1066_16bit.xml OTHER_FILES += resources/configs/memspecs/wideio.xml +OTHER_FILES += resources/configs/memspecs/wideio_less_refresh.xml # Address Mapping Configs OTHER_FILES += resources/configs/amconfigs/am_ddr3.xml @@ -134,10 +138,3 @@ OTHER_FILES += resources/configs/thermalsim/mem.flp OTHER_FILES += resources/configs/thermalsim/powerInfo.xml OTHER_FILES += resources/configs/thermalsim/stack.stk OTHER_FILES += resources/configs/thermalsim/config.xml - -DISTFILES += \ - $$PWD/configs/simulator/wideio_ecc.xml \ - $$PWD/configs/mcconfigs/fifo_ecc.xml \ - $$PWD/simulations/wideio-ecc.xml \ - $$PWD/traces/test_ecc.stl \ - $$PWD/configs/memspecs/wideio_less_refresh.xml From 3e2a84775c140c0bbe48faa73318c0013998ffae Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Wed, 3 May 2017 18:15:13 +0200 Subject: [PATCH 33/59] Alter RR & SJF implementation: 1. Save selected thread in each SJF selection 2. Change RR policy to select the next thread i.e. relative to last selected thread by RR or SJF 3. Remove unused methods --- .../src/controller/scheduler/SMS.cpp | 123 ++++++------------ .../simulator/src/controller/scheduler/SMS.h | 11 +- 2 files changed, 48 insertions(+), 86 deletions(-) diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index 06d53552..3a7f984d 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -40,82 +40,16 @@ void SMS::batchScheduler() sc_time memClk = Configuration::getInstance().memSpec.clk; std::default_random_engine generator; std::bernoulli_distribution distribution((double) SJFprobability / 100.0); - std::map::iterator select = readybatches.begin(); wait(150, SC_NS); // Test Purpose while (true) { - if (distribution(generator)) - { - bool success = selectSJF(memClk); - if (!success) - { - wait(newRequest); - } - } - else - { - bool success = selectRR(memClk, select); - if (!success) - { - wait(newRequest); - } - } + selectRR_SJF(distribution(generator), memClk); } } -bool SMS::batchFormation() -{ - if (existReadyBatch()) - { - return false; - SC_REPORT_FATAL("SMS", "Form ready batches when exist at least a ready batch"); - } - else - { - bool isBatchForm = false; - bool isBatchFormForThread = false; - unsigned int totalNumThreads = Configuration::getInstance().NumberOfTracePlayers; - for (unsigned int threadID = 1; threadID <= totalNumThreads; threadID++) - { - isBatchFormForThread = batchFormation(Thread(threadID)); - isBatchForm = isBatchForm || isBatchFormForThread; - } - return isBatchForm; - } -} - -bool SMS::batchFormation(Thread thread) -{ - if (!readybatches[thread]->isEmpty()) - { - return false; - 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(); - } - - if (readybatches[thread]->isEmpty()) - { - debugManager.printDebugMessage(name(), - "EMPTY buffer, Ready batch for thread: " + to_string(thread.ID()) + " NOT formed"); - return false; - } - else - { - debugManager.printDebugMessage(name(), - "Form ready batch for thread: " + to_string(thread.ID())); - return true; - } - } -} - -bool SMS::selectSJF(sc_time memClk) +bool SMS::selectSJF(sc_time memClk, std::map::iterator &select) { // find threads with non-empty ready batch std::vector threadsWithNonEmptyReadybatches; @@ -153,6 +87,10 @@ bool SMS::selectSJF(sc_time memClk) minThread = thread; } } + + // save selected thread + select = readybatches.find(Thread(minThread)); + debugManager.printDebugMessage(name(), "[SJF] Select ready batch of thread " + to_string(minThread.ID())); @@ -229,26 +167,49 @@ bool SMS::selectRR(sc_time memClk, std::map::iterator &sele } requestPtrs.clear(); - // 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() -{ - for (auto& thread_readybatch : readybatches) +void SMS::selectRR_SJF(bool isSJF, sc_time memClk) { + if (isSJF) { - if (!thread_readybatch.second->isEmpty()) + // select by Shortest Job First policy + bool success = selectSJF(memClk, selected); + if (!success) { - return true; + wait(newRequest); } } - return false; + else + { + // select by Round Robin policy + if (selected == readybatches.end()) + { + // first Round Robin selection + selected = readybatches.begin(); + bool success = selectRR(memClk, selected); + if (!success) + { + wait(newRequest); + } + } + else + { + // subsequent Round Robin selection + // move the select iterator to the next one + selected++; + if (selected == readybatches.end()) + { + selected = readybatches.begin(); + } + bool success = selectRR(memClk, selected); + if (!success) + { + wait(newRequest); + } + } + + } } diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h index e9ad838a..70ee26b0 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.h +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h @@ -27,6 +27,9 @@ public: inFlightMemRequestCounter.emplace(Thread(threadID), 0); readybatches[Thread(threadID)] = new ReadyBatch(); } + + // initialize selected thread iterator + selected = readybatches.end(); SC_THREAD(batchScheduler); } SC_HAS_PROCESS(SMS); @@ -50,17 +53,15 @@ private: std::map> bankbuffer; std::map readybatches; std::map inFlightMemRequestCounter; + std::map::iterator selected; unsigned int SJFprobability; DebugManager& debugManager; sc_event newRequest; - bool batchFormation(); - bool selectSJF(sc_time memClk); + bool selectSJF(sc_time memClk, std::map::iterator &select); bool selectRR(sc_time memClk, std::map::iterator &next); - bool existReadyBatch(); - bool batchFormation(Thread thread); - + void selectRR_SJF(bool isSJF, sc_time memClk); }; #endif // SMS_H From b76688fb5bfbd3ec4b0d1da932c4d0a0f3367e94 Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Wed, 3 May 2017 23:24:51 +0200 Subject: [PATCH 34/59] Change to better variable name --- .../src/controller/scheduler/SMS.cpp | 46 +++++++++---------- .../simulator/src/controller/scheduler/SMS.h | 4 +- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index 3a7f984d..f5054993 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -49,7 +49,7 @@ void SMS::batchScheduler() } } -bool SMS::selectSJF(sc_time memClk, std::map::iterator &select) +bool SMS::selectSJF(sc_time memClk, std::map::iterator &lastSelectedThread) { // find threads with non-empty ready batch std::vector threadsWithNonEmptyReadybatches; @@ -89,7 +89,7 @@ bool SMS::selectSJF(sc_time memClk, std::map::iterator &sel } // save selected thread - select = readybatches.find(Thread(minThread)); + lastSelectedThread = readybatches.find(Thread(minThread)); debugManager.printDebugMessage(name(), "[SJF] Select ready batch of thread " + to_string(minThread.ID())); @@ -120,29 +120,29 @@ bool SMS::selectSJF(sc_time memClk, std::map::iterator &sel } -bool SMS::selectRR(sc_time memClk, std::map::iterator &select) +bool SMS::selectRR(sc_time memClk, std::map::iterator &nextSelectedThread) { // pick a non-empty ready batch - std::map::iterator saved = select; - while ((*select).second->isEmpty()) + std::map::iterator savedOriginalNextSelectedThread = nextSelectedThread; + while ((*nextSelectedThread).second->isEmpty()) { // form ready batch for this thread - Thread thread = (*select).first; - while (!buffer[thread].empty() && (*select).second->addTransaction(buffer[thread].front())) + Thread thread = (*nextSelectedThread).first; + while (!buffer[thread].empty() && (*nextSelectedThread).second->addTransaction(buffer[thread].front())) { buffer[thread].pop_front(); } - if ((*select).second->isEmpty()) + if ((*nextSelectedThread).second->isEmpty()) { // cannot form ready batch then move to next thread - select++; - if (select == readybatches.end()) + nextSelectedThread++; + if (nextSelectedThread == readybatches.end()) { - select = readybatches.begin(); + nextSelectedThread = readybatches.begin(); } - if (select == saved) + if (nextSelectedThread == savedOriginalNextSelectedThread) { // the next thread is the original thread, that mean req buffer are totally empty // non-existed ready batch to be picked up & drained @@ -151,17 +151,17 @@ bool SMS::selectRR(sc_time memClk, std::map::iterator &sele } } debugManager.printDebugMessage(name(), - "[RR] Select ready batch of thread " + to_string((*select).first.ID())); + "[RR] Select ready batch of thread " + to_string((*nextSelectedThread).first.ID())); // drain to bank buffers - std::deque &requestPtrs = (*select).second->getTransactions(); + std::deque &requestPtrs = (*nextSelectedThread).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((*select).first.ID()) + "[RR] Drained request in the ready batch of thread " + to_string((*nextSelectedThread).first.ID()) + " to bankbuffer " + to_string(bank.ID())); wait(memClk); } @@ -175,7 +175,7 @@ void SMS::selectRR_SJF(bool isSJF, sc_time memClk) { if (isSJF) { // select by Shortest Job First policy - bool success = selectSJF(memClk, selected); + bool success = selectSJF(memClk, selectedThread); if (!success) { wait(newRequest); @@ -184,11 +184,11 @@ void SMS::selectRR_SJF(bool isSJF, sc_time memClk) { else { // select by Round Robin policy - if (selected == readybatches.end()) + if (selectedThread == readybatches.end()) { // first Round Robin selection - selected = readybatches.begin(); - bool success = selectRR(memClk, selected); + selectedThread = readybatches.begin(); + bool success = selectRR(memClk, selectedThread); if (!success) { wait(newRequest); @@ -198,12 +198,12 @@ void SMS::selectRR_SJF(bool isSJF, sc_time memClk) { { // subsequent Round Robin selection // move the select iterator to the next one - selected++; - if (selected == readybatches.end()) + selectedThread++; + if (selectedThread == readybatches.end()) { - selected = readybatches.begin(); + selectedThread = readybatches.begin(); } - bool success = selectRR(memClk, selected); + bool success = selectRR(memClk, selectedThread); if (!success) { wait(newRequest); diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h index 70ee26b0..1ca75c70 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.h +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h @@ -29,7 +29,7 @@ public: } // initialize selected thread iterator - selected = readybatches.end(); + selectedThread = readybatches.end(); SC_THREAD(batchScheduler); } SC_HAS_PROCESS(SMS); @@ -53,7 +53,7 @@ private: std::map> bankbuffer; std::map readybatches; std::map inFlightMemRequestCounter; - std::map::iterator selected; + std::map::iterator selectedThread; unsigned int SJFprobability; DebugManager& debugManager; From b3309eb2384635251a3d1dd4449eed569ea03a7b Mon Sep 17 00:00:00 2001 From: Johannes Feldmann Date: Thu, 4 May 2017 12:08:07 +0200 Subject: [PATCH 35/59] Added comments Reverted all configurations Adjusted resources.pri Added the enable switch for controllerECC to README.md --- .../resources/configs/simulator/ddr3_ecc.xml | 7 -- DRAMSys/simulator/resources/resources.pri | 4 +- DRAMSys/simulator/src/error/ECC/ECC.cpp | 52 +++++++++-- DRAMSys/simulator/src/error/ECC/ECC.h | 22 ++++- DRAMSys/simulator/src/error/controllerECC.h | 88 ++++++++++--------- DRAMSys/simulator/src/simulation/main.cpp | 2 +- README.md | 4 + 7 files changed, 118 insertions(+), 61 deletions(-) diff --git a/DRAMSys/simulator/resources/configs/simulator/ddr3_ecc.xml b/DRAMSys/simulator/resources/configs/simulator/ddr3_ecc.xml index f1f7bcf8..0d192422 100644 --- a/DRAMSys/simulator/resources/configs/simulator/ddr3_ecc.xml +++ b/DRAMSys/simulator/resources/configs/simulator/ddr3_ecc.xml @@ -12,11 +12,4 @@ - - diff --git a/DRAMSys/simulator/resources/resources.pri b/DRAMSys/simulator/resources/resources.pri index 7d191a53..ac3384bf 100644 --- a/DRAMSys/simulator/resources/resources.pri +++ b/DRAMSys/simulator/resources/resources.pri @@ -6,6 +6,7 @@ OTHER_FILES += resources/simulations/ddr3-example.xml OTHER_FILES += resources/simulations/ddr3-single-device.xml OTHER_FILES += resources/simulations/wideio-example.xml OTHER_FILES += resources/simulations/wideio-ecc.xml +OTHER_FILES += resources/simulations/ddr3-ecc.xml # Simulator Files OTHER_FILES += resources/configs/simulator/wideio.xml @@ -13,7 +14,7 @@ OTHER_FILES += resources/configs/simulator/ddr3.xml OTHER_FILES += resources/configs/simulator/ddr3-single-device.xml OTHER_FILES += resources/configs/simulator/wideio_thermal.xml OTHER_FILES += resources/configs/simulator/wideio_ecc.xml - +OTHER_FILES += resources/configs/simulator/ddr3_ecc.xml # Scripts OTHER_FILES += resources/scripts/address_scrambler.pl @@ -112,6 +113,7 @@ OTHER_FILES += resources/configs/memspecs/SAMSUNG_K4B1G1646E_1Gb_DDR3-1600_16bit OTHER_FILES += resources/configs/memspecs/SAMSUNG_K4B4G1646Q_4Gb_DDR3-1066_16bit.xml OTHER_FILES += resources/configs/memspecs/wideio.xml OTHER_FILES += resources/configs/memspecs/wideio_less_refresh.xml +OTHER_FILES += resources/configs/memspecs/MICRON_1Gb_DDR3-1600_8bit_G_less_refresh.xml # Address Mapping Configs OTHER_FILES += resources/configs/amconfigs/am_ddr3.xml diff --git a/DRAMSys/simulator/src/error/ECC/ECC.cpp b/DRAMSys/simulator/src/error/ECC/ECC.cpp index b8e15743..6cfaffe9 100644 --- a/DRAMSys/simulator/src/error/ECC/ECC.cpp +++ b/DRAMSys/simulator/src/error/ECC/ECC.cpp @@ -1,22 +1,32 @@ #include "ECC.h" +// ************************************************************************************************ +// Function which calculates the number of additional bits needed for a given number of data bits +// to store the hamming code and parity bit for a SECDED implementation unsigned ECC::GetNumParityBits(unsigned nDataBits) { unsigned nParityBits = 0; - // n = 2^k - k - 1 + // Function to calculate the nube of bits: n = 2^k - k - 1 + // ( Source: Hacker's Delight; p. 310; math. function 1 ) while (nDataBits > ((1 << nParityBits) - nParityBits - 1)) { ++nParityBits; } - return nParityBits+1; // +1 for SEC-DED + return nParityBits+1; // +1 for the parity bit } + +// ************************************************************************************************ +// Function which extends a given data word to the needed length for a SECDED code void ECC::ExtendWord(CWord & v) { unsigned end = v.GetLength() + ECC::GetNumParityBits(v.GetLength()); + // Insert x bits for the hamming code at positions where pos = 2^a; a = [0..N] + // In "Hacker's Delight" the smallest index is 1 - But in this beautiful C-Code it's 0 as it + // should be. That's why there is a '-1' in the call of v.Insert. unsigned i = 1; while (i < end) { @@ -24,17 +34,33 @@ void ECC::ExtendWord(CWord & v) i <<= 1; } + // Append one bit for the parity v.Append(CBit()); } +// ************************************************************************************************ +// Function which calculates the Hamming Code bits of an extended Data word. +// Function ExtendWord must be called before calling this function +// The calculated bits are stored in p, so the length of p should be at least +// 'GetNumParityBits(#data bits)-1' void ECC::CalculateCheckbits(CWord & v, CWord & p) { - // Hamming-Code Prüfbits füllen - unsigned i = 1, l = 0; + unsigned i = 1, l = 0; // Last bit is the parity bit - don't use this in the algorithm for hamming code unsigned len = v.GetLength()-1; + // Following Graph should show you the behaviour of this algorithm + // #Data bits: 11 #Hamming bits: 4 -> SECDED bits: 16 (incl. parity bit) + // Hamming Code Bit: | Bits used -> data(X)/Hamming Code(H) // Bit unused - + // 0 | H-X-X-X-X-X-X-X + // 1 | -HX--XX--XX--XX + // 2 | ---HXXX----XXXX + // 3 | -------HXXXXXXX + // For further information read "Hacker's delight" chapter 15 + // ATTENTION: The order of indices is different from the one in the book, + // but it doesn't matter in which order your data or check bits are. + // But it should be the same for encoding and decoding while (i < len) { for (unsigned j = (i - 1); j < len; j += (i << 1)) @@ -51,21 +77,26 @@ void ECC::CalculateCheckbits(CWord & v, CWord & p) } } +// ************************************************************************************************ +// Function which inserts the checkbits which were calculated with 'CalculateCheckbits' in the +// extended data word. This is needed to calculate a proper parity of ALL bits to achive a SECDED +// behaviour. void ECC::InsertCheckbits(CWord& v, CWord p) { - // Prüfbits einfügen unsigned i = 1, j = 0; while (i <= v.GetLength()-1) { v[i - 1] = p[j++]; i <<= 1; } - } + +// ************************************************************************************************ +// Function which extracts the checkbits out of an extended data word. This is needed to check for +// bit error in the data word. void ECC::ExtractCheckbits(CWord v, CWord & p) { - // Prüfbits extrahieren unsigned i = 1, j = 0; while(i <= v.GetLength()-1) { @@ -74,6 +105,9 @@ void ECC::ExtractCheckbits(CWord v, CWord & p) } } +// ************************************************************************************************ +// Function which calculates the overal parity +// Simply XOR all bits void ECC::CalculateParityBit(CWord v, CBit & p) { // Paritybit @@ -84,11 +118,15 @@ void ECC::CalculateParityBit(CWord v, CBit & p) } } +// ************************************************************************************************ +// Function to insert the parity bit into the extended data word void ECC::InsertParityBit(CWord& v, CBit p) { v[v.GetLength() - 1] = p; } +// ************************************************************************************************ +// Function to extract the parity bit out of an extended data word. void ECC::ExtractParityBit(CWord v, CBit & p) { p = v[v.GetLength() - 1]; diff --git a/DRAMSys/simulator/src/error/ECC/ECC.h b/DRAMSys/simulator/src/error/ECC/ECC.h index 8379999a..3e9b8238 100644 --- a/DRAMSys/simulator/src/error/ECC/ECC.h +++ b/DRAMSys/simulator/src/error/ECC/ECC.h @@ -3,12 +3,30 @@ #include "Word.h" #include "Bit.h" +// ************************************************************************************************ +// +// | __/ __/ __| | __| _ _ _ __| |_(_)___ _ _ ___ +// | _| (_| (__ | _| || | ' \/ _| _| / _ \ ' \(_-< +// |___\___\___| |_| \_,_|_||_\__|\__|_\___/_||_/__/ +// +// ------------------------------------------------------------------------------------------------ +// ECC Implementation as described in "Hacker's Delight - second Edition" by Henry S. Warren, Jr. +// ------------------------------------------------------------------------------------------------ +// This namespace gives you some handy functions to get a SEC-DED implementation. +// +// SEC-DED: Single Error Correction - Double Error Detection +// This is the most common error correction code (ECC). +// It consists of two different correction codes: Haming code + parity code. +// +// For further details read chapter 15 of "Hacker's Delight - second Edition" +// ************************************************************************************************ + namespace ECC { - unsigned GetNumParityBits(unsigned nDataBits); - // Erweitert das Wort um zusätzliche Bits für die Berechnung des Hamming-Codes + // Extends the data word that it can be used with hamming code + // Several bits will be included at specific places void ExtendWord(CWord &v); void CalculateCheckbits(CWord &v, CWord & p); diff --git a/DRAMSys/simulator/src/error/controllerECC.h b/DRAMSys/simulator/src/error/controllerECC.h index 509e1036..9ca85fe8 100644 --- a/DRAMSys/simulator/src/error/controllerECC.h +++ b/DRAMSys/simulator/src/error/controllerECC.h @@ -14,7 +14,7 @@ using namespace tlm; struct ControllerECC: sc_module { private: - map> m_mBuffer; + map m_mDataPointer; public: tlm_utils::multi_passthrough_target_socket t_socket; @@ -31,7 +31,7 @@ public: // Forward interface virtual tlm::tlm_sync_enum nb_transport_fw( int id, tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_time& delay ) { - if(trans.get_command() == TLM_WRITE_COMMAND && trans.get_response_status() == TLM_INCOMPLETE_RESPONSE) + if(trans.get_command() == TLM_WRITE_COMMAND && phase == BEGIN_REQ) { // Get data and length unsigned nDataLength = trans.get_data_length(); @@ -69,47 +69,37 @@ public: // Copy old data memcpy(&pDataECC[i*9], &pData[i<<3], 8); - // Save new data + // Save hamming code + parity bit in the last byte checkbits.Copy(&pDataECC[i*9+8]); } - // Print all -// for(unsigned i = 0; i < nBlocks; i++) -// { -// for(unsigned j = 0; j < 9; j++) -// { -// cout << setw(2) << setfill('0') << hex << uppercase << (int)pDataECC[i*9+j]; -// } -// cout << endl; -// } -// cout << endl; - // Change transport data length trans.set_data_length(nBlocks*9); - // delete old data - delete[] trans.get_data_ptr(); + // store old data + m_mDataPointer[id] = trans.get_data_ptr(); // Set new data trans.set_data_ptr(pDataECC); } - else if(trans.get_response_status() == TLM_INCOMPLETE_RESPONSE) - { - // 64 -> 72 + else if(trans.get_command() == TLM_READ_COMMAND && phase == BEGIN_REQ) + { + // 64 -> 72 - // Get data length - unsigned nDataLength = trans.get_data_length(); + // Get data length + unsigned nDataLength = trans.get_data_length(); - // delete old data - delete[] trans.get_data_ptr(); + // store old data + m_mDataPointer[id] = trans.get_data_ptr(); - // Set new data - nDataLength += nDataLength>>3; - trans.set_data_ptr(new unsigned char [nDataLength]); + // Set new data + nDataLength += nDataLength>>3; + trans.set_data_ptr(new unsigned char [nDataLength]); + + // Change transport data length + trans.set_data_length(nDataLength); + } - // Change transport data length - trans.set_data_length(nDataLength); - } return i_socket[id]->nb_transport_fw( trans, phase, delay ); } @@ -117,7 +107,7 @@ public: // Backward interface virtual tlm::tlm_sync_enum nb_transport_bw( int id, tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_time& delay ) { - if(trans.get_command() == TLM_READ_COMMAND && phase == 3) + if(trans.get_command() == TLM_READ_COMMAND && phase == BEGIN_RESP) { // Get data and length unsigned nDataLength = trans.get_data_length(); @@ -126,17 +116,6 @@ public: // Calculate how many 72 bit blocks are there unsigned nBlocks = nDataLength/9; - // Print all -// for(unsigned i = 0; i < nBlocks; i++) -// { -// for(unsigned j = 0; j < 9; j++) -// { -// cout << setw(2) << setfill('0') << hex << uppercase << (int)pData[i*9+j]; -// } -// cout << endl; -// } -// cout << endl; - // Verify ECC data for every block for(unsigned i = 0; i < nBlocks; i++) { @@ -209,8 +188,11 @@ public: // Change transport data length trans.set_data_length(nBlocks<<3); - // New Data - unsigned char* pDataECC = new unsigned char[nBlocks<<3]; + // load data pointer + auto it = m_mDataPointer.find(id); + assert(it != m_mDataPointer.end()); + + unsigned char* pDataECC = it->second; // Copy data memcpy(pDataECC, pData, nBlocks<<3); @@ -221,6 +203,26 @@ public: // Set new data trans.set_data_ptr(pDataECC); } + else if(trans.get_command() == TLM_WRITE_COMMAND && phase == BEGIN_RESP) + { + // 72 -> 64 + + // delete old data + delete[] trans.get_data_ptr(); + + // Get data length + unsigned nDataLength = trans.get_data_length(); + + // load data pointer + auto it = m_mDataPointer.find(id); + assert(it != m_mDataPointer.end()); + + trans.set_data_ptr(it->second); + + // Change transport data length + trans.set_data_length((nDataLength/9)<<3); + } + return t_socket[id]->nb_transport_bw( trans, phase, delay ); } }; diff --git a/DRAMSys/simulator/src/simulation/main.cpp b/DRAMSys/simulator/src/simulation/main.cpp index 0bb75469..18e00f77 100644 --- a/DRAMSys/simulator/src/simulation/main.cpp +++ b/DRAMSys/simulator/src/simulation/main.cpp @@ -72,7 +72,7 @@ int sc_main(int argc, char **argv) } else { - SimulationXML = resources + "simulations/ddr3-ecc.xml"; + SimulationXML = resources + "simulations/ddr3-example.xml"; } std::vector players; diff --git a/README.md b/README.md index eb3e5f75..06e96cb6 100644 --- a/README.md +++ b/README.md @@ -544,6 +544,7 @@ Below, the sub-configurations are listed and explained. + ``` @@ -578,6 +579,9 @@ Below, the sub-configurations are listed and explained. - *CheckTLM2Protocol* (boolean) - "1": enables the TLM 2.0 Protocol Checking - "0": disables the TLM 2.0 Protocol Checking + - *EnableControllerECC* (boolean) + - "1": enables the ECC Controller with classic SECDED implementation + - "0": disables the ECC Controller with classic SECDED implementation - **Temperature Simulator Configuration** From 0b55dfd7e706939115a84991f74ea1cb26085e01 Mon Sep 17 00:00:00 2001 From: Johannes Feldmann Date: Thu, 4 May 2017 12:22:31 +0200 Subject: [PATCH 36/59] Revert several changes. --- .../resources/configs/mcconfigs/fifo.xml | 2 +- DRAMSys/simulator/src/error/errormodel.cpp | 20 ------------------- 2 files changed, 1 insertion(+), 21 deletions(-) diff --git a/DRAMSys/simulator/resources/configs/mcconfigs/fifo.xml b/DRAMSys/simulator/resources/configs/mcconfigs/fifo.xml index d6acf112..08135f13 100644 --- a/DRAMSys/simulator/resources/configs/mcconfigs/fifo.xml +++ b/DRAMSys/simulator/resources/configs/mcconfigs/fifo.xml @@ -15,6 +15,6 @@ - Store (store data without errormodel), - ErrorModel (store data with errormodel) --> - + diff --git a/DRAMSys/simulator/src/error/errormodel.cpp b/DRAMSys/simulator/src/error/errormodel.cpp index 5ff3693f..499d16f2 100644 --- a/DRAMSys/simulator/src/error/errormodel.cpp +++ b/DRAMSys/simulator/src/error/errormodel.cpp @@ -110,26 +110,6 @@ void errorModel::init() //weakCells[0].row = 0; //weakCells[0].dependent = true; - weakCells[0].bit = 0; - weakCells[0].col = 0; - weakCells[0].row = 0; - weakCells[0].dependent = false; - - weakCells[0].bit = 5; - weakCells[0].col = 0; - weakCells[0].row = 0; - weakCells[0].dependent = false; - - weakCells[0].bit = 12; - weakCells[0].col = 0; - weakCells[0].row = 0; - weakCells[0].dependent = false; - - weakCells[0].bit = 22; - weakCells[0].col = 0; - weakCells[0].row = 0; - weakCells[0].dependent = false; - markBitFlips(); } From 4d9a6f74d8d09235c8b9b061f62db4882f728a97 Mon Sep 17 00:00:00 2001 From: Johannes Feldmann Date: Mon, 8 May 2017 10:13:57 +0200 Subject: [PATCH 37/59] ControllerECC: stored data pointer will be erased from map if not needed anymore. Moved {ErrorChipSeed, ErrorCSVFile, StoreMode} from mcconfig zu simconfig Error files moved to resources/error/ and are now named correctly. --- .../resources/configs/mcconfigs/fifo.xml | 8 - .../configs/mcconfigs/fifoStrict.xml | 8 - .../resources/configs/mcconfigs/fifo_ecc.xml | 8 - .../resources/configs/mcconfigs/fr_fcfs.xml | 8 - .../resources/configs/mcconfigs/par_bs.xml | 8 - .../configs/simulator/ddr3-single-device.xml | 8 + .../resources/configs/simulator/ddr3.xml | 8 + .../resources/configs/simulator/ddr3_ecc.xml | 8 + .../resources/configs/simulator/wideio.xml | 8 + .../configs/simulator/wideio_ecc.xml | 8 + .../configs/simulator/wideio_thermal.xml | 8 + .../error.csv => resources/error/wideio.csv} | 0 DRAMSys/simulator/resources/resources.pri | 3 + .../resources/simulations/sim-batch.xml | 52 +++ DRAMSys/simulator/src/error/controllerECC.h | 8 +- .../src/simulation/SimulationManager.cpp | 310 ++++++++++++++++++ 16 files changed, 420 insertions(+), 41 deletions(-) rename DRAMSys/simulator/{src/error/error.csv => resources/error/wideio.csv} (100%) create mode 100644 DRAMSys/simulator/resources/simulations/sim-batch.xml create mode 100644 DRAMSys/simulator/src/simulation/SimulationManager.cpp diff --git a/DRAMSys/simulator/resources/configs/mcconfigs/fifo.xml b/DRAMSys/simulator/resources/configs/mcconfigs/fifo.xml index 08135f13..b09a4cfa 100644 --- a/DRAMSys/simulator/resources/configs/mcconfigs/fifo.xml +++ b/DRAMSys/simulator/resources/configs/mcconfigs/fifo.xml @@ -8,13 +8,5 @@ - - - - diff --git a/DRAMSys/simulator/resources/configs/mcconfigs/fifoStrict.xml b/DRAMSys/simulator/resources/configs/mcconfigs/fifoStrict.xml index 5c58a9c5..7ca1a824 100644 --- a/DRAMSys/simulator/resources/configs/mcconfigs/fifoStrict.xml +++ b/DRAMSys/simulator/resources/configs/mcconfigs/fifoStrict.xml @@ -8,13 +8,5 @@ - - - - diff --git a/DRAMSys/simulator/resources/configs/mcconfigs/fifo_ecc.xml b/DRAMSys/simulator/resources/configs/mcconfigs/fifo_ecc.xml index d6acf112..b09a4cfa 100644 --- a/DRAMSys/simulator/resources/configs/mcconfigs/fifo_ecc.xml +++ b/DRAMSys/simulator/resources/configs/mcconfigs/fifo_ecc.xml @@ -8,13 +8,5 @@ - - - - diff --git a/DRAMSys/simulator/resources/configs/mcconfigs/fr_fcfs.xml b/DRAMSys/simulator/resources/configs/mcconfigs/fr_fcfs.xml index fad8b021..0ff319b0 100644 --- a/DRAMSys/simulator/resources/configs/mcconfigs/fr_fcfs.xml +++ b/DRAMSys/simulator/resources/configs/mcconfigs/fr_fcfs.xml @@ -8,14 +8,6 @@ - - - - diff --git a/DRAMSys/simulator/resources/configs/mcconfigs/par_bs.xml b/DRAMSys/simulator/resources/configs/mcconfigs/par_bs.xml index 78a8afd7..63fb4a27 100644 --- a/DRAMSys/simulator/resources/configs/mcconfigs/par_bs.xml +++ b/DRAMSys/simulator/resources/configs/mcconfigs/par_bs.xml @@ -8,13 +8,5 @@ - - - - diff --git a/DRAMSys/simulator/resources/configs/simulator/ddr3-single-device.xml b/DRAMSys/simulator/resources/configs/simulator/ddr3-single-device.xml index 35fd3dec..0a19ff35 100644 --- a/DRAMSys/simulator/resources/configs/simulator/ddr3-single-device.xml +++ b/DRAMSys/simulator/resources/configs/simulator/ddr3-single-device.xml @@ -11,4 +11,12 @@ + + + + diff --git a/DRAMSys/simulator/resources/configs/simulator/ddr3.xml b/DRAMSys/simulator/resources/configs/simulator/ddr3.xml index 9e322605..155ab0ff 100644 --- a/DRAMSys/simulator/resources/configs/simulator/ddr3.xml +++ b/DRAMSys/simulator/resources/configs/simulator/ddr3.xml @@ -11,6 +11,14 @@ + + + + + diff --git a/DRAMSys/simulator/resources/configs/simulator/wideio.xml b/DRAMSys/simulator/resources/configs/simulator/wideio.xml index 8ba8f3ba..ba435056 100644 --- a/DRAMSys/simulator/resources/configs/simulator/wideio.xml +++ b/DRAMSys/simulator/resources/configs/simulator/wideio.xml @@ -10,5 +10,13 @@ + + + + diff --git a/DRAMSys/simulator/resources/configs/simulator/wideio_ecc.xml b/DRAMSys/simulator/resources/configs/simulator/wideio_ecc.xml index 4b8ad3d1..3a7c43e5 100644 --- a/DRAMSys/simulator/resources/configs/simulator/wideio_ecc.xml +++ b/DRAMSys/simulator/resources/configs/simulator/wideio_ecc.xml @@ -11,5 +11,13 @@ + + + + diff --git a/DRAMSys/simulator/resources/configs/simulator/wideio_thermal.xml b/DRAMSys/simulator/resources/configs/simulator/wideio_thermal.xml index 42dcda72..880e573d 100644 --- a/DRAMSys/simulator/resources/configs/simulator/wideio_thermal.xml +++ b/DRAMSys/simulator/resources/configs/simulator/wideio_thermal.xml @@ -10,5 +10,13 @@ + + + + diff --git a/DRAMSys/simulator/src/error/error.csv b/DRAMSys/simulator/resources/error/wideio.csv similarity index 100% rename from DRAMSys/simulator/src/error/error.csv rename to DRAMSys/simulator/resources/error/wideio.csv diff --git a/DRAMSys/simulator/resources/resources.pri b/DRAMSys/simulator/resources/resources.pri index ac3384bf..b3f97407 100644 --- a/DRAMSys/simulator/resources/resources.pri +++ b/DRAMSys/simulator/resources/resources.pri @@ -140,3 +140,6 @@ OTHER_FILES += resources/configs/thermalsim/mem.flp OTHER_FILES += resources/configs/thermalsim/powerInfo.xml OTHER_FILES += resources/configs/thermalsim/stack.stk OTHER_FILES += resources/configs/thermalsim/config.xml + +# Error Simulation data +OTHER_FILES += resources/error/wideio.csv diff --git a/DRAMSys/simulator/resources/simulations/sim-batch.xml b/DRAMSys/simulator/resources/simulations/sim-batch.xml new file mode 100644 index 00000000..0752914c --- /dev/null +++ b/DRAMSys/simulator/resources/simulations/sim-batch.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + chstone-adpcm_32.stl + + + + + diff --git a/DRAMSys/simulator/src/error/controllerECC.h b/DRAMSys/simulator/src/error/controllerECC.h index 9ca85fe8..beefe784 100644 --- a/DRAMSys/simulator/src/error/controllerECC.h +++ b/DRAMSys/simulator/src/error/controllerECC.h @@ -194,6 +194,9 @@ public: unsigned char* pDataECC = it->second; + // delete data pointer from map + m_mDataPointer.erase(it); + // Copy data memcpy(pDataECC, pData, nBlocks<<3); @@ -219,7 +222,10 @@ public: trans.set_data_ptr(it->second); - // Change transport data length + // delete data pointer from map + m_mDataPointer.erase(it); + + // Change transport data length trans.set_data_length((nDataLength/9)<<3); } diff --git a/DRAMSys/simulator/src/simulation/SimulationManager.cpp b/DRAMSys/simulator/src/simulation/SimulationManager.cpp new file mode 100644 index 00000000..a3494667 --- /dev/null +++ b/DRAMSys/simulator/src/simulation/SimulationManager.cpp @@ -0,0 +1,310 @@ +/* + * Copyright (c) 2015, University of Kaiserslautern + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: + * Janik Schlemminger + * Matthias Jung + * Eder F. Zulian + */ + +#include +#include + +#include "SimulationManager.h" +#include "../common/Utils.h" + +using namespace std; +using namespace tinyxml2; + +SimulationManager::SimulationManager(string resources) : resources(resources) +{ +} + +SimulationManager::~SimulationManager() +{ + for (auto player : players) { + delete player; + } +#if USE_EXAMPLE_INITIATOR + delete init; + delete exampleInitiatorTlmChecker; +#endif + + for (auto tlmChecker : playersTlmCheckers) { + delete tlmChecker; + } +} + +void SimulationManager::loadSimulationsFromXML(string uri) +{ + cout << "\n\nload simulation-batch:" << endl; + cout << headline << endl; + + exportPath = getFileName(uri); + loadXML(uri, simulationdoc); + + cout << "\t-> parsing simulation objects .." << endl; + + XMLElement* simulation = simulationdoc.FirstChildElement("simulation"); + string xmlNodeName(simulation->Name()); + if( xmlNodeName != "simulation") + reportFatal("SimulationManager", "simulation node expected"); + parseSimulationBatch(simulation); + + cout << "\t-> simulation batches loaded successfully!\n" << endl; + + for (auto batch : simulationBatches) + { + batch.print(); + } +} + +void SimulationManager::runSimulations() +{ + for (auto& batch : simulationBatches) + { + boost::filesystem::path dir(exportPath); + boost::filesystem::create_directories(dir); + + for (auto& dramSetup : batch.dramSetups) + { + for (auto& traceSetup : batch.traceSetups) + { + string exportname = exportPath + "/" + traceSetup.first; + instantiateModules(exportname, dramSetup, traceSetup.second); + bindSockets(); + runSimulation(exportname); + } + } + } +} + +void SimulationManager::parseSimulationBatch(XMLElement* simulation) +{ + SimulationBatch batch; + + XMLElement* simconfig = simulation->FirstChildElement("simconfig"); + + XMLElement *thermalsimconfig = simulation->FirstChildElement("thermalsimconfig"); + + XMLElement* memspecs = simulation->FirstChildElement("memspecs"); + if(memspecs == NULL) memspecs = simulation; + + XMLElement* addressmappings = simulation->FirstChildElement("addressmappings"); + if(addressmappings == NULL) addressmappings = simulation; + + XMLElement* mcconfigs = simulation->FirstChildElement("mcconfigs"); + if(mcconfigs == NULL) mcconfigs = simulation; + + for (XMLElement* memspec = memspecs->FirstChildElement("memspec"); memspec != NULL; + memspec = memspec->NextSiblingElement("memspec")) + { + + for (XMLElement* addressmapping = addressmappings->FirstChildElement("addressmapping"); addressmapping != NULL; + addressmapping = addressmapping->NextSiblingElement("addressmapping")) + { + + for (XMLElement* mcconfig = mcconfigs->FirstChildElement("mcconfig"); + mcconfig != NULL; mcconfig = mcconfig->NextSiblingElement("mcconfig")) + { + batch.dramSetups.push_back(DramSetup(memspec, mcconfig, simconfig, addressmapping, thermalsimconfig)); + } + } + } + + addTraceSetups(batch, simulation); + + simulationBatches.push_back(batch); +} + +void SimulationManager::instantiateModules(string traceName, DramSetup dramSetup, vector traceSetup) +{ + + simulation = new Simulation("sim", resources, traceName, dramSetup, traceSetup); + +#if USE_EXAMPLE_INITIATOR + init = new ExampleInitiator("init"); + if(Configuration::getInstance().CheckTLM2Protocol) { + string str = "ExampleInitiatorTLMChecker"; + exampleInitiatorTlmChecker = new tlm_utils::tlm2_base_protocol_checker<>(str.c_str()); + } +#else + for (size_t i = 0; i < Configuration::getInstance().NumberOfTracePlayers; i++) { + std::string playerStr = "tracePlayer" + std::to_string(i); + TracePlayer *player; + sc_time playerClk; + + // The clock frequency for the player can be specified in the + // configuration file like in the example below (200 MHz): + // + // + // + // chstone-adpcm_32.stl + // + // + // + // If it is not specified in the configuration, the player will be + // configured to use the memory clock frequency got from the memory + // specs. + if (traceSetup[i].clkMhz == 0) + playerClk = Configuration::getInstance().memSpec.clk; + else + playerClk = FrequencyToClk(traceSetup[i].clkMhz); + const string pathToResources = resources; + player = new StlPlayer(playerStr.c_str(), pathToResources + string("traces/") + traceSetup[i].trace, playerClk, this); + if(Configuration::getInstance().SimulationProgressBar) + { + totalTransactions += player->getNumberOfLines(pathToResources + string("traces/") + traceSetup[i].trace); + } + players.push_back(player); + + if(Configuration::getInstance().CheckTLM2Protocol) { + string str = "TLMCheckerPlayer"+ std::to_string(i); + tlm_utils::tlm2_base_protocol_checker<> * playerTlmChecker = new tlm_utils::tlm2_base_protocol_checker<>(str.c_str()); + playersTlmCheckers.push_back(playerTlmChecker); + } + } + remainingTransactions = totalTransactions; +#endif /* USE_EXAMPLE_INITIATOR */ +} + +void SimulationManager::bindSockets() +{ +#if USE_EXAMPLE_INITIATOR + if(Configuration::getInstance().CheckTLM2Protocol) { + init->socket.bind(exampleInitiatorTlmChecker->target_socket); + exampleInitiatorTlmChecker->initiator_socket.bind(simulation->tSocket); + + } + else { + init->socket.bind(simulation->tSocket); +#else + if(Configuration::getInstance().CheckTLM2Protocol) { + for (size_t i = 0; i < players.size(); i++) { + players[i]->iSocket.bind(playersTlmCheckers[i]->target_socket); + playersTlmCheckers[i]->initiator_socket.bind(simulation->tSocket); + } + + } + else { + for (auto player : players) { + player->iSocket.bind(simulation->tSocket); + } + +#endif + } +} + +void SimulationManager::runSimulation(string traceName) +{ + report("\n\nStarting simulation:"); + report(headline); + report(" -> setup: \t\t" + getFileName(traceName)); + report(" -> memspec: \t\t" + Configuration::getInstance().memSpec.MemoryId); + cout << endl; + simStartTime = clock(); + + for (auto player : players) { + player->nextPayload(); + } + + sc_set_stop_mode(SC_STOP_FINISH_DELTA); + sc_start(); + double elapsed_secs = double(clock() - simStartTime) / CLOCKS_PER_SEC; + report("\nSimulation took " + to_string(elapsed_secs) + " seconds\n"); + delete simulation; +} + +void SimulationManager::startTraceAnalyzer() +{ + string p = getenv("trace"); + string run_tpr = p + " -f "; + run_tpr += "&"; + system(run_tpr.c_str()); +} + +void SimulationManager::addTraceSetups(SimulationBatch &batch, tinyxml2::XMLElement *simulation) +{ + vector devices; + XMLElement *tracesetups = simulation->FirstChildElement("tracesetups"); + XMLElement *simconfig = simulation->FirstChildElement("simconfig"); + unsigned int numberOfTracePlayers = 1; + XMLElement *ntp = simconfig->FirstChildElement("NumberOfTracePlayers"); + if (ntp != NULL) + ntp->QueryUnsignedAttribute("value", &numberOfTracePlayers); + + for (XMLElement *tracesetup = tracesetups->FirstChildElement("tracesetup"); tracesetup != NULL; tracesetup = tracesetup->NextSiblingElement("tracesetup")) { + for (XMLElement *device = tracesetup->FirstChildElement("device"); device != NULL; device = device->NextSiblingElement("device")) { + devices.push_back(Device(device->GetText(), device->IntAttribute("clkMhz"), device->IntAttribute("bl"))); + } + + // This step is done here to add a default device in case the user haven't specified a trace file to be executed by one or more trace players. + while (devices.size() < numberOfTracePlayers) { + devices.push_back(Device()); + } + + batch.traceSetups.emplace(tracesetup->Attribute("id"), devices); + devices.clear(); + } +} + +void inline SimulationManager::tracePlayerTerminates() +{ + static unsigned int finishedTracePlayers = 0; + finishedTracePlayers++; + + if (finishedTracePlayers == Configuration::getInstance().NumberOfTracePlayers) + simulation->terminateSimulation.notify(); +} +void inline SimulationManager::transactionFinished() +{ + remainingTransactions--; + loadbar(totalTransactions - remainingTransactions, totalTransactions); + if (remainingTransactions == 0) + { + cout << endl; + } +} +void SimulationManager::report(string message) +{ + cout << message << endl; +} + +void SimulationBatch::print() +{ + for (auto& s : traceSetups) + { + cout << "trace-setup " + s.first + ":\n"; + for (Device d : s.second) + cout << "\t(" << d.burstLength << ") " << d.trace << ";" << endl; + cout << endl; + } +} From 7d15ebc45ee82c0dec207bd184fed4038b11c8eb Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Tue, 9 May 2017 19:13:17 +0200 Subject: [PATCH 38/59] Fix undefined symbols for architecture x86_64 "SMS::batchScheduler()", referenced from: SMS::SMS(sc_core::sc_module_name, ControllerCore&, unsigned int) in libDRAMSys.a(Controller.o) "vtable for SMS", referenced from: SMS::SMS(sc_core::sc_module_name, ControllerCore&, unsigned int) in libDRAMSys.a(Controller.o) NOTE: a missing vtable usually means the first non-inline virtual member function has no definition. --- DRAMSys/simulator/library.pro | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/DRAMSys/simulator/library.pro b/DRAMSys/simulator/library.pro index 5e9f63a4..3770561e 100644 --- a/DRAMSys/simulator/library.pro +++ b/DRAMSys/simulator/library.pro @@ -81,6 +81,8 @@ SOURCES += \ src/controller/scheduler/PARBS.cpp \ src/controller/scheduler/Fr_Fcfs.cpp \ src/controller/scheduler/Fifo.cpp \ + src/controller/scheduler/SMS.cpp \ + src/controller/scheduler/ReadyBatch.cpp \ src/controller/core/refresh/RefreshManagerBankwise.cpp \ src/controller/core/refresh/RefreshManager.cpp \ src/controller/core/scheduling/checker/WriteChecker.cpp \ @@ -130,6 +132,8 @@ HEADERS += \ src/controller/scheduler/PARBS.h \ src/controller/scheduler/Fr_Fcfs.h \ src/controller/scheduler/Fifo.h \ + src/controller/scheduler/SMS.h \ + src/controller/scheduler/ReadyBatch.h \ src/controller/Controller.h \ src/controller/core/refresh/RefreshManagerBankwise.h \ src/controller/core/refresh/RefreshManager.h \ From 92bd873a3effc1a9f10d7174837c1d8b1e5ecfa7 Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Tue, 9 May 2017 23:23:44 +0200 Subject: [PATCH 39/59] Fix segmentation fault due to calling methods on NULL ReadyBatch Object --- DRAMSys/simulator/src/controller/scheduler/SMS.cpp | 5 +++++ DRAMSys/simulator/src/simulation/TracePlayerListener.h | 1 + DRAMSys/simulator/src/simulation/TraceSetup.h | 1 + 3 files changed, 7 insertions(+) diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index 82e9f6e0..7f505a5d 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -133,6 +133,11 @@ bool SMS::selectSJF(sc_time memClk, std::map::iterator &las bool SMS::selectRR(sc_time memClk, std::map::iterator &nextSelectedThread) { + // no request for this channel, the readybatches map is empty then return + if (readybatches.empty()) { + return false; + } + // pick a non-empty ready batch std::map::iterator savedOriginalNextSelectedThread = nextSelectedThread; while ((*nextSelectedThread).second->isEmpty()) diff --git a/DRAMSys/simulator/src/simulation/TracePlayerListener.h b/DRAMSys/simulator/src/simulation/TracePlayerListener.h index 95c52773..bec9f043 100644 --- a/DRAMSys/simulator/src/simulation/TracePlayerListener.h +++ b/DRAMSys/simulator/src/simulation/TracePlayerListener.h @@ -43,6 +43,7 @@ class TracePlayerListener public: virtual void tracePlayerTerminates() = 0; virtual void transactionFinished() = 0; + virtual ~TracePlayerListener(){}; }; #endif // TRACEPLAYERLISTENER_H diff --git a/DRAMSys/simulator/src/simulation/TraceSetup.h b/DRAMSys/simulator/src/simulation/TraceSetup.h index a9f0b8e5..a11b4abe 100644 --- a/DRAMSys/simulator/src/simulation/TraceSetup.h +++ b/DRAMSys/simulator/src/simulation/TraceSetup.h @@ -53,6 +53,7 @@ public: virtual void tracePlayerTerminates() override; virtual void transactionFinished() override; + virtual ~traceSetup(){}; private: unsigned int NumberOfTracePlayers; From 9c4cb6f979e82d222c076272b3827e26a80308f4 Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Thu, 11 May 2017 15:28:45 +0200 Subject: [PATCH 40/59] Fix auxiliary stuffs for simulating SMS --- DRAMSys/simulator/resources/resources.pri | 1 + DRAMSys/simulator/src/simulation/main.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/DRAMSys/simulator/resources/resources.pri b/DRAMSys/simulator/resources/resources.pri index dc2a316a..914daa88 100644 --- a/DRAMSys/simulator/resources/resources.pri +++ b/DRAMSys/simulator/resources/resources.pri @@ -70,6 +70,7 @@ OTHER_FILES += resources/configs/mcconfigs/fifoStrict.xml OTHER_FILES += resources/configs/mcconfigs/fifo.xml OTHER_FILES += resources/configs/mcconfigs/fr_fcfs.xml OTHER_FILES += resources/configs/mcconfigs/par_bs.xml +OTHER_FILES += resources/configs/mcconfigs/sms.xml # Memspecs OTHER_FILES += resources/configs/memspecs/memspec.dtd diff --git a/DRAMSys/simulator/src/simulation/main.cpp b/DRAMSys/simulator/src/simulation/main.cpp index 18e00f77..a370a6af 100644 --- a/DRAMSys/simulator/src/simulation/main.cpp +++ b/DRAMSys/simulator/src/simulation/main.cpp @@ -72,7 +72,7 @@ int sc_main(int argc, char **argv) } else { - SimulationXML = resources + "simulations/ddr3-example.xml"; + SimulationXML = resources + "simulations/sms-example.xml"; } std::vector players; From 65c1abcc7af2050e6c51213ffb73ed1c56a3135f Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Thu, 11 May 2017 15:54:53 +0200 Subject: [PATCH 41/59] Simplify picking policy of the batch scheduler --- .../src/controller/scheduler/SMS.cpp | 67 +++++++++---------- .../simulator/src/controller/scheduler/SMS.h | 8 +-- 2 files changed, 35 insertions(+), 40 deletions(-) diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index 7f505a5d..0326d5e1 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -52,7 +52,7 @@ void SMS::batchScheduler() std::default_random_engine generator; std::bernoulli_distribution distribution((double) SJFprobability / 100.0); - wait(150, SC_NS); // Test Purpose +// wait(150, SC_NS); // Test Purpose while (true) { @@ -60,7 +60,7 @@ void SMS::batchScheduler() } } -bool SMS::selectSJF(sc_time memClk, std::map::iterator &lastSelectedThread) +bool SMS::selectSJF(sc_time memClk) { // find threads with non-empty ready batch std::vector threadsWithNonEmptyReadybatches; @@ -93,14 +93,14 @@ bool SMS::selectSJF(sc_time memClk, std::map::iterator &las Thread minThread = threadsWithNonEmptyReadybatches.front(); for (auto& thread : threadsWithNonEmptyReadybatches) { - if (inFlightMemRequestCounter[thread] <= inFlightMemRequestCounter[minThread]) + if (inFlightMemRequestCounter[thread] < inFlightMemRequestCounter[minThread]) { minThread = thread; } } // save selected thread - lastSelectedThread = readybatches.find(Thread(minThread)); + lastSelectedThread = readybatches.find(minThread); debugManager.printDebugMessage(name(), "[SJF] Select ready batch of thread " + to_string(minThread.ID())); @@ -131,14 +131,27 @@ bool SMS::selectSJF(sc_time memClk, std::map::iterator &las } -bool SMS::selectRR(sc_time memClk, std::map::iterator &nextSelectedThread) +bool SMS::selectRR(sc_time memClk) { // no request for this channel, the readybatches map is empty then return if (readybatches.empty()) { return false; } - // pick a non-empty ready batch + // pick the next non-empty ready batch + std::map::iterator nextSelectedThread; + if(lastSelectedThread == readybatches.end()) + { + lastSelectedThread = readybatches.begin(); + nextSelectedThread = lastSelectedThread; + } + else + { + nextSelectedThread = lastSelectedThread; + nextSelectedThread++; + if(nextSelectedThread == readybatches.end()) + nextSelectedThread = readybatches.begin(); + } std::map::iterator savedOriginalNextSelectedThread = nextSelectedThread; while ((*nextSelectedThread).second->isEmpty()) { @@ -166,6 +179,9 @@ bool SMS::selectRR(sc_time memClk, std::map::iterator &next } } } + // save last selected thread + lastSelectedThread = nextSelectedThread; + debugManager.printDebugMessage(name(), "[RR] Select ready batch of thread " + to_string((*nextSelectedThread).first.ID())); @@ -188,44 +204,23 @@ bool SMS::selectRR(sc_time memClk, std::map::iterator &next } void SMS::selectRR_SJF(bool isSJF, sc_time memClk) { + // pick correct policy + bool isSucessfulPick; if (isSJF) { // select by Shortest Job First policy - bool success = selectSJF(memClk, selectedThread); - if (!success) - { - wait(newRequest); - } + isSucessfulPick = selectSJF(memClk); } else { // select by Round Robin policy - if (selectedThread == readybatches.end()) - { - // first Round Robin selection - selectedThread = readybatches.begin(); - bool success = selectRR(memClk, selectedThread); - if (!success) - { - wait(newRequest); - } - } - else - { - // subsequent Round Robin selection - // move the select iterator to the next one - selectedThread++; - if (selectedThread == readybatches.end()) - { - selectedThread = readybatches.begin(); - } - bool success = selectRR(memClk, selectedThread); - if (!success) - { - wait(newRequest); - } - } + isSucessfulPick = selectRR(memClk); + } + // otherwise, wait for new request + if (!isSucessfulPick) + { + wait(newRequest); } } diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h index c3727120..64d2ad62 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.h +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h @@ -21,7 +21,7 @@ public: SMS(sc_module_name /*_name*/, ControllerCore &controllerCore, unsigned int SJFprobability) : IScheduler(controllerCore), SJFprobability(SJFprobability), debugManager(DebugManager::getInstance()) { // initialize selected thread iterator - selectedThread = readybatches.end(); + lastSelectedThread = readybatches.end(); SC_THREAD(batchScheduler); } SC_HAS_PROCESS(SMS); @@ -44,14 +44,14 @@ private: std::map> bankbuffer; std::map readybatches; std::map inFlightMemRequestCounter; - std::map::iterator selectedThread; + std::map::iterator lastSelectedThread; unsigned int SJFprobability; DebugManager& debugManager; sc_event newRequest; - bool selectSJF(sc_time memClk, std::map::iterator &select); - bool selectRR(sc_time memClk, std::map::iterator &next); + bool selectSJF(sc_time memClk); + bool selectRR(sc_time memClk); void selectRR_SJF(bool isSJF, sc_time memClk); }; From ea8213da1763269d09d3594b488fc47c4c07a90d Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Thu, 11 May 2017 23:27:47 +0200 Subject: [PATCH 42/59] Add raw MPKC module for calculating MPKC rate --- .../simulator/src/controller/scheduler/MPKC.h | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 DRAMSys/simulator/src/controller/scheduler/MPKC.h diff --git a/DRAMSys/simulator/src/controller/scheduler/MPKC.h b/DRAMSys/simulator/src/controller/scheduler/MPKC.h new file mode 100644 index 00000000..8b7add90 --- /dev/null +++ b/DRAMSys/simulator/src/controller/scheduler/MPKC.h @@ -0,0 +1,55 @@ +/* + * MPKC.h + * + * Created on: May 11, 2017 + * Author: thanhtran + */ + +#ifndef MPKC_H_ +#define MPKC_H_ + +#include "../../../common/Utils.h" + +using namespace std; + +class MPKC: public sc_module +{ + public: + MPKC(sc_module_name /*_name*/, sc_time memClk) : memClk(memClk) + { + lastGeneratedRequests = std::make_pair(0, 0); + SC_THREAD(updateMPKC); + } + SC_HAS_PROCESS(MPKC); + + void updateMPKC() + { + + while(true) + { + mpkc = 1 / (lastGeneratedRequests.second + numClk*memClk -lastGeneratedRequests.first); + wait(memClk); + numClk++; + } + } + + float getMPKC() + { + return mpkc; + } + + void sendNewRequest(sc_time timeOfGeneration) + { + std::swap(lastGeneratedRequests.first, lastGeneratedRequests.second); + lastGeneratedRequests.second = timeOfGeneration; + numClk = 0; + } + + private: + unsigned int numClk = 0; + sc_time memClk; + float mpkc = 0; + std::pair lastGeneratedRequests; +}; + +#endif /* MPKC_H_ */ From 066569c8560278232a76e08d78b752399fc95cd6 Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Mon, 15 May 2017 16:25:26 +0200 Subject: [PATCH 43/59] Adding MPKC & bypass mechanism --- .../src/controller/scheduler/SMS.cpp | 200 ++++++++++++------ .../simulator/src/controller/scheduler/SMS.h | 37 +++- 2 files changed, 159 insertions(+), 78 deletions(-) diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index 0326d5e1..aab6706e 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -7,23 +7,21 @@ void SMS::schedule(gp *payload) { Thread thread = DramExtension::getExtension(payload).getThread(); - buffer[thread].emplace_back(payload); + requestBuffers[thread].emplace_back(payload); if (inFlightMemRequestCounter.find(thread) == inFlightMemRequestCounter.end()) { inFlightMemRequestCounter[thread] = 0; + cacheMisses[thread] = 0; } inFlightMemRequestCounter[thread]++; - - if (readybatches.find(thread) == readybatches.end()) { - readybatches[thread] = new ReadyBatch(); - } + cacheMisses[thread]++; newRequest.notify(SC_ZERO_TIME); } std::pair SMS::getNextRequest(Bank bank) { - if (bankbuffer[bank].empty()) + if (bankBuffers[bank].empty()) { debugManager.printDebugMessage(name(), "Get next request on bank " + to_string(bank.ID()) + " : EMPTY buffer"); @@ -31,19 +29,18 @@ std::pair SMS::getNextRequest(Bank bank) } else { - gp* payload = bankbuffer[bank].front(); + gp* payload = bankBuffers[bank].front(); Command command = IScheduler::getNextCommand(*payload); if (command == Command::Read || command == Command::ReadA || command == Command::Write || command == Command::WriteA) { inFlightMemRequestCounter[DramExtension::getExtension(payload).getThread()]--; - bankbuffer[bank].pop_front(); + bankBuffers[bank].pop_front(); } debugManager.printDebugMessage(name(), "Get next request on bank " + to_string(bank.ID())); return pair(command, payload); } - } void SMS::batchScheduler() @@ -52,11 +49,23 @@ void SMS::batchScheduler() std::default_random_engine generator; std::bernoulli_distribution distribution((double) SJFprobability / 100.0); -// wait(150, SC_NS); // Test Purpose - while (true) { - selectRR_SJF(distribution(generator), memClk); + updateMPKCs(memClk); + if (isRequestBuffersEmpty() && !existReadyBatches()) { + wait(newRequest); + } else { + batchFormation(memClk); + if (existReadyBatches()) { + if (!isSystemLightlyLoaded() && (existLowIntensityThread() || distribution(generator))) { + selectSJF(memClk); + } else { + selectRR(memClk); + } + } else { + wait(memClk); + } + } } } @@ -66,25 +75,11 @@ bool SMS::selectSJF(sc_time memClk) std::vector threadsWithNonEmptyReadybatches; for (auto& readybatch : readybatches) { - if (!readybatch.second->isEmpty()) + if (!readybatch.second.empty()) { // marked as thread with non-empty ready batch threadsWithNonEmptyReadybatches.push_back(readybatch.first); } - else - { - // form ready batch for this thread - Thread thread = readybatch.first; - while (!buffer[thread].empty() && readybatch.second->addTransaction(buffer[thread].front())) - { - buffer[thread].pop_front(); - } - // marked as thread with non-empty ready batch - if (!readybatch.second->isEmpty()) - { - threadsWithNonEmptyReadybatches.push_back(readybatch.first); - } - } } if (!threadsWithNonEmptyReadybatches.empty()) @@ -106,12 +101,12 @@ bool SMS::selectSJF(sc_time memClk) "[SJF] Select ready batch of thread " + to_string(minThread.ID())); // drain to bank buffers - std::deque &requestPtrs = readybatches[minThread]->getTransactions(); + std::deque &requestPtrs = readybatches[minThread]; for (auto payloadPtrIterator = requestPtrs.begin(); payloadPtrIterator != requestPtrs.end(); payloadPtrIterator++) { Bank bank = DramExtension::getExtension(*payloadPtrIterator).getBank(); - bankbuffer[bank].emplace_back(*payloadPtrIterator); + bankBuffers[bank].emplace_back(*payloadPtrIterator); debugManager.printDebugMessage(name(), "[SJF] Drain request in the ready batch of thread " + to_string(minThread.ID()) + " to bankbuffer " + to_string(bank.ID())); @@ -139,7 +134,7 @@ bool SMS::selectRR(sc_time memClk) } // pick the next non-empty ready batch - std::map::iterator nextSelectedThread; + std::map>::iterator nextSelectedThread; if(lastSelectedThread == readybatches.end()) { lastSelectedThread = readybatches.begin(); @@ -152,31 +147,20 @@ bool SMS::selectRR(sc_time memClk) if(nextSelectedThread == readybatches.end()) nextSelectedThread = readybatches.begin(); } - std::map::iterator savedOriginalNextSelectedThread = nextSelectedThread; - while ((*nextSelectedThread).second->isEmpty()) + std::map>::iterator savedOriginalNextSelectedThread = nextSelectedThread; + while ((*nextSelectedThread).second.empty()) { - // form ready batch for this thread - Thread thread = (*nextSelectedThread).first; - while (!buffer[thread].empty() && (*nextSelectedThread).second->addTransaction(buffer[thread].front())) + nextSelectedThread++; + if (nextSelectedThread == readybatches.end()) { - buffer[thread].pop_front(); + nextSelectedThread = readybatches.begin(); } - if ((*nextSelectedThread).second->isEmpty()) + if (nextSelectedThread == savedOriginalNextSelectedThread) { - // cannot form ready batch then move to next thread - nextSelectedThread++; - if (nextSelectedThread == readybatches.end()) - { - nextSelectedThread = readybatches.begin(); - } - - if (nextSelectedThread == savedOriginalNextSelectedThread) - { - // 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; - } + // 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; } } // save last selected thread @@ -186,12 +170,12 @@ bool SMS::selectRR(sc_time memClk) "[RR] Select ready batch of thread " + to_string((*nextSelectedThread).first.ID())); // drain to bank buffers - std::deque &requestPtrs = (*nextSelectedThread).second->getTransactions(); + std::deque &requestPtrs = (*nextSelectedThread).second; for (auto payloadPtrIterator = requestPtrs.begin(); payloadPtrIterator != requestPtrs.end(); payloadPtrIterator++) { Bank bank = DramExtension::getExtension(*payloadPtrIterator).getBank(); - bankbuffer[bank].emplace_back(*payloadPtrIterator); + bankBuffers[bank].emplace_back(*payloadPtrIterator); debugManager.printDebugMessage(name(), "[RR] Drained request in the ready batch of thread " + to_string((*nextSelectedThread).first.ID()) + " to bankbuffer " + to_string(bank.ID())); @@ -203,24 +187,106 @@ bool SMS::selectRR(sc_time memClk) return true; } -void SMS::selectRR_SJF(bool isSJF, sc_time memClk) { - // pick correct policy - bool isSucessfulPick; - if (isSJF) - { - // select by Shortest Job First policy - isSucessfulPick = selectSJF(memClk); +bool SMS::isSystemLightlyLoaded() { + unsigned int totalRequest = 0; + for (auto& bankBuffer : bankBuffers) { + totalRequest += bankBuffer.second.size(); } - else - { - // select by Round Robin policy - isSucessfulPick = selectRR(memClk); + return (totalRequest <= LOW_SYSTEM_LOAD); +} + +bool SMS::existLowIntensityThread() { + for (auto& mpkcPerThread : MPKCs) { + if (mpkcPerThread.second < LOW_MPKC) { + return true; + } + } + return false; +} + +bool SMS::isThresholdAgeExceeded(Thread thread, sc_time memClk, std::deque::iterator begin, std::deque::iterator end) { + // find the oldest request in the thread's batch + sc_time oldestGenerationTime = sc_time_stamp(); + for (auto reqIter = begin; reqIter != end; reqIter++) { + sc_time reqGenerationTime = GenerationExtension::getExtension(*reqIter).TimeOfGeneration(); + if (reqGenerationTime < oldestGenerationTime) { + oldestGenerationTime = reqGenerationTime; + } } - // otherwise, wait for new request - if (!isSucessfulPick) - { - wait(newRequest); + // check threshold age according to the thread's MPKC + sc_time oldestRequestAge = sc_time_stamp() - oldestGenerationTime; + if ((MPKCs[thread] <= MEDIUM_MPKC) && (oldestRequestAge > (MEDIUM_THRESHOLD_AGE * memClk))) { + return true; + } else if ((MPKCs[thread] > MEDIUM_MPKC) && (oldestRequestAge > (HIGH_THRESHOLD_AGE * memClk))) { + return true; + } else { + return false; } } +void SMS::updateMPKCs(sc_time memClk) { + if (sc_time_stamp() % (MPKC_RESET_CYCLE * memClk) <= memClk) { + // reset for every 10k clk cycles + for (auto& mpkc : MPKCs) { + mpkc.second = 0; + } + } else { + // update MPKC for every thread + for (auto& mpkc : MPKCs) { + mpkc.second = (cacheMisses[mpkc.first] * 1000.0 * memClk) / (sc_time_stamp()); + } + } +} + +bool SMS::isExceededReqBufferSize(Thread thread) { + return requestBuffers[thread].size() == REQUEST_BUFFER_SIZE; +} + +void SMS::batchFormation(sc_time memClk) { + for (auto& requestBuffer : requestBuffers) { + if (!requestBuffer.second.empty() && !readybatches[requestBuffer.first].empty()) { + if (MPKCs[requestBuffer.first] < LOW_MPKC || isSystemLightlyLoaded()) { + // bypass requests by forming batch with only one request (threshold age is ZERO) + readybatches[requestBuffer.first].emplace_back(requestBuffer.second.front()); + requestBuffer.second.pop_front(); + } else { + // forming batch with FIFO size & threshold age constraints + auto firstDifferentRowAccessReqIter = requestBuffer.second.begin(); + Row firstRow = DramExtension::getRow(*firstDifferentRowAccessReqIter); + while (firstDifferentRowAccessReqIter != requestBuffer.second.end() && DramExtension::getRow(*firstDifferentRowAccessReqIter) == firstRow) { + firstDifferentRowAccessReqIter++; + } + // deem this batch ready + if ((firstDifferentRowAccessReqIter != requestBuffer.second.end()) + || isExceededReqBufferSize(requestBuffer.first) + || isThresholdAgeExceeded(requestBuffer.first, memClk, requestBuffer.second.begin(), firstDifferentRowAccessReqIter)) { + do { + readybatches[requestBuffer.first].emplace_back(requestBuffer.second.front()); + requestBuffer.second.pop_front(); + } while (requestBuffer.second.begin() != firstDifferentRowAccessReqIter); + } + } + } + } +} + +bool SMS::isRequestBuffersEmpty() { + for (auto& requestBuffer : requestBuffers) { + if (!requestBuffer.second.empty()) { + return false; + } + } + return true; +} + +bool SMS::existReadyBatches() { + for (auto& readybatch : readybatches) { + if (readybatch.second.empty()) { + return true; + } + } + return false; +} + + diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h index 64d2ad62..ee4afd79 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.h +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h @@ -11,7 +11,13 @@ #include "../../common/dramExtension.h" #include "../../common/DebugManager.h" -#define MIN_TOTAL_REQ 16 +#define LOW_SYSTEM_LOAD 16 +#define LOW_MPKC 1 +#define MEDIUM_MPKC 10 +#define MEDIUM_THRESHOLD_AGE 50 +#define HIGH_THRESHOLD_AGE 200 +#define MPKC_RESET_CYCLE 10000 +#define REQUEST_BUFFER_SIZE 10 using namespace std; @@ -28,10 +34,6 @@ public: virtual ~SMS() { - for (auto& thread_readybatch : readybatches) - { - delete thread_readybatch.second; - } } virtual void schedule(gp *payload) override; @@ -40,19 +42,32 @@ public: void batchScheduler(); private: - std::map> buffer; - std::map> bankbuffer; - std::map readybatches; + std::map> requestBuffers; + std::map> bankBuffers; + std::map> readybatches; + std::map inFlightMemRequestCounter; - std::map::iterator lastSelectedThread; + std::map cacheMisses; + std::map MPKCs; unsigned int SJFprobability; - DebugManager& debugManager; + std::map>::iterator lastSelectedThread; sc_event newRequest; + DebugManager& debugManager; + bool selectSJF(sc_time memClk); bool selectRR(sc_time memClk); - void selectRR_SJF(bool isSJF, sc_time memClk); + void batchFormation(sc_time memClk); + + bool existLowIntensityThread(); + bool isSystemLightlyLoaded(); + bool isThresholdAgeExceeded(Thread thread, sc_time memClk, std::deque::iterator begin, std::deque::iterator end); + bool isExceededReqBufferSize(Thread thread); + void updateMPKCs(sc_time memClk); + + bool isRequestBuffersEmpty(); + bool existReadyBatches(); }; #endif // SMS_H From d489db6a46e51b91da262e9c6c7bad40da0b72b5 Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Tue, 16 May 2017 01:35:10 +0200 Subject: [PATCH 44/59] Fix bug --- .../resources/configs/mcconfigs/sms.xml | 1 + .../src/controller/scheduler/SMS.cpp | 21 ++++++++++++------- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/DRAMSys/simulator/resources/configs/mcconfigs/sms.xml b/DRAMSys/simulator/resources/configs/mcconfigs/sms.xml index 19490a2c..84551d57 100644 --- a/DRAMSys/simulator/resources/configs/mcconfigs/sms.xml +++ b/DRAMSys/simulator/resources/configs/mcconfigs/sms.xml @@ -14,4 +14,5 @@ + \ No newline at end of file diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index aab6706e..24022e1c 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -6,6 +6,7 @@ using namespace std; void SMS::schedule(gp *payload) { Thread thread = DramExtension::getExtension(payload).getThread(); + bool wasEmpty = isRequestBuffersEmpty(); requestBuffers[thread].emplace_back(payload); @@ -16,7 +17,9 @@ void SMS::schedule(gp *payload) inFlightMemRequestCounter[thread]++; cacheMisses[thread]++; - newRequest.notify(SC_ZERO_TIME); + if (wasEmpty) { + newRequest.notify(SC_ZERO_TIME); + } } std::pair SMS::getNextRequest(Bank bank) @@ -228,14 +231,16 @@ bool SMS::isThresholdAgeExceeded(Thread thread, sc_time memClk, std::deque: void SMS::updateMPKCs(sc_time memClk) { if (sc_time_stamp() % (MPKC_RESET_CYCLE * memClk) <= memClk) { // reset for every 10k clk cycles - for (auto& mpkc : MPKCs) { - mpkc.second = 0; + for (auto& cacheMiss : cacheMisses) { + MPKCs[cacheMiss.first] = 0; } + debugManager.printDebugMessage(name(), "Reset MKKCs"); } else { // update MPKC for every thread - for (auto& mpkc : MPKCs) { - mpkc.second = (cacheMisses[mpkc.first] * 1000.0 * memClk) / (sc_time_stamp()); + for (auto& cacheMiss : cacheMisses) { + MPKCs[cacheMiss.first] = (cacheMiss.second * 1000.0 * memClk) / (sc_time_stamp()); } + debugManager.printDebugMessage(name(), "Update MPKCs"); } } @@ -245,11 +250,12 @@ bool SMS::isExceededReqBufferSize(Thread thread) { void SMS::batchFormation(sc_time memClk) { for (auto& requestBuffer : requestBuffers) { - if (!requestBuffer.second.empty() && !readybatches[requestBuffer.first].empty()) { + if (!requestBuffer.second.empty() && readybatches[requestBuffer.first].empty()) { if (MPKCs[requestBuffer.first] < LOW_MPKC || isSystemLightlyLoaded()) { // bypass requests by forming batch with only one request (threshold age is ZERO) readybatches[requestBuffer.first].emplace_back(requestBuffer.second.front()); requestBuffer.second.pop_front(); + debugManager.printDebugMessage(name(), "Bypass requests by forming batch of thread " + to_string(requestBuffer.first.ID())); } else { // forming batch with FIFO size & threshold age constraints auto firstDifferentRowAccessReqIter = requestBuffer.second.begin(); @@ -265,6 +271,7 @@ void SMS::batchFormation(sc_time memClk) { readybatches[requestBuffer.first].emplace_back(requestBuffer.second.front()); requestBuffer.second.pop_front(); } while (requestBuffer.second.begin() != firstDifferentRowAccessReqIter); + debugManager.printDebugMessage(name(), "Deem batch ready - thread " + to_string(requestBuffer.first.ID())); } } } @@ -282,7 +289,7 @@ bool SMS::isRequestBuffersEmpty() { bool SMS::existReadyBatches() { for (auto& readybatch : readybatches) { - if (readybatch.second.empty()) { + if (!readybatch.second.empty()) { return true; } } From dab223757258de670c8b41b829ff546c064a3fd5 Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Tue, 16 May 2017 01:38:53 +0200 Subject: [PATCH 45/59] First try to form multiple ready batches --- .../src/controller/scheduler/SMS.cpp | 194 +++++++++++++++++- .../simulator/src/controller/scheduler/SMS.h | 9 +- 2 files changed, 198 insertions(+), 5 deletions(-) diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index 24022e1c..ba1d2199 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -72,6 +72,48 @@ void SMS::batchScheduler() } } +/** + * Pick a Thread according to Shortest-Job Policy + * Save the picked one into lastSelectedThread + * @return true if it can, otherwise false + */ +bool SMS::pickSJF() +{ + // find threads with non-empty request buffers + std::vector threadsWithNonEmptyRequestBuffer; + for (auto& requestBuffer : requestBuffers) + { + if (!requestBuffer.second.empty()) + { + // marked as thread with non-empty request buffer + threadsWithNonEmptyRequestBuffer.push_back(requestBuffer.first); + } + } + + if (!threadsWithNonEmptyRequestBuffer.empty()) + { + // pick shortest-job thread among threads with non-empty request buffer + Thread minThread = threadsWithNonEmptyRequestBuffer.front(); + for (auto& thread : threadsWithNonEmptyRequestBuffer) + { + if (inFlightMemRequestCounter[thread] < inFlightMemRequestCounter[minThread]) + { + minThread = thread; + } + } + + // save selected thread + lastSelectedThread = readybatches.find(minThread); + debugManager.printDebugMessage(name(), + "[SJF] Select ready batch of thread " + to_string(minThread.ID())); + return true; + } + else + { + return false; + } +} + bool SMS::selectSJF(sc_time memClk) { // find threads with non-empty ready batch @@ -126,7 +168,78 @@ bool SMS::selectSJF(sc_time memClk) // this mean the request buffers are totally empty return false; } +} +/** + * Drain the picked request buffer into bank buffers + * by move request one-by-one from start of the request buffer till last parameter + * @param memClk + * @param last + */ +void SMS::drain(sc_time memClk, std::deque::iterator last) +{ + unsigned int batchSize = std::distance((*lastSelectedThread).second.begin(), last) + 1; + for (unsigned int i = 1; i <= batchSize; i++) + { + Bank bank = DramExtension::getExtension(*((*lastSelectedThread).second.begin())).getBank(); + // if(bankBuffers[bank].size() == Configuration::getInstance().BankBufferSize) + // { + // wait(bankBufferIsNotFull); + // } + wait(memClk); + bankBuffers[bank].emplace_back(*((*lastSelectedThread).second.begin())); + (*lastSelectedThread).second.pop_front(); + + debugManager.printDebugMessage(name(), + "[SJF] Drain request in the ready batch of thread " + + to_string((*lastSelectedThread).first.ID()) + " to bankbuffer " + + to_string(bank.ID())); + } +} + +/** + * Pick a Thread according to Round-Robin Policy + * Save the picked one into lastSelectedThread + * @return true if it can pick one, otherwise false + */ +bool SMS::pickRR() +{ + std::map>::iterator nextSelectedThread; + if (lastSelectedThread == requestBuffers.end()) + { + lastSelectedThread = requestBuffers.begin(); + nextSelectedThread = lastSelectedThread; + } + else + { + nextSelectedThread = lastSelectedThread; + nextSelectedThread++; + if (nextSelectedThread == requestBuffers.end()) + nextSelectedThread = requestBuffers.begin(); + } + + std::map>::iterator savedOriginalNextSelectedThread = nextSelectedThread; + + while ((*nextSelectedThread).second.empty()) + { + nextSelectedThread++; + if (nextSelectedThread == requestBuffers.end()) + { + nextSelectedThread = requestBuffers.begin(); + } + + if (nextSelectedThread == savedOriginalNextSelectedThread) + { + // 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; + } + } + // save last selected thread + lastSelectedThread = nextSelectedThread; + debugManager.printDebugMessage(name(), + "[RR] Select ready batch of thread " + to_string((*nextSelectedThread).first.ID())); + return true; } bool SMS::selectRR(sc_time memClk) @@ -138,7 +251,7 @@ bool SMS::selectRR(sc_time memClk) // pick the next non-empty ready batch std::map>::iterator nextSelectedThread; - if(lastSelectedThread == readybatches.end()) + if (lastSelectedThread == readybatches.end()) { lastSelectedThread = readybatches.begin(); nextSelectedThread = lastSelectedThread; @@ -147,7 +260,7 @@ bool SMS::selectRR(sc_time memClk) { nextSelectedThread = lastSelectedThread; nextSelectedThread++; - if(nextSelectedThread == readybatches.end()) + if (nextSelectedThread == readybatches.end()) nextSelectedThread = readybatches.begin(); } std::map>::iterator savedOriginalNextSelectedThread = nextSelectedThread; @@ -232,7 +345,7 @@ void SMS::updateMPKCs(sc_time memClk) { if (sc_time_stamp() % (MPKC_RESET_CYCLE * memClk) <= memClk) { // reset for every 10k clk cycles for (auto& cacheMiss : cacheMisses) { - MPKCs[cacheMiss.first] = 0; + MPKCs[cacheMiss.first] = 0; } debugManager.printDebugMessage(name(), "Reset MKKCs"); } else { @@ -265,7 +378,7 @@ void SMS::batchFormation(sc_time memClk) { } // deem this batch ready if ((firstDifferentRowAccessReqIter != requestBuffer.second.end()) - || isExceededReqBufferSize(requestBuffer.first) + || isExceededReqBufferSize(requestBuffer.first) || isThresholdAgeExceeded(requestBuffer.first, memClk, requestBuffer.second.begin(), firstDifferentRowAccessReqIter)) { do { readybatches[requestBuffer.first].emplace_back(requestBuffer.second.front()); @@ -296,4 +409,77 @@ bool SMS::existReadyBatches() { return false; } +/** + * Form batch from begin iterator parameter of a request buffer + * If this batch is deemed ready, save the iterator pointing to its last element + * @param memClk + * @param begin + * @return true if this batch is ready, otherwise false + */ +bool SMS::batchFormation(sc_time memClk, std::pair> &requestBuffer, + std::deque::iterator beginIter) +{ + if (requestBuffer.second.empty()) + { + return false; + } + if (requestBuffer.second.end() == beginIter) + { + return false; + } + + if (MPKCs[requestBuffer.first] < LOW_MPKC || isSystemLightlyLoaded()) + { + // bypass requests by forming batch with only one request (threshold age is ZERO) + readyBatchesIter[requestBuffer.first].push_back(beginIter); + return true; + } + else + { + // forming batch with FIFO size & threshold age constraints + auto firstDifferentRowAccessReqIter = beginIter; + Row firstRow = DramExtension::getRow(*beginIter); + while (firstDifferentRowAccessReqIter != requestBuffer.second.end() + && DramExtension::getRow(*firstDifferentRowAccessReqIter) == firstRow) + { + firstDifferentRowAccessReqIter++; + } + + // deem this batch ready + if ((firstDifferentRowAccessReqIter != requestBuffer.second.end()) + || isExceededReqBufferSize(requestBuffer.first) + || isThresholdAgeExceeded(requestBuffer.first, memClk, beginIter, + firstDifferentRowAccessReqIter)) + { + firstDifferentRowAccessReqIter--; + readyBatchesIter[requestBuffer.first].push_back(firstDifferentRowAccessReqIter); + debugManager.printDebugMessage(name(), + "Deem batch ready - thread " + to_string(requestBuffer.first.ID())); + return true; + } + else + { + return false; + } + } +} + +void SMS::multiBatchFormation(sc_time memClk) +{ + for (auto& requestBuffer : requestBuffers) + { + bool formed; + do + { + if (readyBatchesIter[requestBuffer.first].empty()) + { + formed = batchFormation(memClk, (std::pair>&)requestBuffer, requestBuffer.second.begin()); + } + else + { + formed = batchFormation(memClk, (std::pair>&)requestBuffer, readyBatchesIter[requestBuffer.first].back() + 1); + } + } while (formed); + } +} diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h index ee4afd79..6e4297ba 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.h +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h @@ -27,7 +27,8 @@ public: SMS(sc_module_name /*_name*/, ControllerCore &controllerCore, unsigned int SJFprobability) : IScheduler(controllerCore), SJFprobability(SJFprobability), debugManager(DebugManager::getInstance()) { // initialize selected thread iterator - lastSelectedThread = readybatches.end(); + lastSelectedThread = readybatches.end(); +// lastSelectedThread = requestBuffers.end(); SC_THREAD(batchScheduler); } SC_HAS_PROCESS(SMS); @@ -45,6 +46,7 @@ private: std::map> requestBuffers; std::map> bankBuffers; std::map> readybatches; + std::map::iterator>> readyBatchesIter; std::map inFlightMemRequestCounter; std::map cacheMisses; @@ -59,6 +61,11 @@ private: bool selectSJF(sc_time memClk); bool selectRR(sc_time memClk); void batchFormation(sc_time memClk); + bool batchFormation(sc_time memClk, std::pair> &requestBuffer, std::deque::iterator beginIter); + void multiBatchFormation(sc_time memClk); + bool pickSJF(); + bool pickRR(); + void drain(sc_time memClk, std::deque::iterator last); bool existLowIntensityThread(); bool isSystemLightlyLoaded(); From 6d739c64f1d38f86548840da235a03d2c454ff60 Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Tue, 16 May 2017 02:03:10 +0200 Subject: [PATCH 46/59] Finish multiple ready batch formation --- .../src/controller/scheduler/SMS.cpp | 35 ++++++++++++++----- .../simulator/src/controller/scheduler/SMS.h | 4 +-- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index ba1d2199..14d63207 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -54,19 +54,36 @@ void SMS::batchScheduler() while (true) { +// updateMPKCs(memClk); +// if (isRequestBuffersEmpty() && !existReadyBatches()) { +// wait(newRequest); +// } else { +// batchFormation(memClk); +// if (existReadyBatches()) { +// if (!isSystemLightlyLoaded() && (existLowIntensityThread() || distribution(generator))) { +// selectSJF(memClk); +// } else { +// selectRR(memClk); +// } +// } else { +// wait(memClk); +// } +// } updateMPKCs(memClk); - if (isRequestBuffersEmpty() && !existReadyBatches()) { - wait(newRequest); + if (isRequestBuffersEmpty()) { + wait(newRequest); } else { - batchFormation(memClk); - if (existReadyBatches()) { - if (!isSystemLightlyLoaded() && (existLowIntensityThread() || distribution(generator))) { - selectSJF(memClk); - } else { - selectRR(memClk); + multiBatchFormation(memClk); + if (!isSystemLightlyLoaded() && (existLowIntensityThread() || distribution(generator))) { + if (pickSJF()) { + drain(memClk, readyBatchesIter[(*lastSelectedThread).first].front()); + readyBatchesIter[(*lastSelectedThread).first].pop_front(); } } else { - wait(memClk); + if (pickRR()) { + drain(memClk, readyBatchesIter[(*lastSelectedThread).first].front()); + readyBatchesIter[(*lastSelectedThread).first].pop_front(); + } } } } diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h index 6e4297ba..c786fbcc 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.h +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h @@ -27,8 +27,8 @@ public: SMS(sc_module_name /*_name*/, ControllerCore &controllerCore, unsigned int SJFprobability) : IScheduler(controllerCore), SJFprobability(SJFprobability), debugManager(DebugManager::getInstance()) { // initialize selected thread iterator - lastSelectedThread = readybatches.end(); -// lastSelectedThread = requestBuffers.end(); +// lastSelectedThread = readybatches.end(); + lastSelectedThread = requestBuffers.end(); SC_THREAD(batchScheduler); } SC_HAS_PROCESS(SMS); From ab2b87aaeb65e89f78f68581fce47f7a6f690203 Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Thu, 1 Jun 2017 02:24:05 +0200 Subject: [PATCH 47/59] Fix bug 1. Trying to drain request from empty request buffers & empty ready batch iterators 2. lastSelectedThread Iterator pointing to readybatchIters instead --- .../resources/simulations/sms-example.xml | 4 + .../src/controller/scheduler/SMS.cpp | 237 +++--------------- .../simulator/src/controller/scheduler/SMS.h | 12 +- 3 files changed, 48 insertions(+), 205 deletions(-) diff --git a/DRAMSys/simulator/resources/simulations/sms-example.xml b/DRAMSys/simulator/resources/simulations/sms-example.xml index d1a2f734..d40e0e8c 100644 --- a/DRAMSys/simulator/resources/simulations/sms-example.xml +++ b/DRAMSys/simulator/resources/simulations/sms-example.xml @@ -12,10 +12,14 @@ + ddr3_example.stl sms_t1.stl sms_t2.stl sms_t3.stl sms_t4.stl + stream.stl + random.stl + chstone-adpcm_32.stl diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index 14d63207..d4336415 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -54,36 +54,25 @@ void SMS::batchScheduler() while (true) { -// updateMPKCs(memClk); -// if (isRequestBuffersEmpty() && !existReadyBatches()) { -// wait(newRequest); -// } else { -// batchFormation(memClk); -// if (existReadyBatches()) { -// if (!isSystemLightlyLoaded() && (existLowIntensityThread() || distribution(generator))) { -// selectSJF(memClk); -// } else { -// selectRR(memClk); -// } -// } else { -// wait(memClk); -// } -// } updateMPKCs(memClk); if (isRequestBuffersEmpty()) { wait(newRequest); } else { multiBatchFormation(memClk); - if (!isSystemLightlyLoaded() && (existLowIntensityThread() || distribution(generator))) { - if (pickSJF()) { - drain(memClk, readyBatchesIter[(*lastSelectedThread).first].front()); - readyBatchesIter[(*lastSelectedThread).first].pop_front(); + if (existReadyBatches()) { + if (!isSystemLightlyLoaded() && (existLowIntensityThread() || distribution(generator))) { + if (pickSJF()) { + drain(memClk, (*lastSelectedThread).second.front()); + (*lastSelectedThread).second.pop_front(); + } + } else { + if (pickRR()) { + drain(memClk, (*lastSelectedThread).second.front()); + (*lastSelectedThread).second.pop_front(); + } } } else { - if (pickRR()) { - drain(memClk, readyBatchesIter[(*lastSelectedThread).first].front()); - readyBatchesIter[(*lastSelectedThread).first].pop_front(); - } + wait(memClk); } } } @@ -96,22 +85,22 @@ void SMS::batchScheduler() */ bool SMS::pickSJF() { - // find threads with non-empty request buffers - std::vector threadsWithNonEmptyRequestBuffer; - for (auto& requestBuffer : requestBuffers) + // find threads with ready batches + std::vector threadsWithReadyBatches; + for (auto& each : readyBatchIters) { - if (!requestBuffer.second.empty()) + if (!each.second.empty()) { // marked as thread with non-empty request buffer - threadsWithNonEmptyRequestBuffer.push_back(requestBuffer.first); + threadsWithReadyBatches.push_back(each.first); } } - if (!threadsWithNonEmptyRequestBuffer.empty()) + if (!threadsWithReadyBatches.empty()) { // pick shortest-job thread among threads with non-empty request buffer - Thread minThread = threadsWithNonEmptyRequestBuffer.front(); - for (auto& thread : threadsWithNonEmptyRequestBuffer) + Thread minThread = threadsWithReadyBatches.front(); + for (auto& thread : threadsWithReadyBatches) { if (inFlightMemRequestCounter[thread] < inFlightMemRequestCounter[minThread]) { @@ -120,7 +109,7 @@ bool SMS::pickSJF() } // save selected thread - lastSelectedThread = readybatches.find(minThread); + lastSelectedThread = readyBatchIters.find(minThread); debugManager.printDebugMessage(name(), "[SJF] Select ready batch of thread " + to_string(minThread.ID())); return true; @@ -131,62 +120,6 @@ bool SMS::pickSJF() } } -bool SMS::selectSJF(sc_time memClk) -{ - // find threads with non-empty ready batch - std::vector threadsWithNonEmptyReadybatches; - for (auto& readybatch : readybatches) - { - if (!readybatch.second.empty()) - { - // marked as thread with non-empty ready batch - threadsWithNonEmptyReadybatches.push_back(readybatch.first); - } - } - - if (!threadsWithNonEmptyReadybatches.empty()) - { - // pick shortest-job thread among threads with non-empty ready batch - Thread minThread = threadsWithNonEmptyReadybatches.front(); - for (auto& thread : threadsWithNonEmptyReadybatches) - { - if (inFlightMemRequestCounter[thread] < inFlightMemRequestCounter[minThread]) - { - minThread = thread; - } - } - - // save selected thread - lastSelectedThread = readybatches.find(minThread); - - debugManager.printDebugMessage(name(), - "[SJF] Select ready batch of thread " + to_string(minThread.ID())); - - // drain to bank buffers - std::deque &requestPtrs = readybatches[minThread]; - for (auto payloadPtrIterator = requestPtrs.begin(); payloadPtrIterator != requestPtrs.end(); - payloadPtrIterator++) - { - Bank bank = DramExtension::getExtension(*payloadPtrIterator).getBank(); - bankBuffers[bank].emplace_back(*payloadPtrIterator); - debugManager.printDebugMessage(name(), - "[SJF] Drain request in the ready batch of thread " + to_string(minThread.ID()) - + " to bankbuffer " + to_string(bank.ID())); - wait(memClk); - } - requestPtrs.clear(); - - // a ready batch has been picked up & drained - return true; - } - else - { - // non-existed ready batch to be picked up & drained - // this mean the request buffers are totally empty - return false; - } -} - /** * Drain the picked request buffer into bank buffers * by move request one-by-one from start of the request buffer till last parameter @@ -195,17 +128,18 @@ bool SMS::selectSJF(sc_time memClk) */ void SMS::drain(sc_time memClk, std::deque::iterator last) { - unsigned int batchSize = std::distance((*lastSelectedThread).second.begin(), last) + 1; + Thread selectedThread = (*lastSelectedThread).first; + unsigned int batchSize = std::distance(requestBuffers[selectedThread].begin(), last) + 1; for (unsigned int i = 1; i <= batchSize; i++) { - Bank bank = DramExtension::getExtension(*((*lastSelectedThread).second.begin())).getBank(); + Bank bank = DramExtension::getExtension(requestBuffers[selectedThread].front()).getBank(); // if(bankBuffers[bank].size() == Configuration::getInstance().BankBufferSize) // { // wait(bankBufferIsNotFull); // } wait(memClk); - bankBuffers[bank].emplace_back(*((*lastSelectedThread).second.begin())); - (*lastSelectedThread).second.pop_front(); + bankBuffers[bank].emplace_back(requestBuffers[selectedThread].front()); + requestBuffers[selectedThread].pop_front(); debugManager.printDebugMessage(name(), "[SJF] Drain request in the ready batch of thread " @@ -221,28 +155,28 @@ void SMS::drain(sc_time memClk, std::deque::iterator last) */ bool SMS::pickRR() { - std::map>::iterator nextSelectedThread; - if (lastSelectedThread == requestBuffers.end()) + std::map>::iterator nextSelectedThread; + if (lastSelectedThread == readyBatchIters.end()) { - lastSelectedThread = requestBuffers.begin(); + lastSelectedThread = readyBatchIters.begin(); nextSelectedThread = lastSelectedThread; } else { nextSelectedThread = lastSelectedThread; nextSelectedThread++; - if (nextSelectedThread == requestBuffers.end()) - nextSelectedThread = requestBuffers.begin(); + if (nextSelectedThread == readyBatchIters.end()) + nextSelectedThread = readyBatchIters.begin(); } - std::map>::iterator savedOriginalNextSelectedThread = nextSelectedThread; + std::map>::iterator savedOriginalNextSelectedThread = nextSelectedThread; while ((*nextSelectedThread).second.empty()) { nextSelectedThread++; - if (nextSelectedThread == requestBuffers.end()) + if (nextSelectedThread == readyBatchIters.end()) { - nextSelectedThread = requestBuffers.begin(); + nextSelectedThread = readyBatchIters.begin(); } if (nextSelectedThread == savedOriginalNextSelectedThread) @@ -259,67 +193,6 @@ bool SMS::pickRR() return true; } -bool SMS::selectRR(sc_time memClk) -{ - // no request for this channel, the readybatches map is empty then return - if (readybatches.empty()) { - return false; - } - - // pick the next non-empty ready batch - std::map>::iterator nextSelectedThread; - if (lastSelectedThread == readybatches.end()) - { - lastSelectedThread = readybatches.begin(); - nextSelectedThread = lastSelectedThread; - } - else - { - nextSelectedThread = lastSelectedThread; - nextSelectedThread++; - if (nextSelectedThread == readybatches.end()) - nextSelectedThread = readybatches.begin(); - } - std::map>::iterator savedOriginalNextSelectedThread = nextSelectedThread; - while ((*nextSelectedThread).second.empty()) - { - nextSelectedThread++; - if (nextSelectedThread == readybatches.end()) - { - nextSelectedThread = readybatches.begin(); - } - - if (nextSelectedThread == savedOriginalNextSelectedThread) - { - // 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; - } - } - // save last selected thread - lastSelectedThread = nextSelectedThread; - - debugManager.printDebugMessage(name(), - "[RR] Select ready batch of thread " + to_string((*nextSelectedThread).first.ID())); - - // drain to bank buffers - std::deque &requestPtrs = (*nextSelectedThread).second; - for (auto payloadPtrIterator = requestPtrs.begin(); payloadPtrIterator != requestPtrs.end(); - payloadPtrIterator++) - { - Bank bank = DramExtension::getExtension(*payloadPtrIterator).getBank(); - bankBuffers[bank].emplace_back(*payloadPtrIterator); - debugManager.printDebugMessage(name(), - "[RR] Drained request in the ready batch of thread " + to_string((*nextSelectedThread).first.ID()) - + " to bankbuffer " + to_string(bank.ID())); - wait(memClk); - } - requestPtrs.clear(); - - // a ready batch has been picked up & drained - return true; -} - bool SMS::isSystemLightlyLoaded() { unsigned int totalRequest = 0; for (auto& bankBuffer : bankBuffers) { @@ -378,36 +251,6 @@ bool SMS::isExceededReqBufferSize(Thread thread) { return requestBuffers[thread].size() == REQUEST_BUFFER_SIZE; } -void SMS::batchFormation(sc_time memClk) { - for (auto& requestBuffer : requestBuffers) { - if (!requestBuffer.second.empty() && readybatches[requestBuffer.first].empty()) { - if (MPKCs[requestBuffer.first] < LOW_MPKC || isSystemLightlyLoaded()) { - // bypass requests by forming batch with only one request (threshold age is ZERO) - readybatches[requestBuffer.first].emplace_back(requestBuffer.second.front()); - requestBuffer.second.pop_front(); - debugManager.printDebugMessage(name(), "Bypass requests by forming batch of thread " + to_string(requestBuffer.first.ID())); - } else { - // forming batch with FIFO size & threshold age constraints - auto firstDifferentRowAccessReqIter = requestBuffer.second.begin(); - Row firstRow = DramExtension::getRow(*firstDifferentRowAccessReqIter); - while (firstDifferentRowAccessReqIter != requestBuffer.second.end() && DramExtension::getRow(*firstDifferentRowAccessReqIter) == firstRow) { - firstDifferentRowAccessReqIter++; - } - // deem this batch ready - if ((firstDifferentRowAccessReqIter != requestBuffer.second.end()) - || isExceededReqBufferSize(requestBuffer.first) - || isThresholdAgeExceeded(requestBuffer.first, memClk, requestBuffer.second.begin(), firstDifferentRowAccessReqIter)) { - do { - readybatches[requestBuffer.first].emplace_back(requestBuffer.second.front()); - requestBuffer.second.pop_front(); - } while (requestBuffer.second.begin() != firstDifferentRowAccessReqIter); - debugManager.printDebugMessage(name(), "Deem batch ready - thread " + to_string(requestBuffer.first.ID())); - } - } - } - } -} - bool SMS::isRequestBuffersEmpty() { for (auto& requestBuffer : requestBuffers) { if (!requestBuffer.second.empty()) { @@ -418,8 +261,8 @@ bool SMS::isRequestBuffersEmpty() { } bool SMS::existReadyBatches() { - for (auto& readybatch : readybatches) { - if (!readybatch.second.empty()) { + for (auto& each : readyBatchIters) { + if (!each.second.empty()) { return true; } } @@ -449,7 +292,7 @@ bool SMS::batchFormation(sc_time memClk, std::pair> &req if (MPKCs[requestBuffer.first] < LOW_MPKC || isSystemLightlyLoaded()) { // bypass requests by forming batch with only one request (threshold age is ZERO) - readyBatchesIter[requestBuffer.first].push_back(beginIter); + readyBatchIters[requestBuffer.first].push_back(beginIter); return true; } else @@ -470,7 +313,7 @@ bool SMS::batchFormation(sc_time memClk, std::pair> &req firstDifferentRowAccessReqIter)) { firstDifferentRowAccessReqIter--; - readyBatchesIter[requestBuffer.first].push_back(firstDifferentRowAccessReqIter); + readyBatchIters[requestBuffer.first].push_back(firstDifferentRowAccessReqIter); debugManager.printDebugMessage(name(), "Deem batch ready - thread " + to_string(requestBuffer.first.ID())); return true; @@ -489,13 +332,13 @@ void SMS::multiBatchFormation(sc_time memClk) bool formed; do { - if (readyBatchesIter[requestBuffer.first].empty()) + if (readyBatchIters[requestBuffer.first].empty()) { formed = batchFormation(memClk, (std::pair>&)requestBuffer, requestBuffer.second.begin()); } else { - formed = batchFormation(memClk, (std::pair>&)requestBuffer, readyBatchesIter[requestBuffer.first].back() + 1); + formed = batchFormation(memClk, (std::pair>&)requestBuffer, readyBatchIters[requestBuffer.first].back() + 1); } } while (formed); } diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h index c786fbcc..df9c132f 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.h +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h @@ -20,6 +20,7 @@ #define REQUEST_BUFFER_SIZE 10 using namespace std; +typedef std::deque::iterator gp_deque_iterator; class SMS: public sc_module, public IScheduler { @@ -27,8 +28,7 @@ public: SMS(sc_module_name /*_name*/, ControllerCore &controllerCore, unsigned int SJFprobability) : IScheduler(controllerCore), SJFprobability(SJFprobability), debugManager(DebugManager::getInstance()) { // initialize selected thread iterator -// lastSelectedThread = readybatches.end(); - lastSelectedThread = requestBuffers.end(); + lastSelectedThread = readyBatchIters.end(); SC_THREAD(batchScheduler); } SC_HAS_PROCESS(SMS); @@ -45,22 +45,18 @@ public: private: std::map> requestBuffers; std::map> bankBuffers; - std::map> readybatches; - std::map::iterator>> readyBatchesIter; + std::map> readyBatchIters; std::map inFlightMemRequestCounter; std::map cacheMisses; std::map MPKCs; unsigned int SJFprobability; - std::map>::iterator lastSelectedThread; + std::map>::iterator lastSelectedThread; sc_event newRequest; DebugManager& debugManager; - bool selectSJF(sc_time memClk); - bool selectRR(sc_time memClk); - void batchFormation(sc_time memClk); bool batchFormation(sc_time memClk, std::pair> &requestBuffer, std::deque::iterator beginIter); void multiBatchFormation(sc_time memClk); bool pickSJF(); From 778834f15c534c5360e4fa1c423c3b7c189bcfb8 Mon Sep 17 00:00:00 2001 From: Johannes Feldmann Date: Fri, 2 Jun 2017 17:19:19 +0200 Subject: [PATCH 48/59] Removed deprecated files --- .../resources/simulations/sim-batch.xml | 52 --- .../src/simulation/SimulationManager.cpp | 310 ------------------ 2 files changed, 362 deletions(-) delete mode 100644 DRAMSys/simulator/resources/simulations/sim-batch.xml delete mode 100644 DRAMSys/simulator/src/simulation/SimulationManager.cpp diff --git a/DRAMSys/simulator/resources/simulations/sim-batch.xml b/DRAMSys/simulator/resources/simulations/sim-batch.xml deleted file mode 100644 index 0752914c..00000000 --- a/DRAMSys/simulator/resources/simulations/sim-batch.xml +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - chstone-adpcm_32.stl - - - - - diff --git a/DRAMSys/simulator/src/simulation/SimulationManager.cpp b/DRAMSys/simulator/src/simulation/SimulationManager.cpp deleted file mode 100644 index a3494667..00000000 --- a/DRAMSys/simulator/src/simulation/SimulationManager.cpp +++ /dev/null @@ -1,310 +0,0 @@ -/* - * Copyright (c) 2015, University of Kaiserslautern - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: - * Janik Schlemminger - * Matthias Jung - * Eder F. Zulian - */ - -#include -#include - -#include "SimulationManager.h" -#include "../common/Utils.h" - -using namespace std; -using namespace tinyxml2; - -SimulationManager::SimulationManager(string resources) : resources(resources) -{ -} - -SimulationManager::~SimulationManager() -{ - for (auto player : players) { - delete player; - } -#if USE_EXAMPLE_INITIATOR - delete init; - delete exampleInitiatorTlmChecker; -#endif - - for (auto tlmChecker : playersTlmCheckers) { - delete tlmChecker; - } -} - -void SimulationManager::loadSimulationsFromXML(string uri) -{ - cout << "\n\nload simulation-batch:" << endl; - cout << headline << endl; - - exportPath = getFileName(uri); - loadXML(uri, simulationdoc); - - cout << "\t-> parsing simulation objects .." << endl; - - XMLElement* simulation = simulationdoc.FirstChildElement("simulation"); - string xmlNodeName(simulation->Name()); - if( xmlNodeName != "simulation") - reportFatal("SimulationManager", "simulation node expected"); - parseSimulationBatch(simulation); - - cout << "\t-> simulation batches loaded successfully!\n" << endl; - - for (auto batch : simulationBatches) - { - batch.print(); - } -} - -void SimulationManager::runSimulations() -{ - for (auto& batch : simulationBatches) - { - boost::filesystem::path dir(exportPath); - boost::filesystem::create_directories(dir); - - for (auto& dramSetup : batch.dramSetups) - { - for (auto& traceSetup : batch.traceSetups) - { - string exportname = exportPath + "/" + traceSetup.first; - instantiateModules(exportname, dramSetup, traceSetup.second); - bindSockets(); - runSimulation(exportname); - } - } - } -} - -void SimulationManager::parseSimulationBatch(XMLElement* simulation) -{ - SimulationBatch batch; - - XMLElement* simconfig = simulation->FirstChildElement("simconfig"); - - XMLElement *thermalsimconfig = simulation->FirstChildElement("thermalsimconfig"); - - XMLElement* memspecs = simulation->FirstChildElement("memspecs"); - if(memspecs == NULL) memspecs = simulation; - - XMLElement* addressmappings = simulation->FirstChildElement("addressmappings"); - if(addressmappings == NULL) addressmappings = simulation; - - XMLElement* mcconfigs = simulation->FirstChildElement("mcconfigs"); - if(mcconfigs == NULL) mcconfigs = simulation; - - for (XMLElement* memspec = memspecs->FirstChildElement("memspec"); memspec != NULL; - memspec = memspec->NextSiblingElement("memspec")) - { - - for (XMLElement* addressmapping = addressmappings->FirstChildElement("addressmapping"); addressmapping != NULL; - addressmapping = addressmapping->NextSiblingElement("addressmapping")) - { - - for (XMLElement* mcconfig = mcconfigs->FirstChildElement("mcconfig"); - mcconfig != NULL; mcconfig = mcconfig->NextSiblingElement("mcconfig")) - { - batch.dramSetups.push_back(DramSetup(memspec, mcconfig, simconfig, addressmapping, thermalsimconfig)); - } - } - } - - addTraceSetups(batch, simulation); - - simulationBatches.push_back(batch); -} - -void SimulationManager::instantiateModules(string traceName, DramSetup dramSetup, vector traceSetup) -{ - - simulation = new Simulation("sim", resources, traceName, dramSetup, traceSetup); - -#if USE_EXAMPLE_INITIATOR - init = new ExampleInitiator("init"); - if(Configuration::getInstance().CheckTLM2Protocol) { - string str = "ExampleInitiatorTLMChecker"; - exampleInitiatorTlmChecker = new tlm_utils::tlm2_base_protocol_checker<>(str.c_str()); - } -#else - for (size_t i = 0; i < Configuration::getInstance().NumberOfTracePlayers; i++) { - std::string playerStr = "tracePlayer" + std::to_string(i); - TracePlayer *player; - sc_time playerClk; - - // The clock frequency for the player can be specified in the - // configuration file like in the example below (200 MHz): - // - // - // - // chstone-adpcm_32.stl - // - // - // - // If it is not specified in the configuration, the player will be - // configured to use the memory clock frequency got from the memory - // specs. - if (traceSetup[i].clkMhz == 0) - playerClk = Configuration::getInstance().memSpec.clk; - else - playerClk = FrequencyToClk(traceSetup[i].clkMhz); - const string pathToResources = resources; - player = new StlPlayer(playerStr.c_str(), pathToResources + string("traces/") + traceSetup[i].trace, playerClk, this); - if(Configuration::getInstance().SimulationProgressBar) - { - totalTransactions += player->getNumberOfLines(pathToResources + string("traces/") + traceSetup[i].trace); - } - players.push_back(player); - - if(Configuration::getInstance().CheckTLM2Protocol) { - string str = "TLMCheckerPlayer"+ std::to_string(i); - tlm_utils::tlm2_base_protocol_checker<> * playerTlmChecker = new tlm_utils::tlm2_base_protocol_checker<>(str.c_str()); - playersTlmCheckers.push_back(playerTlmChecker); - } - } - remainingTransactions = totalTransactions; -#endif /* USE_EXAMPLE_INITIATOR */ -} - -void SimulationManager::bindSockets() -{ -#if USE_EXAMPLE_INITIATOR - if(Configuration::getInstance().CheckTLM2Protocol) { - init->socket.bind(exampleInitiatorTlmChecker->target_socket); - exampleInitiatorTlmChecker->initiator_socket.bind(simulation->tSocket); - - } - else { - init->socket.bind(simulation->tSocket); -#else - if(Configuration::getInstance().CheckTLM2Protocol) { - for (size_t i = 0; i < players.size(); i++) { - players[i]->iSocket.bind(playersTlmCheckers[i]->target_socket); - playersTlmCheckers[i]->initiator_socket.bind(simulation->tSocket); - } - - } - else { - for (auto player : players) { - player->iSocket.bind(simulation->tSocket); - } - -#endif - } -} - -void SimulationManager::runSimulation(string traceName) -{ - report("\n\nStarting simulation:"); - report(headline); - report(" -> setup: \t\t" + getFileName(traceName)); - report(" -> memspec: \t\t" + Configuration::getInstance().memSpec.MemoryId); - cout << endl; - simStartTime = clock(); - - for (auto player : players) { - player->nextPayload(); - } - - sc_set_stop_mode(SC_STOP_FINISH_DELTA); - sc_start(); - double elapsed_secs = double(clock() - simStartTime) / CLOCKS_PER_SEC; - report("\nSimulation took " + to_string(elapsed_secs) + " seconds\n"); - delete simulation; -} - -void SimulationManager::startTraceAnalyzer() -{ - string p = getenv("trace"); - string run_tpr = p + " -f "; - run_tpr += "&"; - system(run_tpr.c_str()); -} - -void SimulationManager::addTraceSetups(SimulationBatch &batch, tinyxml2::XMLElement *simulation) -{ - vector devices; - XMLElement *tracesetups = simulation->FirstChildElement("tracesetups"); - XMLElement *simconfig = simulation->FirstChildElement("simconfig"); - unsigned int numberOfTracePlayers = 1; - XMLElement *ntp = simconfig->FirstChildElement("NumberOfTracePlayers"); - if (ntp != NULL) - ntp->QueryUnsignedAttribute("value", &numberOfTracePlayers); - - for (XMLElement *tracesetup = tracesetups->FirstChildElement("tracesetup"); tracesetup != NULL; tracesetup = tracesetup->NextSiblingElement("tracesetup")) { - for (XMLElement *device = tracesetup->FirstChildElement("device"); device != NULL; device = device->NextSiblingElement("device")) { - devices.push_back(Device(device->GetText(), device->IntAttribute("clkMhz"), device->IntAttribute("bl"))); - } - - // This step is done here to add a default device in case the user haven't specified a trace file to be executed by one or more trace players. - while (devices.size() < numberOfTracePlayers) { - devices.push_back(Device()); - } - - batch.traceSetups.emplace(tracesetup->Attribute("id"), devices); - devices.clear(); - } -} - -void inline SimulationManager::tracePlayerTerminates() -{ - static unsigned int finishedTracePlayers = 0; - finishedTracePlayers++; - - if (finishedTracePlayers == Configuration::getInstance().NumberOfTracePlayers) - simulation->terminateSimulation.notify(); -} -void inline SimulationManager::transactionFinished() -{ - remainingTransactions--; - loadbar(totalTransactions - remainingTransactions, totalTransactions); - if (remainingTransactions == 0) - { - cout << endl; - } -} -void SimulationManager::report(string message) -{ - cout << message << endl; -} - -void SimulationBatch::print() -{ - for (auto& s : traceSetups) - { - cout << "trace-setup " + s.first + ":\n"; - for (Device d : s.second) - cout << "\t(" << d.burstLength << ") " << d.trace << ";" << endl; - cout << endl; - } -} From 7de21cf05603a8103421dca00b086c1e9506e0cc Mon Sep 17 00:00:00 2001 From: Johannes Feldmann Date: Thu, 8 Jun 2017 11:01:08 +0200 Subject: [PATCH 49/59] Configuration for ECC Controller extended to make it possible to add other ECC Controller --- .../configs/simulator/ddr3-single-device.xml | 1 + .../resources/configs/simulator/ddr3.xml | 1 + .../resources/configs/simulator/ddr3_ecc.xml | 2 +- .../resources/configs/simulator/wideio.xml | 1 + .../resources/configs/simulator/wideio_ecc.xml | 2 +- .../configs/simulator/wideio_thermal.xml | 1 + .../core/configuration/Configuration.cpp | 17 +++++++++++++++-- .../core/configuration/Configuration.h | 4 +++- DRAMSys/simulator/src/error/errormodel.cpp | 3 ++- DRAMSys/simulator/src/simulation/DRAMSys.cpp | 16 ++++++++++++---- DRAMSys/simulator/src/simulation/Dram.h | 2 +- DRAMSys/simulator/src/simulation/main.cpp | 2 +- README.md | 8 ++++---- 13 files changed, 44 insertions(+), 16 deletions(-) diff --git a/DRAMSys/simulator/resources/configs/simulator/ddr3-single-device.xml b/DRAMSys/simulator/resources/configs/simulator/ddr3-single-device.xml index 0a19ff35..354ad0d5 100644 --- a/DRAMSys/simulator/resources/configs/simulator/ddr3-single-device.xml +++ b/DRAMSys/simulator/resources/configs/simulator/ddr3-single-device.xml @@ -11,6 +11,7 @@ + diff --git a/DRAMSys/simulator/src/controller/core/configuration/Configuration.cpp b/DRAMSys/simulator/src/controller/core/configuration/Configuration.cpp index e410f639..f0fd7f68 100644 --- a/DRAMSys/simulator/src/controller/core/configuration/Configuration.cpp +++ b/DRAMSys/simulator/src/controller/core/configuration/Configuration.cpp @@ -146,10 +146,8 @@ void Configuration::setParameter(std::string name, std::string value) } else { SJFProbability = string2int(value); } - else if (name == "ReadyBatchSize") - ReadyBatchSize = string2int(value); - else if (name == "ReadyBatchThresholdAge") - ReadyBatchThresholdAge = string2int(value); + else if (name == "RequestBufferSize") + RequestBufferSize = string2int(value); else if(name == "Capsize") Capsize = string2int(value); else if(name == "PowerDownTimeout") diff --git a/DRAMSys/simulator/src/controller/core/configuration/Configuration.h b/DRAMSys/simulator/src/controller/core/configuration/Configuration.h index c52f4655..2f158053 100644 --- a/DRAMSys/simulator/src/controller/core/configuration/Configuration.h +++ b/DRAMSys/simulator/src/controller/core/configuration/Configuration.h @@ -63,8 +63,7 @@ struct Configuration unsigned int MaxNrOfTransactions = 8; std::string Scheduler; unsigned int SJFProbability; - unsigned int ReadyBatchSize; - unsigned int ReadyBatchThresholdAge; + unsigned int RequestBufferSize; unsigned int Capsize = 5; sc_time getPowerDownTimeout(){return powerDownTimeoutInClk*memSpec.clk;} EPowerDownMode PowerDownMode = EPowerDownMode::Staggered; diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index d4336415..7b89d885 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -248,7 +248,7 @@ void SMS::updateMPKCs(sc_time memClk) { } bool SMS::isExceededReqBufferSize(Thread thread) { - return requestBuffers[thread].size() == REQUEST_BUFFER_SIZE; + return requestBuffers[thread].size() == Configuration::getInstance().RequestBufferSize; } bool SMS::isRequestBuffersEmpty() { diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h index 73675a41..3d4282aa 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.h +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h @@ -16,7 +16,6 @@ #define MEDIUM_THRESHOLD_AGE 50 #define HIGH_THRESHOLD_AGE 200 #define MPKC_RESET_CYCLE 10000 -#define REQUEST_BUFFER_SIZE 10 using namespace std; typedef std::deque::iterator gp_deque_iterator; From 64b105d5c7776d6f203d442a0a9a018f5bfddea0 Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Wed, 21 Jun 2017 16:42:47 +0200 Subject: [PATCH 57/59] Fix Disable Refresh Issue --- .../simulator/src/controller/Controller.cpp | 32 +++++++++++++++++++ DRAMSys/simulator/src/controller/Controller.h | 2 ++ .../src/controller/scheduler/Fifo.cpp | 5 +++ .../simulator/src/controller/scheduler/Fifo.h | 1 + .../src/controller/scheduler/FifoStrict.cpp | 4 +++ .../src/controller/scheduler/FifoStrict.h | 1 + .../src/controller/scheduler/Fr_Fcfs.cpp | 5 +++ .../src/controller/scheduler/Fr_Fcfs.h | 1 + .../src/controller/scheduler/IScheduler.h | 1 + .../src/controller/scheduler/SMS.cpp | 12 +++++++ .../simulator/src/controller/scheduler/SMS.h | 1 + 11 files changed, 65 insertions(+) diff --git a/DRAMSys/simulator/src/controller/Controller.cpp b/DRAMSys/simulator/src/controller/Controller.cpp index 8e307173..bf68d7d4 100644 --- a/DRAMSys/simulator/src/controller/Controller.cpp +++ b/DRAMSys/simulator/src/controller/Controller.cpp @@ -300,6 +300,11 @@ void Controller::frontendPEQCallback(tlm_generic_payload &payload, const tlm_pha scheduler->schedule(&payload); scheduleNextFromScheduler(DramExtension::getExtension(payload).getBank()); } + else if (phase == PendingRequest) + { + // Schedule a pending request. + scheduleNextFromScheduler(DramExtension::getExtension(payload).getBank()); + } else if (phase == END_RESP) { if (backpressure != NULL) @@ -365,6 +370,7 @@ void Controller::scheduleNextFromScheduler(Bank bank) return; } + bool rescheduled = true; pair nextRequest = scheduler->getNextRequest(bank); if(nextRequest.second != NULL) { @@ -372,7 +378,17 @@ void Controller::scheduleNextFromScheduler(Bank bank) controllerCore->scheduleRequest(nextRequest.first, *nextRequest.second); printDebugMessage("\t-> Next payload was scheduled by core [" + commandToString(nextRequest.first) + "]"); } + else + { + gp* pendingRequest = scheduler->getPendingRequest(bank); + if (pendingRequest != NULL) + { + rescheduled = true; + frontendPEQ.notify(*(pendingRequest), PendingRequest, Configuration::getInstance().memSpec.clk); + } + } + queue blocked; while (!blockedRequests.empty()) { bank = blockedRequests.front(); blockedRequests.pop(); @@ -383,7 +399,23 @@ void Controller::scheduleNextFromScheduler(Bank bank) controllerCore->scheduleRequest(nextRequest.first, *nextRequest.second); printDebugMessage("\t-> Next payload was scheduled by core [" + commandToString(nextRequest.first) + "] (unblocked)"); } + else + { + gp* pendingRequest = scheduler->getPendingRequest(bank); + if(pendingRequest != NULL) + { + //Pending request + if(!rescheduled) + { + rescheduled = true; + frontendPEQ.notify(*(pendingRequest), PendingRequest, Configuration::getInstance().memSpec.clk); + } + else + blocked.push(bank); + } + } } + blockedRequests = blocked; } void Controller::sendToFrontend(tlm_generic_payload &payload, const tlm_phase &phase, const sc_time &delay) diff --git a/DRAMSys/simulator/src/controller/Controller.h b/DRAMSys/simulator/src/controller/Controller.h index 682a29b0..b5f67ff7 100644 --- a/DRAMSys/simulator/src/controller/Controller.h +++ b/DRAMSys/simulator/src/controller/Controller.h @@ -73,6 +73,8 @@ using namespace std; using namespace tlm; +DECLARE_EXTENDED_PHASE(PendingRequest); + struct Controller: public sc_module, public IController { public: diff --git a/DRAMSys/simulator/src/controller/scheduler/Fifo.cpp b/DRAMSys/simulator/src/controller/scheduler/Fifo.cpp index beb57612..7d7a90e1 100644 --- a/DRAMSys/simulator/src/controller/scheduler/Fifo.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/Fifo.cpp @@ -60,4 +60,9 @@ pair Fifo::getNextRequest(Bank bank) return pair(Command::NOP, NULL); } +gp* Fifo::getPendingRequest(Bank bank) +{ + return NULL; +} + diff --git a/DRAMSys/simulator/src/controller/scheduler/Fifo.h b/DRAMSys/simulator/src/controller/scheduler/Fifo.h index 0576bb32..1b060b12 100644 --- a/DRAMSys/simulator/src/controller/scheduler/Fifo.h +++ b/DRAMSys/simulator/src/controller/scheduler/Fifo.h @@ -52,6 +52,7 @@ public: void schedule(gp* payload) override; std::pair getNextRequest(Bank bank) override; + virtual gp* getPendingRequest(Bank bank) override; private: std::map> buffer; diff --git a/DRAMSys/simulator/src/controller/scheduler/FifoStrict.cpp b/DRAMSys/simulator/src/controller/scheduler/FifoStrict.cpp index f9881fee..6e8bd292 100644 --- a/DRAMSys/simulator/src/controller/scheduler/FifoStrict.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/FifoStrict.cpp @@ -128,3 +128,7 @@ std::pair FifoStrict::getNextRequest(Bank b return pair(Command::NOP, NULL); } +gp* FifoStrict::getPendingRequest(Bank bank) +{ + return NULL; +} diff --git a/DRAMSys/simulator/src/controller/scheduler/FifoStrict.h b/DRAMSys/simulator/src/controller/scheduler/FifoStrict.h index 1cc9ece0..855f7ff3 100644 --- a/DRAMSys/simulator/src/controller/scheduler/FifoStrict.h +++ b/DRAMSys/simulator/src/controller/scheduler/FifoStrict.h @@ -56,6 +56,7 @@ public: void schedule(gp* payload) override; std::pair getNextRequest(Bank bank) override; + virtual gp* getPendingRequest(Bank bank) override; private: std::deque> buffer; diff --git a/DRAMSys/simulator/src/controller/scheduler/Fr_Fcfs.cpp b/DRAMSys/simulator/src/controller/scheduler/Fr_Fcfs.cpp index 30750c7f..5b022ca6 100644 --- a/DRAMSys/simulator/src/controller/scheduler/Fr_Fcfs.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/Fr_Fcfs.cpp @@ -121,3 +121,8 @@ deque::iterator FR_FCFS::FindRowHit(Bank bank) return queue.end(); } + +gp* FR_FCFS::getPendingRequest(Bank bank) +{ + return NULL; +} diff --git a/DRAMSys/simulator/src/controller/scheduler/Fr_Fcfs.h b/DRAMSys/simulator/src/controller/scheduler/Fr_Fcfs.h index 187b81ab..9347c21f 100644 --- a/DRAMSys/simulator/src/controller/scheduler/Fr_Fcfs.h +++ b/DRAMSys/simulator/src/controller/scheduler/Fr_Fcfs.h @@ -53,6 +53,7 @@ public: void schedule(gp* payload) override; std::pair getNextRequest(Bank bank) override; + virtual gp* getPendingRequest(Bank bank) override; private: std::map> buffer; diff --git a/DRAMSys/simulator/src/controller/scheduler/IScheduler.h b/DRAMSys/simulator/src/controller/scheduler/IScheduler.h index a951d015..efeebdc4 100644 --- a/DRAMSys/simulator/src/controller/scheduler/IScheduler.h +++ b/DRAMSys/simulator/src/controller/scheduler/IScheduler.h @@ -54,6 +54,7 @@ public: virtual void schedule(gp* payload) = 0; virtual std::pair getNextRequest(Bank bank) = 0; + virtual gp* getPendingRequest(Bank bank) = 0; static std::string sendername; protected: diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp index 7b89d885..64882dc3 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.cpp @@ -343,3 +343,15 @@ void SMS::multiBatchFormation(sc_time memClk) } while (formed); } } + +gp* SMS::getPendingRequest(Bank bank) +{ + for (auto& requestBuffer : requestBuffers) { + for (auto& request : requestBuffer.second) { + if (DramExtension::getBank(request) == bank) { + return request; + } + } + } + return NULL; +} diff --git a/DRAMSys/simulator/src/controller/scheduler/SMS.h b/DRAMSys/simulator/src/controller/scheduler/SMS.h index 3d4282aa..2843b990 100644 --- a/DRAMSys/simulator/src/controller/scheduler/SMS.h +++ b/DRAMSys/simulator/src/controller/scheduler/SMS.h @@ -46,6 +46,7 @@ public: virtual void schedule(gp *payload) override; virtual std::pair getNextRequest(Bank bank) override; + virtual gp* getPendingRequest(Bank bank) override; void batchScheduler(); From de7381ae49152263bd80f990a2588b40593d6a9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89der=20F=2E=20Zulian?= Date: Thu, 22 Jun 2017 12:05:40 +0200 Subject: [PATCH 58/59] Fix some segfaults. In the current implementation the object deletion order is important. Messages regarding power and energy are printed inside the Dram destructor. The controller object was destructed and then called by the Dram object. The behavior varies with compiler (clang or gcc). It seems that clang deletes objects later than gcc masking some bugs. --- DRAMSys/simulator/src/simulation/DRAMSys.cpp | 10 +++++----- DRAMSys/simulator/src/simulation/main.cpp | 9 ++++++--- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/DRAMSys/simulator/src/simulation/DRAMSys.cpp b/DRAMSys/simulator/src/simulation/DRAMSys.cpp index 41b80d42..515c292c 100644 --- a/DRAMSys/simulator/src/simulation/DRAMSys.cpp +++ b/DRAMSys/simulator/src/simulation/DRAMSys.cpp @@ -245,11 +245,6 @@ DRAMSys::~DRAMSys() delete arbiter; - for (auto controller : controllers) - { - delete controller; - } - for (auto dram : drams) { delete dram; @@ -264,6 +259,11 @@ DRAMSys::~DRAMSys() { delete tlmChecker; } + + for (auto controller : controllers) + { + delete controller; + } } void DRAMSys::report(string message) diff --git a/DRAMSys/simulator/src/simulation/main.cpp b/DRAMSys/simulator/src/simulation/main.cpp index 18e00f77..60246caf 100644 --- a/DRAMSys/simulator/src/simulation/main.cpp +++ b/DRAMSys/simulator/src/simulation/main.cpp @@ -78,15 +78,15 @@ int sc_main(int argc, char **argv) std::vector players; // Instantiate DRAMSys: - DRAMSys dramSys("DRAMSys", SimulationXML, resources); + DRAMSys *dramSys = new DRAMSys("DRAMSys", SimulationXML, resources); // Instantiate STL Players: - traceSetup(SimulationXML, resources, &players); + traceSetup *ts = new traceSetup(SimulationXML, resources, &players); // Bind STL Players with DRAMSys: for(auto& p : players) { - p->iSocket.bind(dramSys.tSocket); + p->iSocket.bind(dramSys->tSocket); } // Store the starting of the simulation in wallclock time: @@ -105,5 +105,8 @@ int sc_main(int argc, char **argv) double elapsed_secs = double(clock() - simStartTime) / CLOCKS_PER_SEC; cout << "Simulation took " + to_string(elapsed_secs) + " seconds" << endl; + delete dramSys; + delete ts; + return 0; } From a5e62f75abe55d66f6ee08a13f170a739c58d03f Mon Sep 17 00:00:00 2001 From: "Thanh C. Tran" Date: Thu, 22 Jun 2017 12:37:46 +0200 Subject: [PATCH 59/59] Revert back to use default simulation file --- DRAMSys/simulator/src/simulation/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DRAMSys/simulator/src/simulation/main.cpp b/DRAMSys/simulator/src/simulation/main.cpp index 72c31f8b..60246caf 100644 --- a/DRAMSys/simulator/src/simulation/main.cpp +++ b/DRAMSys/simulator/src/simulation/main.cpp @@ -72,7 +72,7 @@ int sc_main(int argc, char **argv) } else { - SimulationXML = resources + "simulations/sms-example.xml"; + SimulationXML = resources + "simulations/ddr3-example.xml"; } std::vector players;