From a88d17976a0462d82b737de2080c4007c0c656d8 Mon Sep 17 00:00:00 2001 From: Felipe Salerno Prado Date: Mon, 9 May 2016 14:45:06 +0200 Subject: [PATCH] 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;