From bdc9e58d605fba39b97886e86d5f1fe0b192b606 Mon Sep 17 00:00:00 2001 From: Felipe Salerno Prado Date: Thu, 28 Apr 2016 17:17:26 +0200 Subject: [PATCH 1/8] Charts Correction --- DRAMSys/analyzer/scripts/plots.py | 58 +++++++++++++------------------ 1 file changed, 25 insertions(+), 33 deletions(-) diff --git a/DRAMSys/analyzer/scripts/plots.py b/DRAMSys/analyzer/scripts/plots.py index 745ad8c2..4706b98d 100644 --- a/DRAMSys/analyzer/scripts/plots.py +++ b/DRAMSys/analyzer/scripts/plots.py @@ -7,7 +7,6 @@ import os plots = [] - def plot(function): plots.append(function) return function @@ -22,58 +21,52 @@ def memory_utilisation_window(connection, tracePath): # Besides, extracting the data from the memory specs, it is feasible to calculate the maximum data rate of the memory and then determine the bandwidth in Gbit/s. # The bandwidth data are then plotted in two graphics. - steps = 1000 cursor = connection.cursor() - cursor.execute(""" SELECT max(DataStrobeEnd) FROM Transactions """) - total = cursor.fetchone() - windowSize = ceil(float(total[0])/float(steps)) - if (windowSize == 0): - windowSize = 1 - # print(steps) + cursor.execute(""" SELECT max(time) FROM Power """) + maxTime = cursor.fetchone() + cursor.execute(""" SELECT min(time) FROM Power where time > 0 """) + windowSize = cursor.fetchone()[0] + steps = ceil(float(maxTime[0])/float(windowSize)) # All possible cases of data transfers inside a time window queryFull = """ SELECT sum(DataStrobeEnd - DataStrobeBegin) FROM transactions Where DataStrobeBegin > ? and DataStrobeEnd < ?""" # The data transfer begins and ends inside the time window queryEnd = """ SELECT sum(DataStrobeEnd - ?) FROM transactions Where DataStrobeBegin < ? and DataStrobeEnd > ? and DataStrobeEnd <=?""" # Only the end of the data transfer is inside the time window queryBegin = """ SELECT sum(? - DataStrobeBegin) FROM transactions Where DataStrobeBegin >= ? and DataStrobeBegin < ? and DataStrobeEnd > ?""" # Only the beginning of the data transfer is inside the time window queryPart = """ SELECT DataStrobeBegin FROM transactions Where DataStrobeBegin <= ? and DataStrobeEnd >= ?""" # The data transfer occupies all the time window maxDataRate = maximum_data_rate(connection) - # print(width) - # print(clk) - # print(rate) - bandwidthPercentage = [0] * steps - bandwidth = [0] * steps + bandwidthPercentage = [0] * (steps+1) + bandwidth = [0] * (steps+1) + bandwidthPercentage[0] = 0 + bandwidth[0] = 0 for i in range(steps): - # print(i) - bandwidthPercentage[i] = 0 + bandwidthPercentage[i+1] = 0 cursor.execute(queryPart, (i*windowSize, (i+1)*windowSize)) result = cursor.fetchone() if(result is None): cursor.execute(queryFull, (i*windowSize, (i+1)*windowSize)) result = cursor.fetchone() if(result[0] is not None): - bandwidthPercentage[i] += int(result[0]) + bandwidthPercentage[i+1] += int(result[0]) # print(bandwidthPercentage[i]) cursor.execute(queryEnd, (i*windowSize, i*windowSize, i*windowSize, (i+1)*windowSize)) result = cursor.fetchone() if(result[0] is not None): - bandwidthPercentage[i] += int(result[0]) + bandwidthPercentage[i+1] += int(result[0]) # print(bandwidthPercentage[i]) cursor.execute(queryBegin, ((i+1)*windowSize, i*windowSize, (i+1)*windowSize, (i+1)*windowSize)) result = cursor.fetchone() if(result[0] is not None): - bandwidthPercentage[i] += int(result[0]) + bandwidthPercentage[i+1] += int(result[0]) # print(bandwidthPercentage[i]) else: - bandwidthPercentage[i] = windowSize + bandwidthPercentage[i+1] = windowSize # print(bandwidthPercentage[i]) - bandwidthPercentage[i] = float(bandwidthPercentage[i]/windowSize) - bandwidth[i] = float(bandwidthPercentage[i])*float(maxDataRate)/1024 - bandwidthPercentage[i] *= 100 + bandwidthPercentage[i+1] = float(bandwidthPercentage[i+1]/windowSize) + bandwidth[i+1] = float(bandwidthPercentage[i+1])*float(maxDataRate)/1024 + bandwidthPercentage[i+1] *= 100 name = ntpath.basename(tracePath) basename, extension = os.path.splitext(name) - - OUTPUT_FILE = 'memory_utilization_' + basename + '.pdf' print("Output file is {0}".format(OUTPUT_FILE)) @@ -81,8 +74,7 @@ def memory_utilisation_window(connection, tracePath): import numpy as np from matplotlib.backends.backend_pdf import PdfPages - time = np.arange(0, steps*windowSize, windowSize) - + time = np.arange(0, (steps+1)*windowSize, windowSize) plt.figure() subplotIndex = 211 @@ -112,13 +104,13 @@ def power_window(connection, tracePath): cursor = connection.cursor() cursor.execute(""" SELECT max(time) FROM Power """) maxTime = cursor.fetchone() - cursor.execute(""" SELECT min(time) FROM Power WHERE time > 0""") - windowSize = cursor.fetchone() - steps = ceil(float(maxTime[0])/float(windowSize[0])) + cursor.execute(""" SELECT min(time) FROM Power where time > 0 """) + windowSize = cursor.fetchone()[0] + steps = ceil(float(maxTime[0])/float(windowSize)) cursor.execute(""" SELECT * FROM Power """) - time = [0] * steps - power = [0] * steps - for i in range(steps): + time = [0] * (steps+1) + power = [0] * (steps+1) + for i in range((steps+1)): result = cursor.fetchone() time[i] = int(result[0])/1000 power[i] = float(result[1]) @@ -156,7 +148,7 @@ def power_window(connection, tracePath): # return "Saved as hist.png" -def generatePlots(pathToTrace): +def generatePlots(pathToTrace): connection = sqlite3.connect(pathToTrace) print("================================") From 1dfbbf62cef811f82ee1163f4e41d92bf18b7297 Mon Sep 17 00:00:00 2001 From: Felipe Salerno Prado Date: Mon, 9 May 2016 13:59:59 +0200 Subject: [PATCH 2/8] Choose the number of samples instead of the size of the time window --- .../resources/simulations/ddr3-example.xml | 3 +- .../resources/simulations/sim-batch.xml | 3 +- .../core/configuration/Configuration.cpp | 17 ++++--- .../core/configuration/Configuration.h | 4 +- DRAMSys/simulator/src/simulation/Dram.h | 8 ++-- .../simulator/src/simulation/Simulation.cpp | 12 +++-- .../simulator/src/simulation/StlDataPlayer.h | 44 ++++++++++++++++++ DRAMSys/simulator/src/simulation/StlPlayer.h | 46 +++++++++++++++++++ README.md | 17 ++----- 9 files changed, 119 insertions(+), 35 deletions(-) diff --git a/DRAMSys/simulator/resources/simulations/ddr3-example.xml b/DRAMSys/simulator/resources/simulations/ddr3-example.xml index f4793a45..0df2e1c7 100644 --- a/DRAMSys/simulator/resources/simulations/ddr3-example.xml +++ b/DRAMSys/simulator/resources/simulations/ddr3-example.xml @@ -4,8 +4,7 @@ - - + diff --git a/DRAMSys/simulator/resources/simulations/sim-batch.xml b/DRAMSys/simulator/resources/simulations/sim-batch.xml index b356d01c..aaaba0a9 100644 --- a/DRAMSys/simulator/resources/simulations/sim-batch.xml +++ b/DRAMSys/simulator/resources/simulations/sim-batch.xml @@ -4,8 +4,7 @@ - - + diff --git a/DRAMSys/simulator/src/controller/core/configuration/Configuration.cpp b/DRAMSys/simulator/src/controller/core/configuration/Configuration.cpp index 4959d5a7..975cc7a0 100644 --- a/DRAMSys/simulator/src/controller/core/configuration/Configuration.cpp +++ b/DRAMSys/simulator/src/controller/core/configuration/Configuration.cpp @@ -136,25 +136,28 @@ void Configuration::setParameter(std::string name, std::string value) DatabaseRecording = string2bool(value); else if(name == "PowerAnalysis") PowerAnalysis = string2bool(value); - else if (name == "PowerWindowSize") - PowerWindowSize = std::stod(value.c_str()); - else if (name == "PowerWindowUnit") - PowerWindowUnit = string2TimeUnit(value); + else if (name == "NumberOfTimeWindows") { + if(string2int(value) < 1) { + SC_REPORT_FATAL("Configuration", ("Invalid value for parameter " + name + ". This parameter must be at least one.").c_str()); + throw; + } + NumberOfTimeWindows = string2int(value); + } else if(name == "Debug") Debug = string2bool(value); else if (name == "NumberOfTracePlayers") NumberOfTracePlayers = string2int(value); else if (name == "NumberOfMemChannels") { NumberOfMemChannels = string2int(value); - unsigned int maxNumberofMemChannels = xmlAddressDecoder::getInstance().amount["channel"]; - if (NumberOfMemChannels > maxNumberofMemChannels) { + unsigned int maxNumberofMemChannels = xmlAddressDecoder::getInstance().amount["channel"]; + if (NumberOfMemChannels > maxNumberofMemChannels) { SC_REPORT_FATAL("Configuration", ("Invalid value for parameter " + name + ". Value is out of range. The maximum value according to " + "the address mapping configuration file is " + std::to_string(maxNumberofMemChannels) + ".").c_str()); throw; - } + } } else if (name == "ControllerCoreDisableRefresh") ControllerCoreDisableRefresh = string2bool(value); diff --git a/DRAMSys/simulator/src/controller/core/configuration/Configuration.h b/DRAMSys/simulator/src/controller/core/configuration/Configuration.h index e6abb2ae..450e7bde 100644 --- a/DRAMSys/simulator/src/controller/core/configuration/Configuration.h +++ b/DRAMSys/simulator/src/controller/core/configuration/Configuration.h @@ -75,8 +75,8 @@ struct Configuration //SimConfig bool DatabaseRecording = true; bool PowerAnalysis = false; - double PowerWindowSize; - enum sc_time_unit PowerWindowUnit; + sc_time TraceLength; + unsigned int NumberOfTimeWindows; bool Debug = false; unsigned int NumberOfTracePlayers = 1; unsigned int NumberOfMemChannels = 1; diff --git a/DRAMSys/simulator/src/simulation/Dram.h b/DRAMSys/simulator/src/simulation/Dram.h index ed5152b0..47c7625e 100644 --- a/DRAMSys/simulator/src/simulation/Dram.h +++ b/DRAMSys/simulator/src/simulation/Dram.h @@ -67,9 +67,7 @@ struct Dram : sc_module // Power Model related bool powerAnalysis = Configuration::getInstance().PowerAnalysis; - double pWindowSize = Configuration::getInstance().PowerWindowSize; - enum sc_time_unit pWindowUnit = Configuration::getInstance().PowerWindowUnit; - sc_time powerWindowSize = sc_time(pWindowSize, pWindowUnit); + sc_time powerWindowSize = Configuration::getInstance().TraceLength/Configuration::getInstance().NumberOfTimeWindows; libDRAMPower *DRAMPower; double totalEnergy = 0; double sumOfEnergyWindows = 0; @@ -230,10 +228,10 @@ struct Dram : sc_module double currentAveragePower = 0; double currentTotalEnergy = 0; - do - { + do { DRAMPower->updateCounters(false); DRAMPower->calcEnergy(); + currentTotalEnergy = DRAMPower->getEnergy().total_energy - totalEnergy; currentAveragePower = currentTotalEnergy/powerWindowSize.value(); tlmRecorder->recordPower(sc_time_stamp(),currentAveragePower); diff --git a/DRAMSys/simulator/src/simulation/Simulation.cpp b/DRAMSys/simulator/src/simulation/Simulation.cpp index d889e233..750439db 100644 --- a/DRAMSys/simulator/src/simulation/Simulation.cpp +++ b/DRAMSys/simulator/src/simulation/Simulation.cpp @@ -121,11 +121,15 @@ void Simulation::instantiateModules(const string &traceName, const string &pathT // or if you simply dont care about the data the normal StlPlayer is used. if(Configuration::getInstance().ErrorStoreMode == ErrorStorageMode::NoStorage) { - player = new StlPlayer<>(playerStr.c_str(), pathToResources + string("traces/") + devices[i].trace, devices[i].clkMhz, this); + StlPlayer<> *newPlayer = new StlPlayer<>(playerStr.c_str(), pathToResources + string("traces/") + devices[i].trace, devices[i].clkMhz, this); + player = newPlayer; + newPlayer->getTraceLength(pathToResources + string("traces/") + devices[i].trace); } else { - player = new StlDataPlayer<>(playerStr.c_str(), pathToResources + string("traces/") + devices[i].trace, devices[i].clkMhz, this); + StlDataPlayer<> *newPlayer = new StlDataPlayer<>(playerStr.c_str(), pathToResources + string("traces/") + devices[i].trace, devices[i].clkMhz, this); + player = newPlayer; + newPlayer->getTraceLength(pathToResources + string("traces/") + devices[i].trace); } players.push_back(player); } @@ -177,7 +181,7 @@ Simulation::~Simulation() } for (auto rec : tlmRecorders) { - delete rec; + delete rec; } } @@ -189,7 +193,7 @@ void Simulation::start() report(" -> memspec: \t\t" + Configuration::getInstance().memSpec.MemoryId); cout << endl; simulationStartTime = clock(); - + for (auto player : players) { player->nextPayload(); } diff --git a/DRAMSys/simulator/src/simulation/StlDataPlayer.h b/DRAMSys/simulator/src/simulation/StlDataPlayer.h index d4b55638..06c253d7 100644 --- a/DRAMSys/simulator/src/simulation/StlDataPlayer.h +++ b/DRAMSys/simulator/src/simulation/StlDataPlayer.h @@ -134,6 +134,50 @@ public: } } + void getTraceLength(string pathToTrace) + { + ifstream newFile; + newFile.open(pathToTrace); + if(newFile.is_open()) { + newFile.seekg(-1,ios_base::end);// go to one spot before the EOF + char ch; + newFile.get(ch); + + if(ch == file.eof()) + SC_REPORT_FATAL(0, (string("Empty Trace ") + pathToTrace).c_str()); + + if(ch == '\n') + newFile.seekg(-2,ios_base::end); + + bool keepLooping = true; + while(keepLooping) { + + newFile.get(ch); // Get current byte's data + + if((int)newFile.tellg() <= 1) { // If the data was at or before the 0th byte + newFile.seekg(0); // The first line is the last line + keepLooping = false; // So stop there + } + else if(ch == '\n') { // If the data was a newline + keepLooping = false; // Stop at the current position. + } + else { // If the data was neither a newline nor at the 0 byte + newFile.seekg(-2,ios_base::cur); // Move to the front of that data, then to the front of the data before it + } + } + + string lastLine; + getline(newFile,lastLine); // Read the current line + std::istringstream iss(lastLine); + string time; + iss >> time; + Configuration::getInstance().TraceLength = std::stoull(time.c_str())*clk; + newFile.close(); + } + + } + + private: ifstream file; unsigned int burstlength; diff --git a/DRAMSys/simulator/src/simulation/StlPlayer.h b/DRAMSys/simulator/src/simulation/StlPlayer.h index 918eae84..92038aad 100644 --- a/DRAMSys/simulator/src/simulation/StlPlayer.h +++ b/DRAMSys/simulator/src/simulation/StlPlayer.h @@ -120,6 +120,52 @@ public: } } + + + void getTraceLength(string pathToTrace) + { + ifstream newFile; + newFile.open(pathToTrace); + if(newFile.is_open()) { + newFile.seekg(-1,ios_base::end);// go to one spot before the EOF + char ch; + newFile.get(ch); + + if(ch == file.eof()) + SC_REPORT_FATAL(0, (string("Empty Trace ") + pathToTrace).c_str()); + + if(ch == '\n') + newFile.seekg(-2,ios_base::end); + + bool keepLooping = true; + while(keepLooping) { + + newFile.get(ch); // Get current byte's data + + if((int)newFile.tellg() <= 1) { // If the data was at or before the 0th byte + newFile.seekg(0); // The first line is the last line + keepLooping = false; // So stop there + } + else if(ch == '\n') { // If the data was a newline + keepLooping = false; // Stop at the current position. + } + else { // If the data was neither a newline nor at the 0 byte + newFile.seekg(-2,ios_base::cur); // Move to the front of that data, then to the front of the data before it + } + } + + string lastLine; + getline(newFile,lastLine); // Read the current line + std::istringstream iss(lastLine); + string time; + iss >> time; + Configuration::getInstance().TraceLength = std::stoull(time.c_str())*clk; + newFile.close(); + } + + } + + private: ifstream file; unsigned int burstlength; diff --git a/README.md b/README.md index 84a10c31..8e841423 100644 --- a/README.md +++ b/README.md @@ -319,8 +319,7 @@ The DRAMSys' main configuration file is presented below. - - + @@ -419,8 +418,7 @@ The XML code below shows a typic configuration: - - + @@ -532,15 +530,8 @@ Below are listed the configuration sections and configuration fields. - *PowerAnalysis* (boolean) - "1": enables live power analysis with the DRAMPower tool - "0": disables power analysis - - *PowerWindowSize* (double) - - Size of the time window used to evaluate averate power consumption - - *PowerWindowUnit* (string) - - "s": seconds - - "ms": millisecond - - "us": microseconds - - "ns": nanoseconds - - "ps": picoseconds - - "fs": femtoseconds + - *NumberOfTimeWindows* (int) + - number of time windows used to evaluate average bandwidth and average power consumption - *NumberOfTracePlayers* (unsigned int) - Number of trace players - *NumberOfMemChannels* (unsigned int) From a88d17976a0462d82b737de2080c4007c0c656d8 Mon Sep 17 00:00:00 2001 From: Felipe Salerno Prado Date: Mon, 9 May 2016 14:45:06 +0200 Subject: [PATCH 3/8] Plot bandwidth over time regardless of Power Analysis --- .../analyzer/businessObjects/generalinfo.h | 5 +- DRAMSys/analyzer/data/tracedb.cpp | 8 ++- DRAMSys/analyzer/scripts/plots.py | 72 ++++++++++--------- .../resources/scripts/createTraceDB.sql | 19 ++--- DRAMSys/simulator/src/common/TlmRecorder.cpp | 11 +-- DRAMSys/simulator/src/common/TlmRecorder.h | 2 +- DRAMSys/simulator/src/simulation/Dram.h | 4 +- 7 files changed, 68 insertions(+), 53 deletions(-) diff --git a/DRAMSys/analyzer/businessObjects/generalinfo.h b/DRAMSys/analyzer/businessObjects/generalinfo.h index e103f47c..46b6b3ee 100644 --- a/DRAMSys/analyzer/businessObjects/generalinfo.h +++ b/DRAMSys/analyzer/businessObjects/generalinfo.h @@ -49,10 +49,11 @@ struct GeneralInfo QString description; QString unitOfTime; unsigned int clkPeriod; + unsigned long long timeWindowSize; public: - GeneralInfo(unsigned int numberOfTransactions,unsigned int numberOfPhases, Timespan span,unsigned int numberOfBanks,const QString& description, QString unitOfTime,unsigned int clkPeriod) : - numberOfTransactions(numberOfTransactions) , numberOfPhases(numberOfPhases), span(span), numberOfBanks(numberOfBanks), description(description), unitOfTime(unitOfTime),clkPeriod(clkPeriod) + GeneralInfo(unsigned int numberOfTransactions,unsigned int numberOfPhases,Timespan span,unsigned int numberOfBanks,const QString& description, QString unitOfTime,unsigned int clkPeriod, unsigned long long timeWindowSize) : + numberOfTransactions(numberOfTransactions) , numberOfPhases(numberOfPhases),span(span), numberOfBanks(numberOfBanks), description(description), unitOfTime(unitOfTime), clkPeriod(clkPeriod), timeWindowSize(timeWindowSize) { } diff --git a/DRAMSys/analyzer/data/tracedb.cpp b/DRAMSys/analyzer/data/tracedb.cpp index 89cd17cb..115dc46a 100644 --- a/DRAMSys/analyzer/data/tracedb.cpp +++ b/DRAMSys/analyzer/data/tracedb.cpp @@ -199,7 +199,7 @@ ID TraceDB::getTransactionIDFromPhaseID(ID phaseID) GeneralInfo TraceDB::getGeneralInfoFromDB() { QSqlQuery query(database); - query.prepare("SELECT NumberOfTransactions,TraceEnd,NumberOfBanks,Clk,UnitOfTime,Traces,Memspec,Memconfig FROM GeneralInfo"); + query.prepare("SELECT NumberOfTransactions,TraceEnd,NumberOfBanks,Clk,UnitOfTime,Traces,Memspec,Memconfig,TimeWindowSize FROM GeneralInfo"); executeQuery(query); if(query.next()) @@ -214,15 +214,17 @@ GeneralInfo TraceDB::getGeneralInfoFromDB() QString traces = "Traces: " + query.value(5).toString(); QString memspec = "Memspec: " + query.value(6).toString(); QString memconfig = "Memconfig: " + query.value(7).toString(); + unsigned long long timeWindowSize = query.value(8).toLongLong(); QString description = (traces + "\n"); description += memconfig + "\n"; description += memspec + "\n"; description += "Number of Transactions: " + QString::number(numberOfTransactions) + "\n"; description += "Clock period: " + QString::number(clkPeriod) + " " + unitOfTime + "\n"; - description += "Length of trace: " + prettyFormatTime(traceEnd); + description += "Length of trace: " + prettyFormatTime(traceEnd) + "\n"; + description += "Time windows size: " + prettyFormatTime(timeWindowSize); - return GeneralInfo(numberOfTransactions, numberOfPhases, Timespan(0,traceEnd),numberOfBanks,description,unitOfTime,clkPeriod); + return GeneralInfo(numberOfTransactions, numberOfPhases, Timespan(0,traceEnd),numberOfBanks,description,unitOfTime,clkPeriod,timeWindowSize); } else { diff --git a/DRAMSys/analyzer/scripts/plots.py b/DRAMSys/analyzer/scripts/plots.py index 4706b98d..cae5f80d 100644 --- a/DRAMSys/analyzer/scripts/plots.py +++ b/DRAMSys/analyzer/scripts/plots.py @@ -22,17 +22,18 @@ def memory_utilisation_window(connection, tracePath): # The bandwidth data are then plotted in two graphics. cursor = connection.cursor() - cursor.execute(""" SELECT max(time) FROM Power """) - maxTime = cursor.fetchone() - cursor.execute(""" SELECT min(time) FROM Power where time > 0 """) + cursor.execute("SELECT TimeWindowSize FROM generalInfo") windowSize = cursor.fetchone()[0] - steps = ceil(float(maxTime[0])/float(windowSize)) + cursor.execute("SELECT TraceEnd FROM generalInfo") + traceEnd = cursor.fetchone()[0] + steps = ceil(float(traceEnd)/float(windowSize)) # All possible cases of data transfers inside a time window queryFull = """ SELECT sum(DataStrobeEnd - DataStrobeBegin) FROM transactions Where DataStrobeBegin > ? and DataStrobeEnd < ?""" # The data transfer begins and ends inside the time window queryEnd = """ SELECT sum(DataStrobeEnd - ?) FROM transactions Where DataStrobeBegin < ? and DataStrobeEnd > ? and DataStrobeEnd <=?""" # Only the end of the data transfer is inside the time window queryBegin = """ SELECT sum(? - DataStrobeBegin) FROM transactions Where DataStrobeBegin >= ? and DataStrobeBegin < ? and DataStrobeEnd > ?""" # Only the beginning of the data transfer is inside the time window queryPart = """ SELECT DataStrobeBegin FROM transactions Where DataStrobeBegin <= ? and DataStrobeEnd >= ?""" # The data transfer occupies all the time window maxDataRate = maximum_data_rate(connection) + maximumPercentage = 0 bandwidthPercentage = [0] * (steps+1) bandwidth = [0] * (steps+1) bandwidthPercentage[0] = 0 @@ -63,6 +64,8 @@ def memory_utilisation_window(connection, tracePath): bandwidthPercentage[i+1] = float(bandwidthPercentage[i+1]/windowSize) bandwidth[i+1] = float(bandwidthPercentage[i+1])*float(maxDataRate)/1024 bandwidthPercentage[i+1] *= 100 + if(maximumPercentage < 100 and maximumPercentage < bandwidthPercentage[i+1]): + maximumPercentage = bandwidthPercentage[i+1] name = ntpath.basename(tracePath) basename, extension = os.path.splitext(name) @@ -80,9 +83,9 @@ def memory_utilisation_window(connection, tracePath): subplotIndex = 211 plt.subplot(subplotIndex) plt.plot(time/1000, bandwidthPercentage) - plt.xlabel('Time (ns)') + #plt.xlabel('Time (ns)') plt.ylabel('Bandwidth (%)') - plt.ylim(0, 120) + plt.ylim(0, maximumPercentage + (10 - maximumPercentage%10)) plt.grid(True) subplotIndex += 1 @@ -102,36 +105,40 @@ def memory_utilisation_window(connection, tracePath): @plot def power_window(connection, tracePath): cursor = connection.cursor() - cursor.execute(""" SELECT max(time) FROM Power """) - maxTime = cursor.fetchone() - cursor.execute(""" SELECT min(time) FROM Power where time > 0 """) - windowSize = cursor.fetchone()[0] - steps = ceil(float(maxTime[0])/float(windowSize)) - cursor.execute(""" SELECT * FROM Power """) - time = [0] * (steps+1) - power = [0] * (steps+1) - for i in range((steps+1)): - result = cursor.fetchone() - time[i] = int(result[0])/1000 - power[i] = float(result[1]) - name = ntpath.basename(tracePath) - basename, extension = os.path.splitext(name) + cursor.execute(""" SELECT time FROM Power """) - OUTPUT_FILE = 'power_' + basename + '.pdf' - print("Output file is {0}".format(OUTPUT_FILE)) + if(cursor.fetchone() is not None): + cursor.execute("SELECT TimeWindowSize FROM generalInfo") + windowSize = cursor.fetchone()[0] + cursor.execute("SELECT TraceEnd FROM generalInfo") + traceEnd = cursor.fetchone()[0] + steps = ceil(float(traceEnd)/float(windowSize)) + cursor.execute(""" SELECT * FROM Power """) + time = [0] * (steps+1) + power = [0] * (steps+1) + for i in range((steps+1)): + result = cursor.fetchone() + time[i] = float(result[0])*1000000000 + power[i] = float(result[1])/1000000000 - import matplotlib.pyplot as plt - from matplotlib.backends.backend_pdf import PdfPages + name = ntpath.basename(tracePath) + basename, extension = os.path.splitext(name) - plt.plot(time, power) - plt.xlabel('Time (ns)') - plt.ylabel('Power (mW)') - plt.grid(True) - pdf = PdfPages(OUTPUT_FILE) - pdf.savefig() - pdf.close() - plt.close() + OUTPUT_FILE = 'power_' + basename + '.pdf' + print("Output file is {0}".format(OUTPUT_FILE)) + + import matplotlib.pyplot as plt + from matplotlib.backends.backend_pdf import PdfPages + + plt.plot(time, power) + plt.xlabel('Time (ns)') + plt.ylabel('Power (mW)') + plt.grid(True) + pdf = PdfPages(OUTPUT_FILE) + pdf.savefig() + pdf.close() + plt.close() return # @plot @@ -154,6 +161,7 @@ def generatePlots(pathToTrace): print("================================") print("Generating plots for {0}".format(pathToTrace)) + for p in plots: p(connection, pathToTrace) diff --git a/DRAMSys/simulator/resources/scripts/createTraceDB.sql b/DRAMSys/simulator/resources/scripts/createTraceDB.sql index aa236f83..1f72d197 100644 --- a/DRAMSys/simulator/resources/scripts/createTraceDB.sql +++ b/DRAMSys/simulator/resources/scripts/createTraceDB.sql @@ -15,18 +15,19 @@ CREATE TABLE Phases( ); CREATE TABLE GeneralInfo( - NumberOfTransactions INTEGER, + NumberOfTransactions INTEGER, TraceEnd INTEGER, NumberOfBanks INTEGER, - clk INTEGER, + clk INTEGER, UnitOfTime TEXT, - Memconfig TEXT, + Memconfig TEXT, Memspec TEXT, - Traces TEXT + Traces TEXT, + TimeWindowSize INTEGER ); CREATE TABLE Power( - time INTEGER, + time DOUBLE, AveragePower DOUBLE ); @@ -43,13 +44,13 @@ CREATE TABLE DebugMessages( -- use SQLITE R* TREE Module to make queries on timespans effecient (see http://www.sqlite.org/rtree.html) CREATE VIRTUAL TABLE ranges USING rtree( - id, - begin, end + id, + begin, end ); CREATE TABLE Transactions( ID INTEGER, - Range INTEGER, + Range INTEGER, Address INTEGER, Burstlength INTEGER, TThread INTEGER, @@ -61,7 +62,7 @@ CREATE TABLE Transactions( DataStrobeBegin INTEGER, DataStrobeEnd INTEGER, TimeOfGeneration INTEGER, - Command TEXT + Command TEXT ); CREATE INDEX ranges_index ON Transactions(Range); diff --git a/DRAMSys/simulator/src/common/TlmRecorder.cpp b/DRAMSys/simulator/src/common/TlmRecorder.cpp index c55b2c19..c2c8a41b 100644 --- a/DRAMSys/simulator/src/common/TlmRecorder.cpp +++ b/DRAMSys/simulator/src/common/TlmRecorder.cpp @@ -74,10 +74,10 @@ TlmRecorder::~TlmRecorder() closeConnection(); } -void TlmRecorder::recordPower(sc_time time, double averagePower) +void TlmRecorder::recordPower(double timeInSeconds, double averagePower) { if (TlmRecorder::recordingEnabled) { - sqlite3_bind_int64(insertPowerStatement, 1, time.value()); + sqlite3_bind_double(insertPowerStatement, 1, timeInSeconds); sqlite3_bind_double(insertPowerStatement, 2, averagePower); executeSqlStatement(insertPowerStatement); } @@ -270,8 +270,8 @@ void TlmRecorder::prepareSqlStatements() updatePhaseString = "UPDATE Phases SET PhaseEnd = :end WHERE Transact = :trans AND PhaseName = :name"; insertGeneralInfoString = - "INSERT INTO GeneralInfo (NumberOfTransactions,TraceEnd,NumberOfBanks,clk,UnitOfTime,Memconfig,Memspec,Traces) Values " - "(:numberOfTransactions,:end,:numberOfBanks,:clk,:unitOfTime,:memconfig,:memspec,:traces)"; + "INSERT INTO GeneralInfo (NumberOfTransactions,TraceEnd,NumberOfBanks,clk,UnitOfTime,Memconfig,Memspec,Traces,TimeWindowSize) VALUES" + "(:numberOfTransactions,:end,:numberOfBanks,:clk,:unitOfTime,:memconfig,:memspec,:traces,:timeWindowSize)"; insertDebugMessageString = "INSERT INTO DebugMessages (Time,Message) Values (:time,:message)"; insertPowerString = "INSERT INTO Power VALUES (:time,:averagePower)"; @@ -304,6 +304,9 @@ void TlmRecorder::insertGeneralInfo() sqlite3_bind_text(insertGeneralInfoStatement, 6, memconfig.c_str(), memconfig.length(), NULL); sqlite3_bind_text(insertGeneralInfoStatement, 7, memspec.c_str(), memspec.length(), NULL); sqlite3_bind_text(insertGeneralInfoStatement, 8, traces.c_str(), traces.length(), NULL); + sqlite3_bind_int64(insertGeneralInfoStatement, 9, + Configuration::getInstance().TraceLength.value()/Configuration::getInstance().NumberOfTimeWindows); + executeSqlStatement(insertGeneralInfoStatement); } diff --git a/DRAMSys/simulator/src/common/TlmRecorder.h b/DRAMSys/simulator/src/common/TlmRecorder.h index 1f5e499a..d0c0ad49 100644 --- a/DRAMSys/simulator/src/common/TlmRecorder.h +++ b/DRAMSys/simulator/src/common/TlmRecorder.h @@ -69,7 +69,7 @@ public: void recordTracenames(string traces){this->traces = traces;} void recordPhase(tlm::tlm_generic_payload &trans, tlm::tlm_phase phase, sc_time time); - void recordPower(sc_time time, double averagePower); + void recordPower(double timeInSeconds, double averagePower); void recordDebugMessage(std::string message, sc_time time); void updateDataStrobe(const sc_time& begin, const sc_time& end, tlm::tlm_generic_payload& trans); void closeConnection(); diff --git a/DRAMSys/simulator/src/simulation/Dram.h b/DRAMSys/simulator/src/simulation/Dram.h index 47c7625e..98376ab8 100644 --- a/DRAMSys/simulator/src/simulation/Dram.h +++ b/DRAMSys/simulator/src/simulation/Dram.h @@ -204,7 +204,7 @@ struct Dram : sc_module double currentTotalEnergy = DRAMPower->getEnergy().total_energy - totalEnergy; double currentAveragePower = currentTotalEnergy/powerWindowSize.value(); sumOfEnergyWindows += currentTotalEnergy; - tlmRecorder->recordPower(sc_time_stamp(),currentAveragePower); + tlmRecorder->recordPower(sc_time_stamp().to_seconds(),currentAveragePower); totalEnergy = DRAMPower->getEnergy().total_energy; // Make sure that the summed energy of the windows is the same as the final value provided by DRAMPower: @@ -234,7 +234,7 @@ struct Dram : sc_module currentTotalEnergy = DRAMPower->getEnergy().total_energy - totalEnergy; currentAveragePower = currentTotalEnergy/powerWindowSize.value(); - tlmRecorder->recordPower(sc_time_stamp(),currentAveragePower); + tlmRecorder->recordPower(sc_time_stamp().to_seconds(),currentAveragePower); totalEnergy = DRAMPower->getEnergy().total_energy; sumOfEnergyWindows += currentTotalEnergy; From d359ed6ac31fa6459669134eb199831264d9017f Mon Sep 17 00:00:00 2001 From: Felipe Salerno Prado Date: Mon, 9 May 2016 15:24:27 +0200 Subject: [PATCH 4/8] ARM - DRAMSys Patch --- DRAMSys/simulator/src/simulation/Dram.h | 61 +++++++++++++------------ 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/DRAMSys/simulator/src/simulation/Dram.h b/DRAMSys/simulator/src/simulation/Dram.h index 98376ab8..4d1ac62d 100644 --- a/DRAMSys/simulator/src/simulation/Dram.h +++ b/DRAMSys/simulator/src/simulation/Dram.h @@ -89,7 +89,7 @@ struct Dram : sc_module if(powerAnalysis == true) { sc_time clk = Configuration::getInstance().memSpec.clk; - + MemArchitectureSpec memArchSpec; memArchSpec.burstLength = Configuration::getInstance().memSpec.BurstLength; memArchSpec.dataRate = Configuration::getInstance().memSpec.DataRate; @@ -162,7 +162,7 @@ struct Dram : sc_module memPowerSpec.vdd2 = Configuration::getInstance().memSpec.vDD2; MemorySpecification memSpec; - memSpec.memTimingSpec = memTimingSpec; + memSpec.memTimingSpec = memTimingSpec; memSpec.memPowerSpec = memPowerSpec; memSpec.memArchSpec = memArchSpec; @@ -192,58 +192,59 @@ struct Dram : sc_module ~Dram() { - if(powerAnalysis == true) - { + if (powerAnalysis == true) { + // Obtain the residual energy which was not covered by previous windows DRAMPower->updateCounters(true); DRAMPower->calcEnergy(); - // Calculate the residual power and energy which was not covered by previous windows... - printDebugMessage(string("\tCurrent Energy: \t") + to_string(DRAMPower->getEnergy().total_energy - totalEnergy)); - printDebugMessage(string("\tAverage Power: \t") + to_string((DRAMPower->getEnergy().total_energy - totalEnergy)/powerWindowSize.value())); + double energy = sumOfEnergyWindows + DRAMPower->getEnergy().total_energy; + double averagePower = energy / sc_time_stamp().to_seconds(); - double currentTotalEnergy = DRAMPower->getEnergy().total_energy - totalEnergy; - double currentAveragePower = currentTotalEnergy/powerWindowSize.value(); - sumOfEnergyWindows += currentTotalEnergy; - tlmRecorder->recordPower(sc_time_stamp().to_seconds(),currentAveragePower); - totalEnergy = DRAMPower->getEnergy().total_energy; + tlmRecorder->recordPower(sc_time_stamp().to_seconds(), averagePower); - // Make sure that the summed energy of the windows is the same as the final value provided by DRAMPower: - assert(sumOfEnergyWindows == totalEnergy); - - // Print Final Total Power Values: - cout << name() << string("\tTotal Energy: \t") + to_string(totalEnergy) << endl; - cout << name() << string("\tAverage Power: \t") + to_string(DRAMPower->getPower().average_power) << endl; + // Print Final Total Power Values + cout << name() << string("\tTotal Energy: \t") + to_string(energy) + string("\t[pJ]") << endl; + cout << name() << string("\tAverage Power: \t") + to_string(averagePower) + string("\t[pW]") << endl; } + // Clean up: for (auto e : ememory) { delete e; } - //std::cout << "Simulated Memory Size: " << memory.size() << endl; // TODO Aufrauemen } - + // This Thread is only triggered when Power Simulation is enabled. // It estimates the current average power which will be stored in the trace database for visualization purposes. void powerWindow() { double currentAveragePower = 0; double currentTotalEnergy = 0; + unsigned long long c = 0; do { + c = sc_time_stamp().value() / Configuration::getInstance().memSpec.clk.value(); + + DRAMPower->doCommand(MemCommand::NOP, 0, c); DRAMPower->updateCounters(false); DRAMPower->calcEnergy(); - currentTotalEnergy = DRAMPower->getEnergy().total_energy - totalEnergy; - currentAveragePower = currentTotalEnergy/powerWindowSize.value(); - tlmRecorder->recordPower(sc_time_stamp().to_seconds(),currentAveragePower); - totalEnergy = DRAMPower->getEnergy().total_energy; + currentTotalEnergy = DRAMPower->getEnergy().total_energy; + + //assert(currentTotalEnergy != 0); + + DRAMPower->clearCounters(c); + sumOfEnergyWindows += currentTotalEnergy; + // [pW] = [pJ] / [s] (here considering that DRAMPower provides the value always in pJ) + currentAveragePower = currentTotalEnergy / powerWindowSize.to_seconds(); + + tlmRecorder->recordPower(sc_time_stamp().to_seconds(), currentAveragePower); + + printDebugMessage(string("\tCurrent Energy: \t") + to_string(currentTotalEnergy) + string("\t[pJ]")); + printDebugMessage(string("\tAverage Power: \t") + to_string(currentAveragePower) + string("\t[pW]")); - printDebugMessage(string("\tCurrent Energy: \t") + to_string(currentTotalEnergy)); - printDebugMessage(string("\tAverage Power: \t") + to_string(currentAveragePower)); wait(powerWindowSize); - } - while(true); - + } while(true); } virtual tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload& payload, tlm::tlm_phase& phase, sc_time& delay) @@ -508,7 +509,7 @@ struct Dram : sc_module void setTlmRecorder(TlmRecorder *rec) { - tlmRecorder = rec; + tlmRecorder = rec; } }; From 87e2fce2e71c2db4df97cb7c7f2fd35394d3d783 Mon Sep 17 00:00:00 2001 From: Felipe Salerno Prado Date: Wed, 11 May 2016 14:04:29 +0200 Subject: [PATCH 5/8] Simulation Progress Bar --- .../resources/simulations/ddr3-example.xml | 1 + .../resources/simulations/sim-batch.xml | 1 + .../core/configuration/Configuration.cpp | 2 ++ .../core/configuration/Configuration.h | 1 + DRAMSys/simulator/src/simulation/Simulation.cpp | 16 ++++++++++++++++ DRAMSys/simulator/src/simulation/Simulation.h | 4 ++++ DRAMSys/simulator/src/simulation/StlDataPlayer.h | 13 +++++++++++++ DRAMSys/simulator/src/simulation/StlPlayer.h | 12 ++++++++++++ DRAMSys/simulator/src/simulation/TracePlayer.h | 6 +++++- .../src/simulation/TracePlayerListener.h | 1 + README.md | 6 ++++++ 11 files changed, 62 insertions(+), 1 deletion(-) diff --git a/DRAMSys/simulator/resources/simulations/ddr3-example.xml b/DRAMSys/simulator/resources/simulations/ddr3-example.xml index 0df2e1c7..776656ce 100644 --- a/DRAMSys/simulator/resources/simulations/ddr3-example.xml +++ b/DRAMSys/simulator/resources/simulations/ddr3-example.xml @@ -9,6 +9,7 @@ + diff --git a/DRAMSys/simulator/resources/simulations/sim-batch.xml b/DRAMSys/simulator/resources/simulations/sim-batch.xml index aaaba0a9..3ea21963 100644 --- a/DRAMSys/simulator/resources/simulations/sim-batch.xml +++ b/DRAMSys/simulator/resources/simulations/sim-batch.xml @@ -9,6 +9,7 @@ + diff --git a/DRAMSys/simulator/src/controller/core/configuration/Configuration.cpp b/DRAMSys/simulator/src/controller/core/configuration/Configuration.cpp index 975cc7a0..04ef17da 100644 --- a/DRAMSys/simulator/src/controller/core/configuration/Configuration.cpp +++ b/DRAMSys/simulator/src/controller/core/configuration/Configuration.cpp @@ -163,6 +163,8 @@ void Configuration::setParameter(std::string name, std::string value) ControllerCoreDisableRefresh = string2bool(value); else if (name == "ThermalSimulation") ThermalSimulation = string2bool(value); + else if(name == "SimulationProgressBar") + SimulationProgressBar = string2bool(value); // Specification for ErrorChipSeed, ErrorCSVFile path and ErrorStoreMode 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 450e7bde..6c27b786 100644 --- a/DRAMSys/simulator/src/controller/core/configuration/Configuration.h +++ b/DRAMSys/simulator/src/controller/core/configuration/Configuration.h @@ -82,6 +82,7 @@ struct Configuration unsigned int NumberOfMemChannels = 1; bool ControllerCoreDisableRefresh = false; bool ThermalSimulation = false; + bool SimulationProgressBar; //MemSpec(from DRAM-Power XML) MemSpec memSpec; diff --git a/DRAMSys/simulator/src/simulation/Simulation.cpp b/DRAMSys/simulator/src/simulation/Simulation.cpp index 750439db..b22216c8 100644 --- a/DRAMSys/simulator/src/simulation/Simulation.cpp +++ b/DRAMSys/simulator/src/simulation/Simulation.cpp @@ -124,15 +124,20 @@ void Simulation::instantiateModules(const string &traceName, const string &pathT StlPlayer<> *newPlayer = new StlPlayer<>(playerStr.c_str(), pathToResources + string("traces/") + devices[i].trace, devices[i].clkMhz, this); player = newPlayer; newPlayer->getTraceLength(pathToResources + string("traces/") + devices[i].trace); + totalTransactions += newPlayer->getNumberOfLines(pathToResources + string("traces/") + devices[i].trace); } else { StlDataPlayer<> *newPlayer = new StlDataPlayer<>(playerStr.c_str(), pathToResources + string("traces/") + devices[i].trace, devices[i].clkMhz, this); player = newPlayer; newPlayer->getTraceLength(pathToResources + string("traces/") + devices[i].trace); + totalTransactions += newPlayer->getNumberOfLines(pathToResources + string("traces/") + devices[i].trace); } players.push_back(player); } + remainingTransactions = totalTransactions; + + //player->remainingTransactions = player->totalTransactions; // Create and properly initialize TLM recorders. They need to be ready before creating some modules. setupTlmRecorders(traceName, pathToResources, devices); @@ -228,6 +233,17 @@ void Simulation::stop() report("Simulation took " + to_string(elapsed_secs) + " seconds"); } + +void inline Simulation::transactionFinished() +{ + remainingTransactions--; + loadbar(totalTransactions - remainingTransactions, totalTransactions); + if (remainingTransactions == 0) + { + cout << endl; + } +} + void Simulation::report(string message) { DebugManager::getInstance().printDebugMessage(this->name(), message); diff --git a/DRAMSys/simulator/src/simulation/Simulation.h b/DRAMSys/simulator/src/simulation/Simulation.h index 0721c763..3b5d24fb 100644 --- a/DRAMSys/simulator/src/simulation/Simulation.h +++ b/DRAMSys/simulator/src/simulation/Simulation.h @@ -86,6 +86,7 @@ public: void stop(); virtual void tracePlayerTerminates() override; + virtual void transactionFinished() override; private: std::string traceName; @@ -107,6 +108,9 @@ private: // Transaction Recorders (one per channel). They generate the output databases. std::vector tlmRecorders; + unsigned int totalTransactions = 0; + unsigned int remainingTransactions; + clock_t simulationStartTime; void report(std::string message); void setupTlmRecorders(const string &traceName, const string &pathToResources, const std::vector &devices); diff --git a/DRAMSys/simulator/src/simulation/StlDataPlayer.h b/DRAMSys/simulator/src/simulation/StlDataPlayer.h index 06c253d7..8c29b30b 100644 --- a/DRAMSys/simulator/src/simulation/StlDataPlayer.h +++ b/DRAMSys/simulator/src/simulation/StlDataPlayer.h @@ -177,6 +177,19 @@ public: } + unsigned int getNumberOfLines(string pathToTrace) + { + ifstream newFile; + newFile.open(pathToTrace); + newFile.unsetf(std::ios_base::skipws); // new lines will be skipped unless we stop it from happening: + // count the newlines with an algorithm specialized for counting: + unsigned int lineCount = std::count(std::istream_iterator(newFile), std::istream_iterator(), '\n'); + + newFile.close(); + return lineCount; + } + + private: ifstream file; diff --git a/DRAMSys/simulator/src/simulation/StlPlayer.h b/DRAMSys/simulator/src/simulation/StlPlayer.h index 92038aad..809a4da7 100644 --- a/DRAMSys/simulator/src/simulation/StlPlayer.h +++ b/DRAMSys/simulator/src/simulation/StlPlayer.h @@ -165,6 +165,18 @@ public: } + unsigned int getNumberOfLines(string pathToTrace) + { + ifstream newFile; + newFile.open(pathToTrace); + newFile.unsetf(std::ios_base::skipws); // new lines will be skipped unless we stop it from happening: + // count the newlines with an algorithm specialized for counting: + unsigned int lineCount = std::count(std::istream_iterator(newFile), std::istream_iterator(), '\n'); + + newFile.close(); + return lineCount; + } + private: ifstream file; diff --git a/DRAMSys/simulator/src/simulation/TracePlayer.h b/DRAMSys/simulator/src/simulation/TracePlayer.h index 7a6d4523..6a8e90ef 100644 --- a/DRAMSys/simulator/src/simulation/TracePlayer.h +++ b/DRAMSys/simulator/src/simulation/TracePlayer.h @@ -51,6 +51,7 @@ #include "../common/dramExtension.h" #include "../controller/core/TimingCalculation.h" #include "TracePlayerListener.h" +#include "Simulation.h" using namespace std; using namespace tlm; @@ -96,7 +97,7 @@ gp *TracePlayer::allocatePayload() template void TracePlayer::terminate() { - cout << sc_time_stamp() << " " << this->name() << " terminated" << std::endl; + cout << sc_time_stamp() << " " << this->name() << " terminated " << std::endl; listener->tracePlayerTerminates(); } @@ -159,6 +160,9 @@ void TracePlayer::peqCallback(tlm_generic_payload &payload, const tlm_ sendToTarget(payload, END_RESP, SC_ZERO_TIME); payload.release(); + if(Configuration::getInstance().SimulationProgressBar) + listener->transactionFinished(); + } else if (phase == END_RESP) { diff --git a/DRAMSys/simulator/src/simulation/TracePlayerListener.h b/DRAMSys/simulator/src/simulation/TracePlayerListener.h index 36a0cdd5..95c52773 100644 --- a/DRAMSys/simulator/src/simulation/TracePlayerListener.h +++ b/DRAMSys/simulator/src/simulation/TracePlayerListener.h @@ -42,6 +42,7 @@ class TracePlayerListener { public: virtual void tracePlayerTerminates() = 0; + virtual void transactionFinished() = 0; }; #endif // TRACEPLAYERLISTENER_H diff --git a/README.md b/README.md index 8e841423..1b7cec18 100644 --- a/README.md +++ b/README.md @@ -324,6 +324,7 @@ The DRAMSys' main configuration file is presented below. + @@ -423,6 +424,7 @@ The XML code below shows a typic configuration: + @@ -542,6 +544,10 @@ Below are listed the configuration sections and configuration fields. - *ThermalSimulation* (boolean) - "1": enables thermal simulation - "0": static temperature during simulation + - *SimulationProgressBar* (boolean) + - "1": enables the simulation progress bar + - "0": disables the simulation progress bar + - **Temperature Simulator Configuration** - *TemperatureScale* (string) From fb5a49224af1e9564c6849a6a3fdda80a5829607 Mon Sep 17 00:00:00 2001 From: Felipe Salerno Prado Date: Wed, 11 May 2016 14:07:15 +0200 Subject: [PATCH 6/8] Simulation Progress Bar --- DRAMSys/simulator/src/simulation/TracePlayer.h | 1 - README.md | 1 - 2 files changed, 2 deletions(-) diff --git a/DRAMSys/simulator/src/simulation/TracePlayer.h b/DRAMSys/simulator/src/simulation/TracePlayer.h index 6a8e90ef..070b8127 100644 --- a/DRAMSys/simulator/src/simulation/TracePlayer.h +++ b/DRAMSys/simulator/src/simulation/TracePlayer.h @@ -51,7 +51,6 @@ #include "../common/dramExtension.h" #include "../controller/core/TimingCalculation.h" #include "TracePlayerListener.h" -#include "Simulation.h" using namespace std; using namespace tlm; diff --git a/README.md b/README.md index 1b7cec18..a85fa5cd 100644 --- a/README.md +++ b/README.md @@ -548,7 +548,6 @@ Below are listed the configuration sections and configuration fields. - "1": enables the simulation progress bar - "0": disables the simulation progress bar - - **Temperature Simulator Configuration** - *TemperatureScale* (string) - "Celsius" From 1bbce84a5fcee75df12b9d4f40a338fa08fc9a32 Mon Sep 17 00:00:00 2001 From: sprado Date: Thu, 19 May 2016 15:28:27 +0200 Subject: [PATCH 7/8] Issue #76 fixed and some improvements --- DRAMSys/analyzer/scripts/plots.py | 8 +- .../src/controller/core/ControllerCore.cpp | 10 +- .../core/refresh/RefreshManager.cpp | 2 +- .../scheduling/checker/RefreshChecker.cpp | 92 ++++++++++++++----- DRAMSys/simulator/src/simulation/Dram.h | 3 +- 5 files changed, 81 insertions(+), 34 deletions(-) diff --git a/DRAMSys/analyzer/scripts/plots.py b/DRAMSys/analyzer/scripts/plots.py index cae5f80d..1bf18b7e 100644 --- a/DRAMSys/analyzer/scripts/plots.py +++ b/DRAMSys/analyzer/scripts/plots.py @@ -117,10 +117,12 @@ def power_window(connection, tracePath): cursor.execute(""" SELECT * FROM Power """) time = [0] * (steps+1) power = [0] * (steps+1) - for i in range((steps+1)): + time[0] = 0 + power[0] = 0 + for i in range((steps)): result = cursor.fetchone() - time[i] = float(result[0])*1000000000 - power[i] = float(result[1])/1000000000 + time[i+1] = float(result[0])*1000000000 + power[i+1] = float(result[1])/1000000000 name = ntpath.basename(tracePath) basename, extension = os.path.splitext(name) diff --git a/DRAMSys/simulator/src/controller/core/ControllerCore.cpp b/DRAMSys/simulator/src/controller/core/ControllerCore.cpp index f18c1630..92c74966 100644 --- a/DRAMSys/simulator/src/controller/core/ControllerCore.cpp +++ b/DRAMSys/simulator/src/controller/core/ControllerCore.cpp @@ -139,11 +139,13 @@ void ControllerCore::triggerRefresh(tlm::tlm_generic_payload& payload) void ControllerCore::scheduleRequest(Command command, tlm::tlm_generic_payload &payload) { sc_time start = clkAlign(sc_time_stamp()); - state->cleanUp(start); - ScheduledCommand scheduledCommand = schedule(command, start, payload); - state->change(scheduledCommand); - controller.send(scheduledCommand, payload); + if(!(command == Command::Precharge && refreshManager->hasCollision(scheduledCommand))) + { + state->cleanUp(start); + state->change(scheduledCommand); + controller.send(scheduledCommand, payload); + } } ScheduledCommand ControllerCore::schedule(Command command, sc_time start, diff --git a/DRAMSys/simulator/src/controller/core/refresh/RefreshManager.cpp b/DRAMSys/simulator/src/controller/core/refresh/RefreshManager.cpp index c3acac16..d2049f2f 100644 --- a/DRAMSys/simulator/src/controller/core/refresh/RefreshManager.cpp +++ b/DRAMSys/simulator/src/controller/core/refresh/RefreshManager.cpp @@ -58,7 +58,7 @@ RefreshManager::~RefreshManager() bool RefreshManager::hasCollision(const ScheduledCommand& command) { - return command.getStart() < controllerCore.state->getLastCommand(Command::AutoRefresh).getEnd() || command.getEnd() > nextPlannedRefresh; + return command.getStart() < controllerCore.state->getLastCommand(Command::AutoRefresh).getEnd() || command.getEnd() >= nextPlannedRefresh; } void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload& payload __attribute__((unused)), sc_time time) diff --git a/DRAMSys/simulator/src/controller/core/scheduling/checker/RefreshChecker.cpp b/DRAMSys/simulator/src/controller/core/scheduling/checker/RefreshChecker.cpp index ffc8ebfa..3978253e 100644 --- a/DRAMSys/simulator/src/controller/core/scheduling/checker/RefreshChecker.cpp +++ b/DRAMSys/simulator/src/controller/core/scheduling/checker/RefreshChecker.cpp @@ -37,45 +37,87 @@ #include "RefreshChecker.h" #include "../../TimingCalculation.h" - - void RefreshChecker::delayToSatisfyConstraints(ScheduledCommand& command) const { sc_assert(command.getCommand() == Command::AutoRefresh); - ScheduledCommand lastCommandOnBank = state.getLastScheduledCommand(command.getBank()); - - if (lastCommandOnBank.isValidCommand()) + if(config.BankwiseLogic) { - if (lastCommandOnBank.getCommand() == Command::Precharge || lastCommandOnBank.getCommand() == Command::PrechargeAll) + ScheduledCommand lastCommandOnBank = state.getLastScheduledCommand(command.getBank()); + + if (lastCommandOnBank.isValidCommand()) { - command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tRP); + if (lastCommandOnBank.getCommand() == Command::Precharge || lastCommandOnBank.getCommand() == Command::PrechargeAll) + { + command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tRP); + } + else if (lastCommandOnBank.getCommand() == Command::ReadA) + { + command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tRTP + config.memSpec.tRP); + } + else if (lastCommandOnBank.getCommand() == Command::WriteA) + { + command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), + config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR + config.memSpec.tRP); + } + else if (lastCommandOnBank.getCommand() == Command::PDNPX || lastCommandOnBank.getCommand() == Command::PDNAX) + { + command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tXP); + } + else if (lastCommandOnBank.getCommand() == Command::SREFX) + { + command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tXSR); + } + else if (lastCommandOnBank.getCommand() == Command::AutoRefresh) + { + } + else + reportFatal("Refresh Checker", "Refresh can not follow " + commandToString(lastCommandOnBank.getCommand())); } - else if (lastCommandOnBank.getCommand() == Command::ReadA) + } + else + { + for (unsigned int bank = 0; bank < config.memSpec.NumberOfBanks; ++bank) { - command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tRTP + config.memSpec.tRP); - } - else if (lastCommandOnBank.getCommand() == Command::WriteA) - { - command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), - config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR + config.memSpec.tRP); - } - else if (lastCommandOnBank.getCommand() == Command::PDNPX || lastCommandOnBank.getCommand() == Command::PDNAX) - { - command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tXP); - } - else if (lastCommandOnBank.getCommand() == Command::SREFX) + ScheduledCommand lastCommand = state.getLastScheduledCommand(Bank(bank)); + if (lastCommand.isValidCommand()) + { + if(lastCommand.getCommand() == Command::Precharge || lastCommand.getCommand() == Command::PrechargeAll) { - command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), config.memSpec.tXSR); + command.establishMinDistanceFromStart(lastCommand.getStart(), config.memSpec.tRP); } - else if (lastCommandOnBank.getCommand() == Command::AutoRefresh) - { + else if(lastCommand.getCommand() == Command::Activate) + { + command.establishMinDistanceFromStart(lastCommand.getStart(), config.memSpec.tRCD); + } + else if (lastCommand.getCommand() == Command::ReadA) + { + command.establishMinDistanceFromStart(lastCommand.getStart(), config.memSpec.tRTP + config.memSpec.tRP); + } + else if(lastCommand.getCommand() == Command::WriteA) + { + command.establishMinDistanceFromStart(lastCommand.getStart(), config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR + config.memSpec.tRP); + } + else if (lastCommand.getCommand() == Command::PDNAX || lastCommand.getCommand() == Command::PDNPX) + { + command.establishMinDistanceFromStart(lastCommand.getStart(), config.memSpec.tXP); + } + else if (lastCommand.getCommand() == Command::SREFX) + { + command.establishMinDistanceFromStart(lastCommand.getEnd(), config.memSpec.tXSR); + } + else if (lastCommand.getCommand() == Command::AutoRefresh) + { + } + else + reportFatal("Refresh Checker", "Refresh can not follow " + commandToString(lastCommand.getCommand())); + } } - else - reportFatal("Refresh Checker", "Refresh can not follow " + commandToString(lastCommandOnBank.getCommand())); } state.bus.moveCommandToNextFreeSlot(command); + + } diff --git a/DRAMSys/simulator/src/simulation/Dram.h b/DRAMSys/simulator/src/simulation/Dram.h index 4d1ac62d..ec930a65 100644 --- a/DRAMSys/simulator/src/simulation/Dram.h +++ b/DRAMSys/simulator/src/simulation/Dram.h @@ -222,6 +222,8 @@ struct Dram : sc_module unsigned long long c = 0; do { + wait(powerWindowSize); + c = sc_time_stamp().value() / Configuration::getInstance().memSpec.clk.value(); DRAMPower->doCommand(MemCommand::NOP, 0, c); @@ -243,7 +245,6 @@ struct Dram : sc_module printDebugMessage(string("\tCurrent Energy: \t") + to_string(currentTotalEnergy) + string("\t[pJ]")); printDebugMessage(string("\tAverage Power: \t") + to_string(currentAveragePower) + string("\t[pW]")); - wait(powerWindowSize); } while(true); } From 212b39e1a8e90e2a4d5415e3b116e5b9cde44bf6 Mon Sep 17 00:00:00 2001 From: Felipe Salerno Prado Date: Thu, 19 May 2016 16:32:46 +0200 Subject: [PATCH 8/8] More Improvements --- DRAMSys/analyzer/scripts/plots.py | 2 +- .../src/controller/core/ControllerCore.cpp | 4 ++-- DRAMSys/simulator/src/simulation/Dram.h | 20 ++++++++++--------- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/DRAMSys/analyzer/scripts/plots.py b/DRAMSys/analyzer/scripts/plots.py index 1bf18b7e..1713a4ae 100644 --- a/DRAMSys/analyzer/scripts/plots.py +++ b/DRAMSys/analyzer/scripts/plots.py @@ -122,7 +122,7 @@ def power_window(connection, tracePath): for i in range((steps)): result = cursor.fetchone() time[i+1] = float(result[0])*1000000000 - power[i+1] = float(result[1])/1000000000 + power[i+1] = float(result[1]) name = ntpath.basename(tracePath) basename, extension = os.path.splitext(name) diff --git a/DRAMSys/simulator/src/controller/core/ControllerCore.cpp b/DRAMSys/simulator/src/controller/core/ControllerCore.cpp index 92c74966..e8c079f5 100644 --- a/DRAMSys/simulator/src/controller/core/ControllerCore.cpp +++ b/DRAMSys/simulator/src/controller/core/ControllerCore.cpp @@ -139,10 +139,10 @@ void ControllerCore::triggerRefresh(tlm::tlm_generic_payload& payload) void ControllerCore::scheduleRequest(Command command, tlm::tlm_generic_payload &payload) { sc_time start = clkAlign(sc_time_stamp()); + state->cleanUp(start); ScheduledCommand scheduledCommand = schedule(command, start, payload); if(!(command == Command::Precharge && refreshManager->hasCollision(scheduledCommand))) - { - state->cleanUp(start); + { state->change(scheduledCommand); controller.send(scheduledCommand, payload); } diff --git a/DRAMSys/simulator/src/simulation/Dram.h b/DRAMSys/simulator/src/simulation/Dram.h index ec930a65..3a2518a9 100644 --- a/DRAMSys/simulator/src/simulation/Dram.h +++ b/DRAMSys/simulator/src/simulation/Dram.h @@ -197,14 +197,15 @@ struct Dram : sc_module DRAMPower->updateCounters(true); DRAMPower->calcEnergy(); - double energy = sumOfEnergyWindows + DRAMPower->getEnergy().total_energy; - double averagePower = energy / sc_time_stamp().to_seconds(); + double totalEnergy = sumOfEnergyWindows + DRAMPower->getEnergy().total_energy; + // The energy is given in [pJ] and divided by [s] resulting in [pW] then converted to [mW] + double averagePower = (totalEnergy / sc_time_stamp().to_seconds()) / 1e9; - tlmRecorder->recordPower(sc_time_stamp().to_seconds(), averagePower); + tlmRecorder->recordPower(sc_time_stamp().to_seconds(), DRAMPower->getPower().average_power); - // Print Final Total Power Values - cout << name() << string("\tTotal Energy: \t") + to_string(energy) + string("\t[pJ]") << endl; - cout << name() << string("\tAverage Power: \t") + to_string(averagePower) + string("\t[pW]") << endl; + // Print the final total energy and the average power for the simulation + cout << name() << string("\tTotal Energy: \t") + to_string(totalEnergy) + string("\t[pJ]") << endl; + cout << name() << string("\tAverage Power: \t") + to_string(averagePower) + string("\t[mW]") << endl; } // Clean up: @@ -231,19 +232,20 @@ struct Dram : sc_module DRAMPower->calcEnergy(); currentTotalEnergy = DRAMPower->getEnergy().total_energy; + currentAveragePower = DRAMPower->getPower().average_power; //assert(currentTotalEnergy != 0); DRAMPower->clearCounters(c); sumOfEnergyWindows += currentTotalEnergy; - // [pW] = [pJ] / [s] (here considering that DRAMPower provides the value always in pJ) - currentAveragePower = currentTotalEnergy / powerWindowSize.to_seconds(); + // Store the time (in seconds) and the current average power (in mW) into the database tlmRecorder->recordPower(sc_time_stamp().to_seconds(), currentAveragePower); + // Here considering that DRAMPower provides the energy in pJ and the power in mW printDebugMessage(string("\tCurrent Energy: \t") + to_string(currentTotalEnergy) + string("\t[pJ]")); - printDebugMessage(string("\tAverage Power: \t") + to_string(currentAveragePower) + string("\t[pW]")); + printDebugMessage(string("\tAverage Power: \t") + to_string(currentAveragePower) + string("\t[mW]")); } while(true); }