From d4804225cb7f1179c05e7746086b4607918130c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89der=20F=2E=20Zulian?= Date: Thu, 2 Aug 2018 20:30:53 +0200 Subject: [PATCH] [DRAMSylva]: New metrics added. Other changes: - PEP8 --- DRAMSys/traceAnalyzer/scripts/memUtil.py | 3 + DRAMSys/traceAnalyzer/scripts/plots.py | 26 +++++--- DRAMSys/traceAnalyzer/scripts/tests.py | 75 ++++++++++++------------ 3 files changed, 58 insertions(+), 46 deletions(-) diff --git a/DRAMSys/traceAnalyzer/scripts/memUtil.py b/DRAMSys/traceAnalyzer/scripts/memUtil.py index 4a11df45..7ca5f07f 100755 --- a/DRAMSys/traceAnalyzer/scripts/memUtil.py +++ b/DRAMSys/traceAnalyzer/scripts/memUtil.py @@ -91,12 +91,14 @@ def getMaxRefBurst(connection): result = cursor.fetchone() return result[0] + def getControllerThread(connection): cursor = connection.cursor() cursor.execute("SELECT ControllerThread FROM GeneralInfo") result = cursor.fetchone() return result[0] + def get_phase_occurrences(connection, phase): cursor = connection.cursor() query = "select count(*) from Phases where PhaseName = :phase" @@ -107,6 +109,7 @@ def get_phase_occurrences(connection, phase): cnt = 0 return cnt + def get_total_time_in_phase(connection, phase): cursor = connection.cursor() query = "select sum(PhaseEnd - PhaseBegin) / 1000 from Phases where PhaseName = :phase" diff --git a/DRAMSys/traceAnalyzer/scripts/plots.py b/DRAMSys/traceAnalyzer/scripts/plots.py index b745f5af..aefb1235 100755 --- a/DRAMSys/traceAnalyzer/scripts/plots.py +++ b/DRAMSys/traceAnalyzer/scripts/plots.py @@ -9,6 +9,7 @@ latencyRange = None plots = [] + def getThreads(connection): cursor = connection.cursor() cursor.execute("SELECT DISTINCT(TThread) FROM transactions WHERE TThread != 0 ORDER BY TThread") @@ -17,12 +18,14 @@ def getThreads(connection): result.append(currentRow[0]) return result + def createOutputFilename(tracePath, plot_type, target_measurement, file_type): name = ntpath.basename(tracePath) basename, extension = os.path.splitext(name) outputFileName = plot_type + '_' + target_measurement + basename + '.' + file_type return outputFileName, target_measurement + basename + def accessDatabase(connection, query): cursor = connection.cursor() # cursor.execute(" ") @@ -36,6 +39,7 @@ def accessDatabase(connection, query): break return resultArray + def calculate_bandwidth_util(connection, windowSize, steps, queryFull, queryEnd, queryBegin, queryPart): cursor = connection.cursor() maxDataRate = maximum_data_rate(connection) @@ -71,6 +75,7 @@ def calculate_bandwidth_util(connection, windowSize, steps, queryFull, queryEnd, return bandwidthPercentage, bandwidth, maximumPercentage + def memory_utilisation_window_thread(connection, tracePath, steps, thread_ID): # All possible cases of data transfers inside a time window queryFull = """ SELECT sum(DataStrobeEnd - DataStrobeBegin) FROM transactions Where DataStrobeBegin >= ? and DataStrobeEnd <= ? and TThread = {0}""" # The data transfer begins and ends inside the time window @@ -90,10 +95,12 @@ def memory_utilisation_window_thread(connection, tracePath, steps, thread_ID): outputFileNameBWMatlab, basename = createOutputFilename(tracePath, 'memory_utilization_percent', 'thread_' + str(thread_ID) + '_', 'txt') return bandwidthPercentage, bandwidth, outputFileNameBWMatlab + def plot(function): plots.append(function) return function + @plot def memory_utilisation_window(connection, tracePath, steps): # This function determines the average memory bandwidth over time in @@ -122,13 +129,13 @@ def memory_utilisation_window(connection, tracePath, steps): outputFileNameGBPS, basename = createOutputFilename(tracePath, 'memory_utilization_gbps', '', 'pdf') outputFileNamePercent, basename = createOutputFilename(tracePath, 'memory_utilization_percent', '', 'pdf') outputFileNameBWMatlab, basename = createOutputFilename(tracePath, 'memory_utilization_percent', '', 'txt') - outputFiles = "{0}\n\t{1}\n\t{2}\n\t".format(outputFileNameGBPS,outputFileNamePercent,outputFileNameBWMatlab) + outputFiles = "{0}\n\t{1}\n\t{2}\n\t".format(outputFileNameGBPS, outputFileNamePercent, outputFileNameBWMatlab) import matplotlib.pyplot as plt import numpy as np from matplotlib.backends.backend_pdf import PdfPages - #windowSize/1000: picoseconds to nanoseconds conversion + # windowSize/1000: picoseconds to nanoseconds conversion time = np.arange(0, (steps+1)*windowSize/1000, windowSize/1000) maxBandwidth = [maxDataRate/1024] * (steps+1) @@ -137,13 +144,12 @@ def memory_utilisation_window(connection, tracePath, steps): line = "{} {}\n".format(time[i], bandwidthPercentage[i]) f.write(line) - # Plot Bandwidth in Percent BWPercentageFigure = plt.figure() BWPercentageFigurePlot = BWPercentageFigure.add_subplot(111) BWPercentageFigurePlot.set_xlabel('Time [ns]') BWPercentageFigurePlot.set_ylabel('Bandwidth [%]') - BWPercentageFigurePlot.set_ylim(-1, maximumPercentage + (10 - maximumPercentage%10)) + BWPercentageFigurePlot.set_ylim(-1, maximumPercentage + (10 - maximumPercentage % 10)) BWPercentageFigurePlot.set_title('Memory Utilization in % ' + str(basename)) BWPercentageFigurePlot.grid(True) BWPercentageFigurePlot.plot(time, bandwidthPercentage, label='Total') @@ -190,6 +196,7 @@ def memory_utilisation_window(connection, tracePath, steps): return outputFiles + @plot def power_window(connection, tracePath, steps): @@ -201,8 +208,8 @@ def power_window(connection, tracePath, steps): cursor.execute(" SELECT * FROM Power") import numpy as np - window = float(windowSize) / pow(10,12) - time = np.arange(0, (windowSize*(steps+1))/pow(10,6), windowSize/pow(10,6)) + window = float(windowSize) / pow(10, 12) + time = np.arange(0, (windowSize * (steps + 1)) / pow(10, 6), windowSize / pow(10, 6)) power = np.full(len(time), 0) for i in range(steps): @@ -229,7 +236,7 @@ def power_window(connection, tracePath, steps): import matplotlib.pyplot as plt from matplotlib.backends.backend_pdf import PdfPages - PowFigure = plt.figure(figsize=(10,5), dpi=300) + PowFigure = plt.figure(figsize=(10, 5), dpi=300) PowFigurePlot = PowFigure.add_subplot(111) PowFigurePlot.set_xlabel('Time [us]') PowFigurePlot.set_ylabel('Power [mW]') @@ -245,6 +252,7 @@ def power_window(connection, tracePath, steps): return outputFile + @plot def latency_histogram(connection, tracePath, steps): # This function plots an histogram with access latencys @@ -333,7 +341,7 @@ def generatePlots(pathToTrace): if __name__ == "__main__": path = sys.argv[1] if ((len(sys.argv)) > 2): - latencyRange = (0, int(sys.argv[2])) # Optional argument to use a different range + latencyRange = (0, int(sys.argv[2])) # Optional argument to use a different range if ((len(sys.argv)) > 3): - numberOfBins = int(sys.argv[3]) # Optional argument to use a different number of bins + numberOfBins = int(sys.argv[3]) # Optional argument to use a different number of bins generatePlots(path) diff --git a/DRAMSys/traceAnalyzer/scripts/tests.py b/DRAMSys/traceAnalyzer/scripts/tests.py index a954693f..27cb71a5 100755 --- a/DRAMSys/traceAnalyzer/scripts/tests.py +++ b/DRAMSys/traceAnalyzer/scripts/tests.py @@ -121,30 +121,30 @@ class DramConfig(object): elif (self. memoryType == "DDR3"): self.nActivateWindow = 4 - self.tRP = self.clk * memspec.getIntValue("RP"); - self.tRAS = self.clk * memspec.getIntValue("RAS"); - self.tRC = self.clk * memspec.getIntValue("RC"); - self.tRTP = self.clk * memspec.getIntValue("RTP"); - self.tRRD_S = self.clk * memspec.getIntValue("RRD"); - self.tRRD_L = self.clk * memspec.getIntValue("RRD"); - self.tCCD_S = self.clk * memspec.getIntValue("CCD"); - self.tCCD_L = self.clk * memspec.getIntValue("CCD"); - self.tRCD = self.clk * memspec.getIntValue("RCD"); - self.tNAW = self.clk * memspec.getIntValue("FAW"); - self.tRL = self.clk * memspec.getIntValue("RL"); - self.tWL = self.clk * memspec.getIntValue("WL"); - self.tWR = self.clk * memspec.getIntValue("WR"); - self.tWTR_S = self.clk * memspec.getIntValue("WTR"); - self.tWTR_L = self.clk * memspec.getIntValue("WTR"); - self.tCKESR = self.clk * memspec.getIntValue("CKESR"); - self.tCKE = self.clk * memspec.getIntValue("CKE"); - self.tXP = self.clk * memspec.getIntValue("XP"); - self.tXPDLL = self.clk * memspec.getIntValue("XPDLL"); - self.tXSR = self.clk * memspec.getIntValue("XS"); - self.tXSRDLL = self.clk * memspec.getIntValue("XSDLL"); - self.tAL = self.clk * memspec.getIntValue("AL"); - self.tRFC = self.clk * memspec.getIntValue("RFC"); - self.tREFI = self.clk * memspec.getIntValue("REFI"); + self.tRP = self.clk * memspec.getIntValue("RP") + self.tRAS = self.clk * memspec.getIntValue("RAS") + self.tRC = self.clk * memspec.getIntValue("RC") + self.tRTP = self.clk * memspec.getIntValue("RTP") + self.tRRD_S = self.clk * memspec.getIntValue("RRD") + self.tRRD_L = self.clk * memspec.getIntValue("RRD") + self.tCCD_S = self.clk * memspec.getIntValue("CCD") + self.tCCD_L = self.clk * memspec.getIntValue("CCD") + self.tRCD = self.clk * memspec.getIntValue("RCD") + self.tNAW = self.clk * memspec.getIntValue("FAW") + self.tRL = self.clk * memspec.getIntValue("RL") + self.tWL = self.clk * memspec.getIntValue("WL") + self.tWR = self.clk * memspec.getIntValue("WR") + self.tWTR_S = self.clk * memspec.getIntValue("WTR") + self.tWTR_L = self.clk * memspec.getIntValue("WTR") + self.tCKESR = self.clk * memspec.getIntValue("CKESR") + self.tCKE = self.clk * memspec.getIntValue("CKE") + self.tXP = self.clk * memspec.getIntValue("XP") + self.tXPDLL = self.clk * memspec.getIntValue("XPDLL") + self.tXSR = self.clk * memspec.getIntValue("XS") + self.tXSRDLL = self.clk * memspec.getIntValue("XSDLL") + self.tAL = self.clk * memspec.getIntValue("AL") + self.tRFC = self.clk * memspec.getIntValue("RFC") + self.tREFI = self.clk * memspec.getIntValue("REFI") else: raise Exception("MemoryType not supported yet. Insert a coin into the coin machine and try again") @@ -157,10 +157,9 @@ class DramConfig(object): return self.clk*(self.burstLength - 1) elif (self.memoryType == "DDR4"): return self.clk*self.burstLength/self.dataRate - else: #DEFAULT + else: # DEFAULT return self.clk*self.burstLength/self.dataRate - def getReadAccessTime(self): return self.burstLength/self.dataRate * dramconfig.clk @@ -386,7 +385,6 @@ def timing_constraits_on_the_same_bank_hold(connection): cursor = connection.cursor() validTransitions = {} - if (dramconfig.bankwiseLogic == "1"): query = """SELECT PhaseName, phases.ID, PhaseBegin, PhaseEnd FROM phases INNER JOIN transactions ON phases.transact=transactions.ID WHERE TBank=:bank AND PhaseName NOT IN ('REQ','RESP') ORDER BY PhaseBegin""" @@ -472,19 +470,20 @@ def no_commands_during_refresh(connection): query = """SELECT PhaseBegin, PhaseEnd FROM phases WHERE PhaseName = 'REFA' """ test_query = """SELECT PhaseName FROM phases WHERE ((PhaseBegin >= ? and PhaseEnd <= ?) or (PhaseBegin <= ? and PhaseEnd > ?) or (PhaseBegin < ? and PhaseEnd >= ?)) and PhaseName NOT IN ('REQ','RESP','REFA')""" - cursor.execute(query); - result = cursor.fetchall(); + cursor.execute(query) + result = cursor.fetchall() for row in result: if(dramconfig.bankwiseLogic == "1"): cursor.execute(test_query, (row[0], row[1], row[0], row[0], row[1], row[1], row[2])) else: cursor.execute(test_query, (row[0], row[1], row[0], row[0], row[1], row[1])) - test = cursor.fetchone(); + test = cursor.fetchone() if(test is not None): return TestFailed("A Command {0} was scheduled during a refresh period".format(test[0])) return TestSuceeded() + @test def max_number_ref_burst(connection): """Checks that the maximum number of REFA commands in a burst is not exceeded""" @@ -495,23 +494,24 @@ def max_number_ref_burst(connection): flexibleRef = getFlexibleRef(connection) maxRefBurst = getMaxRefBurst(connection) - cursor.execute(query); - result = cursor.fetchall(); + cursor.execute(query) + result = cursor.fetchall() if (flexibleRef): - maxRefBurst = maxRefBurst - 1 # Since the intersections will be used for this test, use -1 from the max + maxRefBurst = maxRefBurst - 1 # Since the intersections will be used for this test, use -1 from the max for row in result: if (prevrow[1] == row[0]): cnt += 1 else: - cnt = 0 # Reset the counter every time a burst ends + cnt = 0 # Reset the counter every time a burst ends prevrow = row if(cnt > maxRefBurst): return TestFailed("Maximum number of REFA in a burst was exceeded at {0} with {1} REFA in sequence. Maximum allowed is {2}.".format(formatTime(row[0]), cnt, maxRefBurst)) return TestSuceeded() + @test def max_time_without_ref(connection): """Checks that the maximum time allowed between REFA commands""" @@ -521,11 +521,11 @@ def max_time_without_ref(connection): flexibleRef = getFlexibleRef(connection) maxRefBurst = getMaxRefBurst(connection) - cursor.execute(query); - result = cursor.fetchall(); + cursor.execute(query) + result = cursor.fetchall() if (flexibleRef): - maxTimeWithoutRef = ((maxRefBurst + 1) * dramconfig.tREFI) + dramconfig.tRP # Bursts are possible, so max should be the possible burst size + 1 + maxTimeWithoutRef = ((maxRefBurst + 1) * dramconfig.tREFI) + dramconfig.tRP # Bursts are possible, so max should be the possible burst size + 1 else: maxTimeWithoutRef = dramconfig.tREFI + dramconfig.tRP @@ -537,6 +537,7 @@ def max_time_without_ref(connection): return TestSuceeded() + # ----------- activate checks --------------------------------------- @test def activate_to_activate_holds(connection):